commit 368df6f64709ce6ff8557ff2c3883c863221d54b Author: nelo Date: Fri Sep 15 07:41:54 2017 +0200 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..39fb081 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..dfa9e34 --- /dev/null +++ b/.hgignore @@ -0,0 +1,10 @@ +syntax: glob +*.iml +.gradle +.idea/dictionaries +.idea/libraries +.idea/tasks.xml +.idea/workspace.xml +build +gen +local.properties \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..2c5a629 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..d80eed3 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5d19981 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..3928842 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..964afce --- /dev/null +++ b/build.gradle @@ -0,0 +1,41 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply from: 'buildsystem/ci.gradle' +apply from: 'buildsystem/dependencies.gradle' +apply plugin: 'kotlin' + +buildscript { + ext.kotlin_version = '1.1.0' + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.2.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version" + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + ext { + androidApplicationId = 'es.verdnatura.almacen' + androidVersionCode = 1 + androidVersionName = "1.0" + testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner" + testApplicationId = 'es.verdnatura.almacen.test' + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} +repositories { + mavenCentral() +} +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" +} +sourceSets { + main.java.srcDirs += 'src/main/kotlin' +} diff --git a/buildsystem/ci.gradle b/buildsystem/ci.gradle new file mode 100644 index 0000000..53420ee --- /dev/null +++ b/buildsystem/ci.gradle @@ -0,0 +1,13 @@ +def ciServer = 'TRAVIS' +def executingOnCI = "true".equals(System.getenv(ciServer)) + +// Since for CI we always do full clean builds, we don't want to pre-dex +// See http://tools.android.com/tech-docs/new-build-system/tips +subprojects { + project.plugins.whenPluginAdded { plugin -> + if ('com.android.build.gradle.AppPlugin'.equals(plugin.class.name) || + 'com.android.build.gradle.LibraryPlugin'.equals(plugin.class.name)) { + project.android.dexOptions.preDexLibraries = !executingOnCI + } + } +} \ No newline at end of file diff --git a/buildsystem/dependencies.gradle b/buildsystem/dependencies.gradle new file mode 100644 index 0000000..5d2e9a8 --- /dev/null +++ b/buildsystem/dependencies.gradle @@ -0,0 +1,133 @@ +allprojects { + repositories { + jcenter() + } +} + +ext{ + //Android + androidBuildToolsVersion = "24.0.1" + androidMinSdkVersion = 15 + androidTargetSdkVersion = 24 + androidCompileSdkVersion = 24 + + //Libraries + gsonVersion = '2.3' + retrofitVersion = '2.2.0' + rxJavaVersion = '2.0.6' + rxAndroidVersion = '2.0.1' + daggerVersion = '2.5' + javaxInjectVersion = '1' + javaxAnnotationVersion = '1.0' + kotlinVersion = "1.1.0" + appcompatV7Version = "24.2.1" + butterKnifeVersion = '8.5.1' + barcodeScannerVersion = '1.9' + constraintLayout = '1.0.2' + ankoVersion = '0.9' + designVersion = '24.2.1' + + + //Test + jUnitVersion = '4.12' + roboelectricVersion = '3.2.1' + kotlinVersion = '1.1.0' + kotlinTestVersion = '1.1.0' + mockitoKotlin = '1.1.0' + kluenVersion = '1.14' + assertJVersion = '1.7.1' + + //androidTest + espressoVersion = '2.2.2' + annotationsVersion = '25.1.0' + rulesVersion = "0.5" + + //Development + leakCanaryVersion = '1.3.1' + + + dataDependencies = [ + kotlin: "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}", + rxJava: "io.reactivex.rxjava2:rxjava:${rxJavaVersion}", + rxAndroid: "io.reactivex.rxjava2:rxandroid:${rxAndroidVersion}", + daggerCompiler: "com.google.dagger:dagger-compiler:${daggerVersion}", + dagger: "com.google.dagger:dagger:${daggerVersion}", + retrofit: "com.squareup.retrofit2:retrofit:${retrofitVersion}", + gson_converter: "com.squareup.retrofit2:converter-gson:${retrofitVersion}", + rxjava_adapter: "com.squareup.retrofit2:adapter-rxjava2:${retrofitVersion}" + ] + + dataTestDependencies = [ + jUnit: "junit:junit:${jUnitVersion}", + roboelectric: "org.robolectric:robolectric:${roboelectricVersion}", + kotlin: "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}", + kotlinTest: "org.jetbrains.kotlin:kotlin-test-junit:${kotlinTestVersion}", + mockitoKotlin: "com.nhaarman:mockito-kotlin:${mockitoKotlin}", + kluent: "org.amshove.kluent:kluent:${kluenVersion}", + ] + + domainDependencies = [ + rxJava: "io.reactivex.rxjava2:rxjava:${rxJavaVersion}", + javaxInject: "javax.inject:javax.inject:${javaxInjectVersion}", + kotlin: "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}", + gson: "com.google.code.gson:gson:${gsonVersion}", + javaxAnnotation: "javax.annotation:jsr250-api:${javaxAnnotationVersion}" + ] + + domainTestDependencies = [ + jUnit: "junit:junit:${jUnitVersion}", + kotlin: "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}", + kotlinTest: "org.jetbrains.kotlin:kotlin-test-junit:${kotlinTestVersion}", + mockitoKotlin: "com.nhaarman:mockito-kotlin:${mockitoKotlin}", + kluent: "org.amshove.kluent:kluent:${kluenVersion}", + assertj: "org.assertj:assertj-core:${assertJVersion}" + ] + + presentationDependencies = [ + kotlin: "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}", + appcomapt_v7: "com.android.support:appcompat-v7:${appcompatV7Version}", + dagger: "com.google.dagger:dagger:${daggerVersion}", + butterKnife: "com.jakewharton:butterknife:${butterKnifeVersion}", + kaptButterKnife: "com.jakewharton:butterknife-compiler:${butterKnifeVersion}", + kaptDagger: "com.google.dagger:dagger-compiler:${daggerVersion}", + rxAndroid: "io.reactivex.rxjava2:rxandroid:${rxAndroidVersion}", + javaxAnnotation: "javax.annotation:jsr250-api:${javaxAnnotationVersion}", + barcodeScanner: "me.dm7.barcodescanner:zxing:${barcodeScannerVersion}", + constranintLayout: "com.android.support.constraint:constraint-layout:${constraintLayout}" + ] + + presentationTestDependencies = [ + jUnit: "junit:junit:${jUnitVersion}", + roboelectric: "org.robolectric:robolectric:${roboelectricVersion}", + kotlin: "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}", + kotlinTest: "org.jetbrains.kotlin:kotlin-test-junit:${kotlinTestVersion}", + mockitoKotlin: "com.nhaarman:mockito-kotlin:${mockitoKotlin}", + kluent: "org.amshove.kluent:kluent:${kluenVersion}", + ] + + presentationAndroidTestDependencies = [ + espresso: "com.android.support.test.espresso:espresso-core:${espressoVersion}", + runner: "com.android.support.test:runner:${rulesVersion}", + rules: "com.android.support.test:rules:${rulesVersion}", + espressoIntents: "com.android.support.test.espresso:espresso-intents:${espressoVersion}", + annotations: "com.android.support:support-annotations:${annotationsVersion}", + ] + + coreDependencies = [ + kotlin: "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}", + appcomapt_v7: "com.android.support:appcompat-v7:${appcompatV7Version}", + recyclerview: "com.android.support:recyclerview-v7:${appcompatV7Version}", + cardview: "com.android.support:cardview-v7:${appcompatV7Version}", + anko: "org.jetbrains.anko:anko-common:${ankoVersion}", + design: "com.android.support:design:${designVersion}", + retrofit: "com.squareup.retrofit2:retrofit:${retrofitVersion}", + gson_converter: "com.squareup.retrofit2:converter-gson:${retrofitVersion}", + rxjava_adapter: "com.squareup.retrofit2:adapter-rxjava2:${retrofitVersion}", + javaxInject: "javax.inject:javax.inject:${javaxInjectVersion}", + ] + + developmentDependencies = [ + leakCanary: "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}", + ] + +} \ No newline at end of file diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/data/.gitignore @@ -0,0 +1 @@ +/build diff --git a/data/build.gradle b/data/build.gradle new file mode 100644 index 0000000..5788e73 --- /dev/null +++ b/data/build.gradle @@ -0,0 +1,59 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' + +android { + def globalConfiguration = rootProject.extensions.getByName("ext") + + compileSdkVersion globalConfiguration.getAt("androidCompileSdkVersion") + buildToolsVersion globalConfiguration.getAt("androidBuildToolsVersion") + + defaultConfig { + minSdkVersion globalConfiguration.getAt("androidMinSdkVersion") + targetSdkVersion globalConfiguration.getAt("androidTargetSdkVersion") + + versionCode globalConfiguration.getAt("androidVersionCode") + versionName globalConfiguration.getAt("androidVersionName") + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + + } + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + test.java.srcDirs += 'src/test/kotlin' + } + +} + +dependencies { + def dataDependencies = rootProject.ext.dataDependencies + def dataTestDependencies = rootProject.ext.dataTestDependencies + + compile project(":domain") + compile project(":core") + + compile dataDependencies.kotlin + compile dataDependencies.rxJava + compile dataDependencies.daggerCompiler + compile dataDependencies.dagger + + testCompile dataTestDependencies.jUnit + testCompile dataTestDependencies.roboelectric + testCompile dataTestDependencies.kotlin + testCompile dataTestDependencies.kotlinTest + testCompile dataTestDependencies.mockitoKotlin + testCompile dataTestDependencies.kluent + + compile fileTree(dir: 'libs', include: '*.jar') + +} + +repositories { + mavenCentral() +} diff --git a/data/proguard-rules.pro b/data/proguard-rules.pro new file mode 100644 index 0000000..f6f0958 --- /dev/null +++ b/data/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/nelo/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/data/src/main/AndroidManifest.xml b/data/src/main/AndroidManifest.xml new file mode 100644 index 0000000..15371c4 --- /dev/null +++ b/data/src/main/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/data/src/main/kotlin/es/verdnatura/data/entity/TicketDetailDto.kt b/data/src/main/kotlin/es/verdnatura/data/entity/TicketDetailDto.kt new file mode 100644 index 0000000..4ea220b --- /dev/null +++ b/data/src/main/kotlin/es/verdnatura/data/entity/TicketDetailDto.kt @@ -0,0 +1,33 @@ +package es.verdnatura.data.entity + +import java.util.* + +/** + * Created by nelo on 8/3/17. + */ +class TicketDetailDto{ + val IdDetail: Int = 0 + val Niche: String = "" + val IdArticle: String = "" + val ArticleImage: String = "" + val Ok: Int = 0 + val Packing: Int = 0 + val Grouping: Int = 0 + val Quantity: Int = 0 + val OldQuantity: Int = 0 + val OriginalQuantity: Int = 0 + val Concept: String = "" + val Producer: String = "" + val Size: Int = 0 + val Color: String = "" + val Category: String = "" + val Origin: String = "" + val Stems: Int = 0 + val Reign: String = "" + val IdTicket: String = "" + val Barcodes: List = ArrayList() + val Discount: Float = 0.0F + val Reserved: Int = 0 + val Price: Float = 0.0F + val Path: String = "" +} \ No newline at end of file diff --git a/data/src/main/kotlin/es/verdnatura/data/entity/TicketDto.kt b/data/src/main/kotlin/es/verdnatura/data/entity/TicketDto.kt new file mode 100644 index 0000000..f1b675a --- /dev/null +++ b/data/src/main/kotlin/es/verdnatura/data/entity/TicketDto.kt @@ -0,0 +1,25 @@ +package es.verdnatura.data.entity + +import java.util.* + +/** + * Created by nelo on 8/3/17. + */ +class TicketDto{ + + val IdTicket: Int = 0 + val ClientCode: String = "" + val ClientName: String = "" + val ClientCity: String = "" + val TicketTotal: Float = 0.0F + val Transport: String = "" + val Date: String = "" + val Observations: String = "" + val Server: String = "" + val Commercial: String = "" + val Tickets: Int = 0 + val Agency: String = "" + val IdWarehouse: Int = 0 + val Details: List = ArrayList() + +} \ No newline at end of file diff --git a/data/src/main/kotlin/es/verdnatura/data/exceptions/NotFoundException.kt b/data/src/main/kotlin/es/verdnatura/data/exceptions/NotFoundException.kt new file mode 100644 index 0000000..69be056 --- /dev/null +++ b/data/src/main/kotlin/es/verdnatura/data/exceptions/NotFoundException.kt @@ -0,0 +1,10 @@ +package es.verdnatura.data.exceptions + +import android.content.Context +import es.verdnatura.core.UtilsResources +import es.verdnatura.data.R + +/** + * Created by nelo on 1/3/17. + */ +class NotFoundException(context: Context) : RuntimeException(UtilsResources.getResourceString(context, R.string.error_404)) \ No newline at end of file diff --git a/data/src/main/kotlin/es/verdnatura/data/exceptions/ServerError.kt b/data/src/main/kotlin/es/verdnatura/data/exceptions/ServerError.kt new file mode 100644 index 0000000..a66fca5 --- /dev/null +++ b/data/src/main/kotlin/es/verdnatura/data/exceptions/ServerError.kt @@ -0,0 +1,10 @@ +package es.verdnatura.data.exceptions + +import android.content.Context +import es.verdnatura.core.UtilsResources +import es.verdnatura.data.R + +/** + * Created by nelo on 1/3/17. + */ +class ServerError(context: Context) : RuntimeException(UtilsResources.getResourceString(context, R.string.error_500)) \ No newline at end of file diff --git a/data/src/main/kotlin/es/verdnatura/data/exceptions/ServerException.kt b/data/src/main/kotlin/es/verdnatura/data/exceptions/ServerException.kt new file mode 100644 index 0000000..2040ca1 --- /dev/null +++ b/data/src/main/kotlin/es/verdnatura/data/exceptions/ServerException.kt @@ -0,0 +1,6 @@ +package es.verdnatura.data.exceptions + +/** + * Created by nelo on 1/3/17. + */ +class ServerException(override var message: String) : RuntimeException(message) \ No newline at end of file diff --git a/data/src/main/kotlin/es/verdnatura/data/exceptions/TimeoutException.kt b/data/src/main/kotlin/es/verdnatura/data/exceptions/TimeoutException.kt new file mode 100644 index 0000000..3ee998e --- /dev/null +++ b/data/src/main/kotlin/es/verdnatura/data/exceptions/TimeoutException.kt @@ -0,0 +1,10 @@ +package es.verdnatura.data.exceptions + +import android.content.Context +import es.verdnatura.core.UtilsResources +import es.verdnatura.data.R + +/** + * Created by nelo on 1/3/17. + */ +class TimeoutException(context: Context) : RuntimeException(UtilsResources.getResourceString(context, R.string.time_out)) \ No newline at end of file diff --git a/data/src/main/kotlin/es/verdnatura/data/rest/WarehouseApi.kt b/data/src/main/kotlin/es/verdnatura/data/rest/WarehouseApi.kt new file mode 100644 index 0000000..425f402 --- /dev/null +++ b/data/src/main/kotlin/es/verdnatura/data/rest/WarehouseApi.kt @@ -0,0 +1,18 @@ +package es.verdnatura.data.rest + +import es.verdnatura.data.entity.TicketDto +import io.reactivex.Observable +import retrofit2.http.Body +import retrofit2.http.POST + +/** + * Created by nelo on 16/2/17. + */ +interface WarehouseApi { + + @POST("security/login") + fun login(@Body vararg args: Any): Observable + + @POST("warehouse/get_ticket_controller") + fun getTicketController(@Body vararg args: Any): Observable +} \ No newline at end of file diff --git a/data/src/main/kotlin/es/verdnatura/data/rest/WarehouseApiImpl.kt b/data/src/main/kotlin/es/verdnatura/data/rest/WarehouseApiImpl.kt new file mode 100644 index 0000000..8f0858d --- /dev/null +++ b/data/src/main/kotlin/es/verdnatura/data/rest/WarehouseApiImpl.kt @@ -0,0 +1,52 @@ +package es.verdnatura.data.rest + +import android.app.Application +import es.verdnatura.core.UtilsResources +import es.verdnatura.data.R +import es.verdnatura.data.entity.TicketDto +import es.verdnatura.data.exceptions.ServerException +import es.verdnatura.data.parser.Serializer +import es.verdnatura.domain.entity.Ticket +import es.verdnatura.domain.repository.WarehouseRepository +import io.reactivex.Observable +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Created by nelo on 16/2/17. + */ +@Singleton +class WarehouseApiImpl : WarehouseRepository { + + lateinit var mWarehouseApi: WarehouseApi + lateinit var application: Application + lateinit var serializer: Serializer + + val vnConnector: VnConnector + + @Inject + constructor(application: Application) { + this.vnConnector = VnConnector(application) + createApi("user", "pass", "1") + } + + override fun createApi(user: String, pass: String, version: String) { + vnConnector.createApi(user, pass, version) + application = vnConnector.application + serializer = vnConnector.serializer + mWarehouseApi = vnConnector.vnAdapter.create(WarehouseApi::class.java) + } + + override fun login(user: String, pass: String, imei: String): Observable { + return mWarehouseApi!!.login(user, pass, imei).doOnError { + throwable -> if(throwable is ServerException) throwable.message = UtilsResources.getResourceString(application, R.string.error_login) + } + } + + override fun getTicketController(ticket: String): Observable{ + return mWarehouseApi!!.getTicketController(ticket) + .map { ticket -> serializer.serialize(ticket, TicketDto::class.java) } + .map { json -> serializer.deserialize(json, Ticket::class.java) } + } + +} \ No newline at end of file diff --git a/data/src/main/res/values-es/strings.xml b/data/src/main/res/values-es/strings.xml new file mode 100644 index 0000000..fe55a97 --- /dev/null +++ b/data/src/main/res/values-es/strings.xml @@ -0,0 +1,6 @@ + + + Data + + + diff --git a/data/src/main/res/values/strings.xml b/data/src/main/res/values/strings.xml new file mode 100644 index 0000000..fa3358c --- /dev/null +++ b/data/src/main/res/values/strings.xml @@ -0,0 +1,10 @@ + + + + + Data + Internal server error + Resource not found + Connection timeout + Invalid user or pass + diff --git a/data/src/release/res/values/strings.xml b/data/src/release/res/values/strings.xml new file mode 100644 index 0000000..9e8ff5e --- /dev/null +++ b/data/src/release/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/domain/.gitignore b/domain/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/domain/.gitignore @@ -0,0 +1 @@ +/build diff --git a/domain/.hgignore b/domain/.hgignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/domain/.hgignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/domain/build.gradle b/domain/build.gradle new file mode 100644 index 0000000..45ea043 --- /dev/null +++ b/domain/build.gradle @@ -0,0 +1,40 @@ +apply plugin: 'kotlin' +apply plugin: 'java' + +configurations { + provided +} + +sourceSets { + main.java.srcDirs += "src/main/kotlin" + test.java.srcDirs += 'src/test/kotlin' + + main{ + compileClasspath += configurations.provided + } +} + +dependencies { + def domainDependencies = rootProject.ext.domainDependencies + def domainTestDependencies = rootProject.ext.domainTestDependencies + + compile domainDependencies.rxJava + compile domainDependencies.javaxInject + compile domainDependencies.kotlin + compile domainDependencies.gson + + testCompile domainTestDependencies.jUnit + testCompile domainTestDependencies.kotlin + testCompile domainTestDependencies.kotlinTest + testCompile domainTestDependencies.mockitoKotlin + testCompile domainTestDependencies.kluent + testCompile domainTestDependencies.assertj + + provided domainDependencies.javaxAnnotation + + compile fileTree(dir: 'libs', include: '*.jar') + +} +repositories { + mavenCentral() +} \ No newline at end of file diff --git a/domain/src/main/kotlin/es/verdnatura/domain/check/Preconditions.kt b/domain/src/main/kotlin/es/verdnatura/domain/check/Preconditions.kt new file mode 100644 index 0000000..18c78a4 --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/check/Preconditions.kt @@ -0,0 +1,17 @@ +package es.verdnatura.domain.check + + +/** + * Created by nelo on 16/2/17. + */ +class Preconditions { + + companion object{ + fun checkNotNull(obj: Any?): Any{ + if(obj == null){ + throw NullPointerException() + } + return obj + } + } +} \ No newline at end of file diff --git a/domain/src/main/kotlin/es/verdnatura/domain/entity/Ticket.kt b/domain/src/main/kotlin/es/verdnatura/domain/entity/Ticket.kt new file mode 100644 index 0000000..87771f1 --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/entity/Ticket.kt @@ -0,0 +1,53 @@ +package es.verdnatura.domain.entity + +import com.google.gson.annotations.SerializedName +import java.util.* + +/** + * Created by nelo on 8/3/17. + */ +class Ticket { + + @SerializedName("IdTicket") + var IdTicket: Int = 0 + + @SerializedName("ClientCode") + var ClientCode: String = "" + + @SerializedName("ClientName") + var ClientName: String = "" + + @SerializedName("ClientCity") + var ClientCity: String = "" + + @SerializedName("TicketTotal") + var TicketTotal: Float = 0.0F + + @SerializedName("Transport") + var Transport: String = "" + + @SerializedName("Date") + var Date: String = "" + + @SerializedName("Observations") + var Observations: String = "" + + @SerializedName("Server") + var Server: String = "" + + @SerializedName("Commercial") + var Commercial: String = "" + + @SerializedName("Tickets") + var Tickets: Int = 0 + + @SerializedName("Agency") + var Agency: String = "" + + @SerializedName("IdWarehouse") + var IdWarehouse: Int = 0 + + @SerializedName("Details") + var Details: MutableList = ArrayList() + +} \ No newline at end of file diff --git a/domain/src/main/kotlin/es/verdnatura/domain/entity/TicketDetail.kt b/domain/src/main/kotlin/es/verdnatura/domain/entity/TicketDetail.kt new file mode 100644 index 0000000..2fe01d7 --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/entity/TicketDetail.kt @@ -0,0 +1,88 @@ +package es.verdnatura.domain.entity + +import com.google.gson.annotations.SerializedName +import java.util.* + +/** + * Created by nelo on 8/3/17. + */ +class TicketDetail{ + + @SerializedName("IdDetail") + var IdDetail: Int = 0 + + @SerializedName("Niche") + var Niche: String = "" + + @SerializedName("IdArticle") + var IdArticle: String = "" + + @SerializedName("ArticleImage") + var ArticleImage: String = "" + + @SerializedName("Ok") + var Ok: Int = 0 + + @SerializedName("Packing") + var Packing: Int = 0 + + @SerializedName("Grouping") + var Grouping: Int = 0 + + @SerializedName("Quantity") + var Quantity: Int = 0 + + @SerializedName("OldQuantity") + var OldQuantity: Int = 0 + + @SerializedName("OriginalQuantity") + var OriginalQuantity: Int = 0 + + @SerializedName("Concept") + var Concept: String = "" + + @SerializedName("Producer") + var Producer: String = "" + + @SerializedName("Size") + var Size: Int = 0 + + @SerializedName("Color") + var Color: String = "" + + @SerializedName("Category") + var Category: String = "" + + @SerializedName("Origin") + var Origin: String = "" + + @SerializedName("Stems") + var Stems: Int = 0 + + @SerializedName("Reign") + var Reign: String = "" + + @SerializedName("IdTicket") + var IdTicket: String = "" + + @SerializedName("Barcodes") + var Barcodes: MutableList = ArrayList() + + @SerializedName("Discount") + var Discount: Float = 0.0F + + @SerializedName("Reserved") + var Reserved: Int = 0 + + @SerializedName("Price") + var Price: Float = 0.0F + + @SerializedName("Path") + var Path: String = "" + + var DetailState: State = State.DEFAULT + + enum class State{ + DEFAULT, MARKED, UPLOADED, ERROR + } +} \ No newline at end of file diff --git a/domain/src/main/kotlin/es/verdnatura/domain/interactor/DefaultObserver.kt b/domain/src/main/kotlin/es/verdnatura/domain/interactor/DefaultObserver.kt new file mode 100644 index 0000000..3c5280e --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/interactor/DefaultObserver.kt @@ -0,0 +1,15 @@ +package es.verdnatura.domain.interactor + +import io.reactivex.observers.DisposableObserver + +/** + * Created by nelo on 27/2/17. + */ +open class DefaultObserver : DisposableObserver() { + + override fun onNext(t: T) {} + + override fun onComplete() {} + + override fun onError(exception: Throwable ){} +} \ No newline at end of file diff --git a/domain/src/main/kotlin/es/verdnatura/domain/interactor/DefaultObserver.kt.orig b/domain/src/main/kotlin/es/verdnatura/domain/interactor/DefaultObserver.kt.orig new file mode 100644 index 0000000..d9cf812 --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/interactor/DefaultObserver.kt.orig @@ -0,0 +1,20 @@ +package es.verdnatura.domain.interactor + + +/** + * Created by nelo on 16/2/17. + */ +class DefaultObserver : DisposableObserver() { + + override fun onComplete() { + + } + + override fun onError(e: Throwable?) { + + } + + override fun onNext(value: T) { + + } +} \ No newline at end of file diff --git a/domain/src/main/kotlin/es/verdnatura/domain/interactor/DownloadTicketUseCase.kt b/domain/src/main/kotlin/es/verdnatura/domain/interactor/DownloadTicketUseCase.kt new file mode 100644 index 0000000..a091e6a --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/interactor/DownloadTicketUseCase.kt @@ -0,0 +1,32 @@ +package es.verdnatura.domain.interactor + +import es.verdnatura.domain.entity.Ticket +import es.verdnatura.domain.repository.WarehouseRepository +import io.reactivex.Observable +import io.reactivex.Scheduler +import javax.inject.Inject + +/** + * Created by nelo on 8/3/17. + */ +class DownloadTicketUseCase : UseCase { + + val repository: WarehouseRepository + + @Inject + constructor(repository: WarehouseRepository, uiThread: Scheduler, mExecutorThread: Scheduler) : super(uiThread, mExecutorThread) { + this.repository = repository + } + + override fun buildUseCaseObservable(params: Params): Observable { + return this.repository.getTicketController(params.ticket) + } + + class Params private constructor(val ticket: String) { + companion object{ + fun forGetTicket(ticket: String): Params { + return Params(ticket) + } + } + } +} \ No newline at end of file diff --git a/domain/src/main/kotlin/es/verdnatura/domain/interactor/GetMarkedTicketLinesUseCase.kt b/domain/src/main/kotlin/es/verdnatura/domain/interactor/GetMarkedTicketLinesUseCase.kt new file mode 100644 index 0000000..252982e --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/interactor/GetMarkedTicketLinesUseCase.kt @@ -0,0 +1,29 @@ +package es.verdnatura.domain.interactor + +import es.verdnatura.domain.entity.Ticket +import io.reactivex.Observable +import io.reactivex.Scheduler +import javax.inject.Inject + +/** + * Created by nelo on 5/4/17. + */ +class GetMarkedTicketLinesUseCase : UseCase { + + @Inject + constructor(uiThread: Scheduler, mExecutorThread: Scheduler) : super(uiThread, mExecutorThread) + + override fun buildUseCaseObservable(params: Params): Observable { + return Observable.just(params.ticket.Details.filter { detail -> detail.Ok == 2 }.count()) + } + + class Params private constructor(val ticket: Ticket) { + companion object{ + fun forGetMarkedLines(ticket: Ticket): Params { + return Params(ticket) + } + } + } + +} + diff --git a/domain/src/main/kotlin/es/verdnatura/domain/interactor/LoginUseCase.kt b/domain/src/main/kotlin/es/verdnatura/domain/interactor/LoginUseCase.kt new file mode 100644 index 0000000..ce034d1 --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/interactor/LoginUseCase.kt @@ -0,0 +1,32 @@ +package es.verdnatura.domain.interactor + +import es.verdnatura.domain.repository.WarehouseRepository +import io.reactivex.Observable +import io.reactivex.Scheduler +import javax.inject.Inject + +/** + * Created by nelo on 16/2/17. + */ +class LoginUseCase : UseCase{ + + val repository: WarehouseRepository + + @Inject + constructor(repository: WarehouseRepository, uiThread: Scheduler, mExecutorThread: Scheduler) : super(uiThread, mExecutorThread) { + this.repository = repository + } + + override fun buildUseCaseObservable(params: Params): Observable { + this.repository.createApi(params.user, params.pass, params.version) + return this.repository.login(params.user, params.pass, params.imei) + } + + class Params private constructor(val user: String, val pass: String, val imei: String, val version: String) { + companion object{ + fun forLogin(user: String, pass: String, imei: String, version: String): Params { + return Params(user, pass, imei, version) + } + } + } +} \ No newline at end of file diff --git a/domain/src/main/kotlin/es/verdnatura/domain/interactor/UseCase.kt b/domain/src/main/kotlin/es/verdnatura/domain/interactor/UseCase.kt new file mode 100644 index 0000000..5176b2d --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/interactor/UseCase.kt @@ -0,0 +1,47 @@ +package es.verdnatura.domain.interactor + +import es.verdnatura.domain.check.Preconditions +import io.reactivex.Observable +import io.reactivex.Scheduler +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.observers.DisposableObserver +import io.reactivex.disposables.Disposable + +/** + * Created by nelo on 16/2/17. + */ +abstract class UseCase { + + val uiThread: Scheduler + val mExecutorThread: Scheduler + var disposables: CompositeDisposable + + constructor(uiThread: Scheduler, mExecutorThread: Scheduler){ + this.uiThread = uiThread + this.mExecutorThread = mExecutorThread + this.disposables = CompositeDisposable() + } + + abstract fun buildUseCaseObservable(params: Params): Observable + + open fun execute(observer: DisposableObserver, params: Params) { + Preconditions.checkNotNull(params) + Preconditions.checkNotNull(observer) + val observable: Observable = this.buildUseCaseObservable(params) + .subscribeOn(mExecutorThread) + .observeOn(uiThread) + addDisposable(observable.subscribeWith(observer)) + } + + fun dispose() { + if (!disposables.isDisposed) { + disposables.dispose() + } + } + + private fun addDisposable(disposable: Disposable) { + Preconditions.checkNotNull(disposable) + Preconditions.checkNotNull(disposables) + disposables.add(disposable) + } +} \ No newline at end of file diff --git a/domain/src/main/kotlin/es/verdnatura/domain/repository/WarehouseRepository.kt b/domain/src/main/kotlin/es/verdnatura/domain/repository/WarehouseRepository.kt new file mode 100644 index 0000000..ef54343 --- /dev/null +++ b/domain/src/main/kotlin/es/verdnatura/domain/repository/WarehouseRepository.kt @@ -0,0 +1,17 @@ +package es.verdnatura.domain.repository + +import es.verdnatura.domain.entity.Ticket +import io.reactivex.Observable + + +/** + * Created by nelo on 16/2/17. + */ +interface WarehouseRepository { + + fun createApi(user: String, pass: String, version: String) + + fun login(user: String, pass: String, imei: String): Observable + + fun getTicketController(ticket: String): Observable +} \ No newline at end of file diff --git a/domain/src/test/kotlin/check/PreconditionsTest.kt b/domain/src/test/kotlin/check/PreconditionsTest.kt new file mode 100644 index 0000000..03f188f --- /dev/null +++ b/domain/src/test/kotlin/check/PreconditionsTest.kt @@ -0,0 +1,31 @@ +package check + + +import es.verdnatura.domain.check.Preconditions +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException +import org.junit.runner.RunWith +import org.mockito.junit.MockitoJUnitRunner + +/** + * Created by nelo on 21/3/17. + */ +class PreconditionsTest { + + @Rule + @JvmField + public var exception = ExpectedException.none() + + @Test + fun checkNotNull(){ + var message : String = "" + Preconditions.checkNotNull(message) + } + + @Test + fun checkNull(){ + exception.expect(NullPointerException::class.java) + Preconditions.checkNotNull(null) + } +} \ No newline at end of file diff --git a/domain/src/test/kotlin/interactor/LoginUseCaseTest.kt b/domain/src/test/kotlin/interactor/LoginUseCaseTest.kt new file mode 100644 index 0000000..cb747a9 --- /dev/null +++ b/domain/src/test/kotlin/interactor/LoginUseCaseTest.kt @@ -0,0 +1,19 @@ +package interactor + +import com.nhaarman.mockito_kotlin.mock +import es.verdnatura.domain.repository.WarehouseRepository +import io.reactivex.Scheduler + +/** + * Created by nelo on 7/4/17. + */ +class LoginUseCaseTest { + + private val warehouseRepository: WarehouseRepository = mock() + private val mExecutorThread: Scheduler = mock() + private val uiThread: Scheduler = mock() + + + + +} \ No newline at end of file diff --git a/domain/src/test/kotlin/interactor/TicketcontrollerUseCaseTest.kt b/domain/src/test/kotlin/interactor/TicketcontrollerUseCaseTest.kt new file mode 100644 index 0000000..2ab02dc --- /dev/null +++ b/domain/src/test/kotlin/interactor/TicketcontrollerUseCaseTest.kt @@ -0,0 +1,42 @@ +package interactor + +import com.nhaarman.mockito_kotlin.mock +import com.nhaarman.mockito_kotlin.verify +import com.nhaarman.mockito_kotlin.verifyNoMoreInteractions +import com.nhaarman.mockito_kotlin.verifyZeroInteractions +import es.verdnatura.domain.interactor.DownloadTicketUseCase +import es.verdnatura.domain.repository.WarehouseRepository +import io.reactivex.Scheduler +import org.junit.Before +import org.junit.Test + +/** + * Created by nelo on 20/3/17. + */ + +class TicketcontrollerUseCaseTest { + + private val TICKET = "775762" + + private val warehouseRepository: WarehouseRepository = mock() + private val mExecutorThread: Scheduler = mock() + private val uiThread: Scheduler = mock() + + private lateinit var downloadTicketUseCase: DownloadTicketUseCase + + @Before + fun setUp() { + downloadTicketUseCase = DownloadTicketUseCase(warehouseRepository, uiThread, mExecutorThread) + } + + @Test + fun shouldGetTicketController() { + downloadTicketUseCase.buildUseCaseObservable(DownloadTicketUseCase.Params.forGetTicket(TICKET)) + + verify(warehouseRepository).getTicketController(TICKET) + verifyNoMoreInteractions(warehouseRepository) + verifyZeroInteractions(uiThread) + verifyZeroInteractions(mExecutorThread) + } + +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..aac7c9b --- /dev/null +++ b/gradle.properties @@ -0,0 +1,17 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..13372ae Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..04e285f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Dec 28 10:00:20 PST 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..9d82f78 --- /dev/null +++ b/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..aec9973 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/presentation/.gitignore b/presentation/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/presentation/.gitignore @@ -0,0 +1 @@ +/build diff --git a/presentation/.hgignore b/presentation/.hgignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/presentation/.hgignore @@ -0,0 +1 @@ +/build diff --git a/presentation/build.gradle b/presentation/build.gradle new file mode 100644 index 0000000..3eaefdf --- /dev/null +++ b/presentation/build.gradle @@ -0,0 +1,110 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + + +android { + def globalConfiguration = rootProject.extensions.getByName("ext") + + compileSdkVersion globalConfiguration.getAt("androidCompileSdkVersion") + buildToolsVersion globalConfiguration.getAt("androidBuildToolsVersion") + + defaultConfig { + minSdkVersion globalConfiguration.getAt("androidMinSdkVersion") + targetSdkVersion globalConfiguration.getAt("androidTargetSdkVersion") + + applicationId globalConfiguration.getAt("androidApplicationId") + versionCode globalConfiguration.getAt("androidVersionCode") + versionName globalConfiguration.getAt("androidVersionName") + testInstrumentationRunner globalConfiguration.getAt("testInstrumentationRunner") + testApplicationId globalConfiguration.getAt("testApplicationId") + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + debug.java.srcDirs += 'src/debug/kotlin' + test.java.srcDirs += 'src/test/kotlin' + androidTest.java.srcDirs += 'src/androidTest/kotlin' + main.res.srcDirs = + [ + 'src/main/res', + 'src/main/res/layouts/fragment', + 'src/main/res/layouts/activity', + 'src/main/res/layouts/item', + 'src/main/res/layouts/view' + ] + + } + + packagingOptions { + exclude 'LICENSE.txt' + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/ASL2.0' + exclude 'META-INF/NOTICE' + exclude 'META-INF/LICENSE' + exclude 'META-INF/rxjava.properties' + } + +} + +afterEvaluate { + android.sourceSets.all { sourceSet -> + if (!sourceSet.name.startsWith('test') || !sourceSet.name.startsWith('androidTest')) { + sourceSet.kotlin.setSrcDirs([]) + } + } +} + +dependencies { + def presentationDependencies = rootProject.ext.presentationDependencies + def presentationTestDependencies = rootProject.ext.presentationTestDependencies + def presentationAndroidTestDependencies = rootProject.ext.presentationAndroidTestDependencies + + compile project(':core') + compile project(':domain') + compile project(':data') + + compile presentationDependencies.appcomapt_v7 + compile presentationDependencies.kotlin + compile presentationDependencies.butterKnife + compile presentationDependencies.dagger + compile presentationDependencies.rxAndroid + compile presentationDependencies.barcodeScanner + compile presentationDependencies.constranintLayout + + testCompile presentationTestDependencies.jUnit + testCompile presentationTestDependencies.kotlin + testCompile presentationTestDependencies.kotlinTest + testCompile presentationTestDependencies.mockitoKotlin + testCompile presentationTestDependencies.kluent + + androidTestCompile presentationAndroidTestDependencies.espresso + androidTestCompile presentationAndroidTestDependencies.runner + androidTestCompile presentationAndroidTestDependencies.rules + androidTestCompile presentationAndroidTestDependencies.espressoIntents + androidTestCompile presentationAndroidTestDependencies.annotations + + provided presentationDependencies.javaxAnnotation + + kapt presentationDependencies.kaptButterKnife + kapt presentationDependencies.kaptDagger + + //Development + //compile developmentDependencies.leakCanary + + compile fileTree(dir: 'libs', include: '*.jar') +} + +repositories { + mavenCentral() +} +kapt { + generateStubs = true +} \ No newline at end of file diff --git a/presentation/proguard-rules.pro b/presentation/proguard-rules.pro new file mode 100644 index 0000000..f6f0958 --- /dev/null +++ b/presentation/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/nelo/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/presentation/src/androidTest/kotlin/es/verdnatura/almacen/activity/LoginActivityTest.kt b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/activity/LoginActivityTest.kt new file mode 100644 index 0000000..51f720c --- /dev/null +++ b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/activity/LoginActivityTest.kt @@ -0,0 +1,13 @@ +package es.verdnatura.almacen.activity + +import es.verdnatura.almacen.framework.AcceptanceTest +import es.verdnatura.almacen.view.activity.LoginActivity + + +/** + * Created by nelo on 22/3/17. + */ +class LoginActivityTest : AcceptanceTest(LoginActivity::class.java){ + + +} \ No newline at end of file diff --git a/presentation/src/androidTest/kotlin/es/verdnatura/almacen/fragment/LoginFragmentTest.kt b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/fragment/LoginFragmentTest.kt new file mode 100644 index 0000000..a12875d --- /dev/null +++ b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/fragment/LoginFragmentTest.kt @@ -0,0 +1,33 @@ +package es.verdnatura.almacen.fragment + +import es.verdnatura.almacen.framework.FragmentTestRule +import es.verdnatura.almacen.view.fragment.LoginFragment +import android.support.test.espresso.matcher.ViewMatchers.isDisplayed +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.matcher.ViewMatchers.withId +import es.verdnatura.almacen.R +import org.junit.Rule +import org.junit.Test + + +/** + * Created by nelo on 10/4/17. + */ +class LoginFragmentTest : FragmentTestRule(LoginFragment::class.java, R.layout.fragment_login) { + + + @Rule @JvmField + public var mFragmentTestRule: FragmentTestRule = FragmentTestRule(LoginFragment::class.java!!, R.layout.fragment_login) + + @Test + fun fragment_can_be_instantiated() { + + // Launch the activity to make the fragment visible + mFragmentTestRule.launchActivity(null) + + // Then use Espresso to test the Fragment + onView(withId(R.id.button_login)).check(matches(isDisplayed())) + } + +} \ No newline at end of file diff --git a/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/AcceptanceTest.kt b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/AcceptanceTest.kt new file mode 100644 index 0000000..476478f --- /dev/null +++ b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/AcceptanceTest.kt @@ -0,0 +1,24 @@ +package es.verdnatura.almacen.framework + +import android.app.Activity +import android.support.test.espresso.intent.rule.IntentsTestRule +import android.support.test.rule.ActivityTestRule +import android.support.test.runner.AndroidJUnit4 +import android.test.suitebuilder.annotation.LargeTest +import org.junit.Rule +import org.junit.runner.RunWith + +/** + * Created by nelo on 22/3/17. + */ +@LargeTest +@RunWith(AndroidJUnit4::class) +abstract class AcceptanceTest(clazz: Class) { + + @Rule @JvmField + val testRule: ActivityTestRule = IntentsTestRule(clazz) + + val checkThat: Matchers = Matchers() + val events: Events = Events() +} + diff --git a/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/Events.kt b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/Events.kt new file mode 100644 index 0000000..5534ccc --- /dev/null +++ b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/Events.kt @@ -0,0 +1,17 @@ +package es.verdnatura.almacen.framework + +import android.support.annotation.IdRes +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.action.ViewActions.click +import android.support.test.espresso.matcher.ViewMatchers.withId + +/** + * Created by nelo on 22/3/17. + */ +class Events { + + fun clickOnView(@IdRes viewId: Int) { + onView(withId(viewId)).perform(click()) + } + +} \ No newline at end of file diff --git a/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/FragmentTestRule.kt b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/FragmentTestRule.kt new file mode 100644 index 0000000..bebe910 --- /dev/null +++ b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/FragmentTestRule.kt @@ -0,0 +1,52 @@ +package es.verdnatura.almacen.framework + +import android.app.FragmentManager +import android.support.test.rule.ActivityTestRule +import android.support.test.runner.AndroidJUnit4 +import es.verdnatura.almacen.R +import es.verdnatura.almacen.TestActivity +import es.verdnatura.almacen.view.fragment.BaseFragment +import junit.framework.Assert +import org.junit.runner.RunWith + + +/** + * Created by nelo on 10/4/17. + */ +@RunWith(AndroidJUnit4::class) +open class FragmentTestRule : ActivityTestRule { + + private var mFragmentClass: Class + private var mFragment: F? = null + private val layout: Int + + constructor(fragmentClass: Class, layout: Int) : super(TestActivity::class.java, true, false) { + mFragmentClass = fragmentClass + this.layout = layout + } + + override fun afterActivityLaunched() { + super.afterActivityLaunched() + activity.runOnUiThread { + try { + val manager: FragmentManager = activity.fragmentManager + val transaction = manager.beginTransaction() + mFragment = mFragmentClass.getDeclaredConstructor(Int::class.java).newInstance(layout) + transaction.replace(R.id.fragmentContainer, mFragment) + transaction.commit() + + } + catch (e: Exception){ + Assert.fail(String.format("%s: Could not insert %s into TestActivity: %s", + javaClass.getSimpleName(), + mFragmentClass.getSimpleName(), + e.message)) + } + } + } + + fun getFragment(): F?{ + return mFragment + } + +} \ No newline at end of file diff --git a/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/Matchers.kt b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/Matchers.kt new file mode 100644 index 0000000..9d716e7 --- /dev/null +++ b/presentation/src/androidTest/kotlin/es/verdnatura/almacen/framework/Matchers.kt @@ -0,0 +1,33 @@ +package es.verdnatura.almacen.framework + +import android.app.Activity +import android.support.annotation.IdRes +import android.support.annotation.StringRes +import android.support.test.espresso.Espresso.onView +import android.support.test.espresso.assertion.ViewAssertions.matches +import android.support.test.espresso.intent.Intents.intended +import android.support.test.espresso.intent.matcher.IntentMatchers +import android.support.test.espresso.matcher.ViewMatchers.* + +/** + * Created by nelo on 22/3/17. + */ +class Matchers { + + fun nextOpenActivityIs(clazz: Class) { + intended(IntentMatchers.hasComponent(clazz.name)) + } + + fun viewIsVisibleAndContainsText(@StringRes stringResource: Int) { + onView(withText(stringResource)).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + } + + fun viewContainsText(@IdRes viewId: Int, @StringRes stringResource: Int) { + onView(withId(viewId)).check(matches(withText(stringResource))) + } + + fun viewIsVisible(@IdRes viewId: Int){ + onView(withId(viewId)).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) + } + +} \ No newline at end of file diff --git a/presentation/src/debug/AndroidManifest.xml b/presentation/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..491feff --- /dev/null +++ b/presentation/src/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/presentation/src/debug/kotlin/es/verdnatura/almacen/TestActivity.kt b/presentation/src/debug/kotlin/es/verdnatura/almacen/TestActivity.kt new file mode 100644 index 0000000..e3bd677 --- /dev/null +++ b/presentation/src/debug/kotlin/es/verdnatura/almacen/TestActivity.kt @@ -0,0 +1,18 @@ +package es.verdnatura.almacen + +import android.os.Bundle +import android.widget.FrameLayout +import es.verdnatura.core.activity.BaseActivity + +/** + * Created by nelo on 10/4/17. + */ +class TestActivity : BaseActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + var framelayout = FrameLayout(this) + framelayout.id = R.id.fragmentContainer + setContentView(framelayout) + } +} \ No newline at end of file diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d92cbe0 --- /dev/null +++ b/presentation/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/presentation/src/main/ic_launcher-web.png b/presentation/src/main/ic_launcher-web.png new file mode 100644 index 0000000..d7ee401 Binary files /dev/null and b/presentation/src/main/ic_launcher-web.png differ diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/AndroidApplication.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/AndroidApplication.kt new file mode 100644 index 0000000..2540a8a --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/AndroidApplication.kt @@ -0,0 +1,34 @@ +package es.verdnatura.almacen + +import android.app.Application +import es.verdnatura.almacen.di.components.ApplicationComponent +import es.verdnatura.almacen.di.components.DaggerApplicationComponent +import es.verdnatura.almacen.di.modules.ApplicationModule +import es.verdnatura.almacen.navigation.Navigator +import javax.inject.Inject + +/** + * Created by nelo on 20/2/17. + */ + +class AndroidApplication: Application() { + + @Inject lateinit var navigator: Navigator + + val component: ApplicationComponent by lazy { + DaggerApplicationComponent.builder().applicationModule(ApplicationModule(this)).build() + } + + override fun onCreate() { + super.onCreate() + component.inject(this) + //initializeLeakDetection() + } + + /*private fun initializeLeakDetection() { + if (BuildConfig.DEBUG) { + LeakCanary.install(this) + } + }*/ + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/adapter/HeaderAdapter.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/adapter/HeaderAdapter.kt new file mode 100644 index 0000000..bd4627f --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/adapter/HeaderAdapter.kt @@ -0,0 +1,39 @@ +package es.verdnatura.almacen.adapter + +import android.view.View +import android.widget.TextView +import butterknife.BindView +import butterknife.ButterKnife +import es.verdnatura.almacen.R +import es.verdnatura.almacen.entity.KeyValue +import es.verdnatura.core.components.recylerview.AdapterBase + +/** + * Created by nelo on 22/3/17. + */ +class HeaderAdapter(elements: List, layout: Int) : AdapterBase(elements, layout){ + + class HeaderViewHolder(itemView: View) : AdapterViewHolder(itemView){ + + @BindView(R.id.header_label) + lateinit var label: TextView + + @BindView(R.id.header_value) + lateinit var value: TextView + + override fun loadElements(itemView: View) { + ButterKnife.bind(this, itemView) + } + + override fun bindElement(t: Any) { + val map = t as KeyValue + label.setText(map.key) + value.setText(map.value) + } + + } + + override fun create(itemView: View): AdapterViewHolder { + return HeaderViewHolder(itemView) + } +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/adapter/MenuAdapter.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/adapter/MenuAdapter.kt new file mode 100644 index 0000000..ab6d0c3 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/adapter/MenuAdapter.kt @@ -0,0 +1,41 @@ +package es.verdnatura.almacen.adapter + +import android.content.Context +import android.view.View +import android.widget.ImageView +import android.widget.TextView +import butterknife.BindView +import butterknife.ButterKnife +import es.verdnatura.almacen.R +import es.verdnatura.core.components.recylerview.AdapterBase + +/** + * Created by nelo on 9/3/17. + */ +class MenuAdapter(val context: Context, items: List, resource: Int) : AdapterBase(items, resource) { + + override fun create(itemView: View): AdapterViewHolder { + return MenuViewHolder(context, itemView) + } + + class MenuViewHolder(val context: Context, itemView: View): AdapterViewHolder(itemView) { + + @BindView(R.id.menu_item_image) + lateinit var image: ImageView + + @BindView(R.id.menu_item_text) + lateinit var text: TextView + + override fun loadElements(itemView: View) { + ButterKnife.bind(this, itemView) + } + + override fun bindElement(t: Any) { + var item = t as MenuItem + image.setImageDrawable(context.resources.getDrawable(item.imageRecourse)) + text.setText(item.text) + } + } + + data class MenuItem(val id: Int, val imageRecourse: Int, val text: String) +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/adapter/TicketAdapter.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/adapter/TicketAdapter.kt new file mode 100644 index 0000000..5255435 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/adapter/TicketAdapter.kt @@ -0,0 +1,81 @@ +package es.verdnatura.almacen.adapter + +import android.view.View +import android.widget.LinearLayout +import android.widget.TextView +import butterknife.BindView +import butterknife.ButterKnife +import es.verdnatura.almacen.R +import es.verdnatura.core.UtilsResources +import es.verdnatura.core.components.recylerview.AdapterBase +import es.verdnatura.domain.entity.TicketDetail + +/** + * Created by nelo on 13/3/17. + */ +class TicketAdapter(elements: List, layout: Int): AdapterBase(elements, layout) { + + override fun create(itemView: View): AdapterViewHolder { + return OrderViewHolder(itemView) + } + + class OrderViewHolder(itemView: View): AdapterViewHolder(itemView) { + + @BindView(R.id.detail_content) lateinit var content: LinearLayout + @BindView(R.id.order_concept) lateinit var concept: TextView + @BindView(R.id.order_producer) lateinit var producer: TextView + @BindView(R.id.order_niche) lateinit var niche: TextView + @BindView(R.id.order_quantity) lateinit var quantity: TextView + @BindView(R.id.order_grouping) lateinit var grouping: TextView + @BindView(R.id.order_packing) lateinit var packing: TextView + @BindView(R.id.order_old_quantity) lateinit var oldQuantity: TextView + + override fun loadElements(itemView: View) { + ButterKnife.bind(this, itemView) + } + + override fun bindElement(t: Any) { + val detail = t as TicketDetail + concept.setText(detail.IdArticle + " - "+ detail.Concept) + producer.setText(detail.Producer) + niche.setText(detail.Niche) + quantity.setText(detail.Quantity.toString()) + setMultiply(detail) + choseColor(detail) + //if(detail.OldQuantity != detail.Quantity) + // oldQuantity.setText(detail.OldQuantity.toString()) + } + + fun setMultiply(detail: TicketDetail){ + if(detail.Packing == 0 || detail.Packing == 1){ + packing.visibility = View.GONE + grouping.visibility = View.GONE + } + else{ + packing.visibility = View.VISIBLE + grouping.visibility = View.VISIBLE + grouping.setText(detail.Grouping.toString()) + packing.setText("x"+detail.Packing+"=") + } + } + + fun choseColor(detail: TicketDetail){ + when(detail.DetailState){ + TicketDetail.State.UPLOADED -> setBackgroundColor(R.color.green) + TicketDetail.State.ERROR -> setBackgroundColor(R.color.red) + TicketDetail.State.MARKED -> setBackgroundColor(R.color.yellow) + else -> setBackgroundColor(android.R.color.white) + } + } + + fun markForUpload(){ + setBackgroundColor(R.color.yellow) + } + + fun setBackgroundColor(resourse: Int){ + content.setBackgroundColor(UtilsResources.getColor(itemView.context, resourse)) + } + + } + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/di/HasComponent.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/di/HasComponent.kt new file mode 100644 index 0000000..b2ecafd --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/di/HasComponent.kt @@ -0,0 +1,8 @@ +package es.verdnatura.almacen.di + +/** + * Created by nelo on 21/2/17. + */ +interface HasComponent { + fun getSubComponent(): C +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/di/PerActivity.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/di/PerActivity.kt new file mode 100644 index 0000000..69950c2 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/di/PerActivity.kt @@ -0,0 +1,11 @@ +package es.verdnatura.almacen.di + +import javax.inject.Scope +import kotlin.annotation.AnnotationRetention.RUNTIME +/** + * Created by nelo on 20/2/17. + */ + +@Scope +@Retention(RUNTIME) +annotation class PerActivity diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/di/components/ApplicationComponent.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/di/components/ApplicationComponent.kt new file mode 100644 index 0000000..aaf6b04 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/di/components/ApplicationComponent.kt @@ -0,0 +1,36 @@ +package es.verdnatura.almacen.di.components + +import android.app.Application +import android.content.Context +import dagger.Component +import es.verdnatura.almacen.AndroidApplication +import es.verdnatura.almacen.di.modules.ApplicationModule +import es.verdnatura.almacen.di.modules.LoginModule +import es.verdnatura.almacen.di.modules.TicketModule +import es.verdnatura.data.rest.VnConnector +import es.verdnatura.domain.repository.WarehouseRepository +import io.reactivex.Scheduler + +import javax.inject.Named + +import javax.inject.Singleton + +/** + * Created by nelo on 20/2/17. + */ +@Singleton +@Component(modules = arrayOf(ApplicationModule::class)) +interface ApplicationComponent { + + @Named("ui_thread") fun uiThread(): Scheduler + @Named("executor_thread") fun executorThread(): Scheduler + + fun inject(application: AndroidApplication) + + fun application(): Application + + fun warehouseRepository(): WarehouseRepository + + fun plus(loginModule: LoginModule): LoginComponent + fun plus(ticketModule: TicketModule): TicketComponent +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/di/components/LoginComponent.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/di/components/LoginComponent.kt new file mode 100644 index 0000000..f77c387 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/di/components/LoginComponent.kt @@ -0,0 +1,21 @@ +package es.verdnatura.almacen.di.components + +import dagger.Subcomponent +import es.verdnatura.almacen.di.PerActivity +import es.verdnatura.almacen.di.modules.LoginModule +import es.verdnatura.almacen.presenter.LoginPresenterImpl +import es.verdnatura.almacen.view.fragment.LoginFragment +import es.verdnatura.domain.interactor.LoginUseCase + + +/** + * Created by nelo on 21/2/17. + */ +@PerActivity +@Subcomponent(modules = arrayOf(LoginModule::class)) +interface LoginComponent{ + fun inject(loginFragment: LoginFragment) + + fun getLoginUseCase() : LoginUseCase + fun getLoginPresenter(): LoginPresenterImpl +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/di/components/TicketComponent.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/di/components/TicketComponent.kt new file mode 100644 index 0000000..36ae361 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/di/components/TicketComponent.kt @@ -0,0 +1,21 @@ +package es.verdnatura.almacen.di.components +import dagger.Subcomponent +import es.verdnatura.almacen.di.PerActivity +import es.verdnatura.almacen.di.modules.TicketModule +import es.verdnatura.almacen.view.components.VnTicketHeader.VnTicketHeader +import es.verdnatura.almacen.view.fragment.TicketFragment +import es.verdnatura.domain.interactor.DownloadTicketUseCase +import es.verdnatura.domain.interactor.GetMarkedTicketLinesUseCase + +/** + * Created by nelo on 8/3/17. + */ +@PerActivity +@Subcomponent(modules = arrayOf(TicketModule::class)) +interface TicketComponent{ + + fun inject(fragment: TicketFragment) + fun inject(ticketHeader: VnTicketHeader) + fun getTicketControllerUseCase(): DownloadTicketUseCase + fun getMarkedTicketLinesUseCase(): GetMarkedTicketLinesUseCase +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/di/modules/ApplicationModule.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/di/modules/ApplicationModule.kt new file mode 100644 index 0000000..eb90573 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/di/modules/ApplicationModule.kt @@ -0,0 +1,29 @@ +package es.verdnatura.almacen.di.modules + + +import android.app.Application +import dagger.Module +import javax.inject.Singleton +import dagger.Provides +import es.verdnatura.data.rest.VnConnector +import es.verdnatura.data.rest.WarehouseApiImpl +import es.verdnatura.domain.repository.WarehouseRepository +import javax.inject.Named +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers + +/** + * Created by nelo on 20/2/17. + */ +@Module +class ApplicationModule(private val application: Application) { + + @Provides @Named("executor_thread") fun provideExecutorThread() = Schedulers.newThread() + + @Provides @Named("ui_thread") fun provideUiThread() = AndroidSchedulers.mainThread() + + @Provides @Singleton fun provideApplication() = application + + @Provides @Singleton fun provideWarehouseRepository(warehouseRepository: WarehouseApiImpl): WarehouseRepository = warehouseRepository + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/di/modules/LoginModule.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/di/modules/LoginModule.kt new file mode 100644 index 0000000..74e711d --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/di/modules/LoginModule.kt @@ -0,0 +1,33 @@ +package es.verdnatura.almacen.di.modules + +import dagger.Module +import dagger.Provides +import es.verdnatura.almacen.di.PerActivity +import es.verdnatura.almacen.presenter.LoginPresenterImpl +import es.verdnatura.almacen.view.activity.LoginActivity +import es.verdnatura.almacen.view.fragment.LoginFragment +import es.verdnatura.domain.interactor.LoginUseCase +import es.verdnatura.domain.repository.WarehouseRepository +import io.reactivex.Scheduler +import javax.inject.Named + +/** + * Created by nelo on 21/2/17. + */ +@Module +class LoginModule(val activity: LoginActivity){ + + @Provides + @PerActivity + fun getLoginPresenter(loginUseCase: LoginUseCase): LoginPresenterImpl { + return LoginPresenterImpl(loginUseCase) + } + + @Provides + @PerActivity + fun getLoginUseCase(warehouseRepository: WarehouseRepository, + @Named("ui_thread") uiThread: Scheduler, + @Named("executor_thread") executorThread: Scheduler): LoginUseCase{ + return LoginUseCase(warehouseRepository, uiThread, executorThread) + } +} diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/di/modules/TicketModule.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/di/modules/TicketModule.kt new file mode 100644 index 0000000..325196e --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/di/modules/TicketModule.kt @@ -0,0 +1,33 @@ +package es.verdnatura.almacen.di.modules + +import dagger.Module +import dagger.Provides +import es.verdnatura.almacen.di.PerActivity +import es.verdnatura.almacen.view.activity.TicketActivity +import es.verdnatura.domain.interactor.DownloadTicketUseCase +import es.verdnatura.domain.interactor.GetMarkedTicketLinesUseCase +import es.verdnatura.domain.repository.WarehouseRepository +import io.reactivex.Scheduler +import javax.inject.Named + +/** + * Created by nelo on 8/3/17. + */ +@Module +class TicketModule(val activity: TicketActivity) { + + @PerActivity + @Provides + fun getTicketControllerUseCase(warehouseRepository: WarehouseRepository, + @Named("ui_thread") uiThread: Scheduler, + @Named("executor_thread") executorThread: Scheduler): DownloadTicketUseCase { + return DownloadTicketUseCase(warehouseRepository, uiThread, executorThread) + } + + @PerActivity + @Provides + fun getMarkedTicketLinesUseCase(@Named("ui_thread") uiThread: Scheduler, + @Named("executor_thread") executorThread: Scheduler): GetMarkedTicketLinesUseCase{ + return GetMarkedTicketLinesUseCase(uiThread, executorThread) + } +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/entity/KeyValue.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/entity/KeyValue.kt new file mode 100644 index 0000000..a84fca5 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/entity/KeyValue.kt @@ -0,0 +1,6 @@ +package es.verdnatura.almacen.entity + +/** + * Created by nelo on 22/3/17. + */ +data class KeyValue(val key: String, val value: String) \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/menu/TicketControlerMenu.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/menu/TicketControlerMenu.kt new file mode 100644 index 0000000..b6579ce --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/menu/TicketControlerMenu.kt @@ -0,0 +1,17 @@ +package es.verdnatura.almacen.menu + +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem + + +/** + * Created by nelo on 28/4/17. + */ +interface TicketControlerMenu { + + /*fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) + fun onOptionsItemSelected(item: MenuItem?): Boolean + fun*/ + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/menu/TicketControllerMenu.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/menu/TicketControllerMenu.kt new file mode 100644 index 0000000..3e2e363 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/menu/TicketControllerMenu.kt @@ -0,0 +1,24 @@ +package es.verdnatura.almacen.menu + +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import es.verdnatura.almacen.R + +/** + * Created by nelo on 28/4/17. + */ +class TicketControllerMenu { + + /*fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { + inflater?.inflate(R.menu.ticket_controller, menu) + } + + fun onOptionsItemSelected(item: MenuItem?): Boolean { + when (item?.itemId) { + R.id.menu_ticket_controller_search -> changeVisibilityVnScan() + } + return super.onOptionsItemSelected(item) + }*/ + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/navigation/Navigator.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/navigation/Navigator.kt new file mode 100644 index 0000000..d254502 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/navigation/Navigator.kt @@ -0,0 +1,30 @@ +package es.verdnatura.almacen.navigation + +import android.content.Intent +import es.verdnatura.almacen.R +import es.verdnatura.almacen.view.activity.BaseActivity +import es.verdnatura.almacen.view.activity.MenuActivity +import es.verdnatura.almacen.view.activity.ScanActivity +import es.verdnatura.almacen.view.activity.TicketActivity +import es.verdnatura.core.UtilsResources +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Created by nelo on 21/2/17. + */ +@Singleton +class Navigator @Inject constructor(){ + + fun navigateToMain(activity: BaseActivity){ + activity.startActivity(Intent(activity, MenuActivity::class.java)) + } + + fun navigateToController(activity: BaseActivity){ + activity.startActivity(Intent(activity, TicketActivity::class.java)) + } + + fun navigateToScan(activity: BaseActivity){ + activity.startActivityForResult(Intent(activity, ScanActivity::class.java), UtilsResources.getResourceInt(activity, R.integer.CAMERA)) + } +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/navigation/UserNavigator.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/navigation/UserNavigator.kt new file mode 100644 index 0000000..2bc2d70 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/navigation/UserNavigator.kt @@ -0,0 +1,10 @@ +package es.verdnatura.almacen.navigation + +/** + * Created by nelo on 27/4/17. + */ +interface UserNavigator { + + fun navigate() + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/observer/GetMarkedLinesObserver.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/observer/GetMarkedLinesObserver.kt new file mode 100644 index 0000000..f47432f --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/observer/GetMarkedLinesObserver.kt @@ -0,0 +1,22 @@ +package es.verdnatura.almacen.observer + +import android.util.Log +import es.verdnatura.almacen.presenter.TicketPresenterImpl +import io.reactivex.observers.DisposableObserver + +/** + * Created by nelo on 12/4/17. + */ +/*class GetMarkedLinesObserver(val tp: TicketPresenter): DisposableObserver() { + + override fun onError(e: Throwable?) { + Log.e("Error when mark a line", e?.message.toString()) + } + + override fun onComplete() { + } + + override fun onNext(t: Int?) { + tp.setMarkedLines(t!!, tp.ticket?.Details!!.size) + } +}*/ \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/observer/GetTicketObserver.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/observer/GetTicketObserver.kt new file mode 100644 index 0000000..b5865d1 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/observer/GetTicketObserver.kt @@ -0,0 +1,26 @@ +package es.verdnatura.almacen.observer + +import es.verdnatura.almacen.presenter.TicketPresenterImpl +import es.verdnatura.domain.entity.Ticket +import es.verdnatura.domain.interactor.DefaultObserver + +/** + * Created by nelo on 5/4/17. + */ +class GetTicketObserver(val tp: TicketPresenterImpl): DefaultObserver(){ + + override fun onComplete() { + super.onComplete() + tp.onCompletedDownloadedTicket() + } + + override fun onNext(t: Ticket) { + super.onNext(t) + tp.onTicketDownloaded(t) + } + + override fun onError(exception: Throwable) { + super.onError(exception) + tp.onError(exception) + } +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/BasePresenter.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/BasePresenter.kt new file mode 100644 index 0000000..073af96 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/BasePresenter.kt @@ -0,0 +1,15 @@ +package es.verdnatura.almacen.presenter + +import android.os.Bundle +import android.support.annotation.NonNull +import es.verdnatura.almacen.view.view.BaseView +import es.verdnatura.almacen.view.view.LoginView + +/** + * Created by nelo on 20/2/17. + */ +interface BasePresenter { + + fun onDestroy() + fun setView(@NonNull v: BaseView) +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/LoginPresenterImpl.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/LoginPresenterImpl.kt new file mode 100644 index 0000000..18f2655 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/LoginPresenterImpl.kt @@ -0,0 +1,85 @@ +package es.verdnatura.almacen.presenter + +import android.content.Context +import android.os.Bundle +import android.support.annotation.NonNull +import android.telephony.TelephonyManager +import android.util.Log +import es.verdnatura.almacen.view.view.BaseView +import es.verdnatura.almacen.view.view.LoginView +import es.verdnatura.domain.interactor.DefaultObserver +import es.verdnatura.domain.interactor.LoginUseCase + +import javax.inject.Inject + +/** + * Created by nelo on 20/2/17. + */ +class LoginPresenterImpl : BasePresenter { + + private var view: LoginView? = null + + private val loginUserCase: LoginUseCase + + @Inject + constructor(lus: LoginUseCase) { + this.loginUserCase = lus + } + + override fun setView(@NonNull v: BaseView){ + this.view = v as LoginView + } + + override fun onDestroy() { + this.loginUserCase.dispose() + this.view = null + } + + fun login(user: String, pass: String, imei: String, version: String) { + showViewLoading() + loginUserCase.execute(LoginObserver(this), LoginUseCase.Params.forLogin(user, pass, imei, version)) + } + + private fun manageLoginError(message: String) { + Log.e("Error", message) + view!!.showError(message) + } + + private fun manageLoginSucces() { + hideViewLoading() + view?.removeUser() + view?.removePass() + view?.navigateToMain() + } + + private fun showViewLoading() { + this.view?.showProgress() + } + + private fun hideViewLoading() { + this.view?.hideProgress() + } + + fun getImei(context: Context): String{ + val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + return telephonyManager.deviceId + } + + fun getVersion(context: Context): String{ + return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).toString() + } + + private class LoginObserver(val lp: LoginPresenterImpl) : DefaultObserver(){ + + override fun onComplete() { + super.onComplete() + lp.manageLoginSucces() + } + + override fun onError(exception: Throwable) { + super.onError(exception) + lp.manageLoginError(exception.message!!) + lp.hideViewLoading() + } + } +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/TicketPresenter.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/TicketPresenter.kt new file mode 100644 index 0000000..96d84f7 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/TicketPresenter.kt @@ -0,0 +1,19 @@ +package es.verdnatura.almacen.presenter + +import es.verdnatura.domain.entity.Ticket + +/** + * Created by nelo on 28/4/17. + */ +interface TicketPresenter: BasePresenter { + + fun getTicket(): Ticket? + fun downloadTicket(idTicket: String) + fun onRefreshTicket() + fun printTicket() + fun markLine() + fun getPendingTickets() + fun getAvailable() + fun createLine() + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/TicketPresenterImpl.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/TicketPresenterImpl.kt new file mode 100644 index 0000000..6698313 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/TicketPresenterImpl.kt @@ -0,0 +1,76 @@ +package es.verdnatura.almacen.presenter + +import es.verdnatura.almacen.observer.GetTicketObserver +import es.verdnatura.almacen.view.view.BaseView +import es.verdnatura.almacen.view.view.TicketView +import es.verdnatura.domain.entity.Ticket +import es.verdnatura.domain.interactor.DownloadTicketUseCase + +import javax.inject.Inject + +/** + * Created by nelo on 8/3/17. + */ +class TicketPresenterImpl : TicketPresenter { + + private var view: TicketView? = null + + private val downloadTicketUseCase: DownloadTicketUseCase + + private var ticket: Ticket? = null + + @Inject constructor(downloadTicketUseCase: DownloadTicketUseCase){ + this.downloadTicketUseCase = downloadTicketUseCase + } + + override fun getPendingTickets() {} + + override fun onDestroy() { + downloadTicketUseCase.dispose() + view = null + } + + override fun setView(v: BaseView) { + view = v as TicketView + } + + override fun downloadTicket(idTicket: String) = downloadTicketUseCase.execute(GetTicketObserver(this), DownloadTicketUseCase.Params.forGetTicket(idTicket)) + + override fun onRefreshTicket() { + downloadTicket(ticket?.IdTicket.toString()) + } + + override fun printTicket() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun markLine() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun getAvailable() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun createLine() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + fun onTicketDownloaded(ticket: Ticket){ + this.ticket = ticket + view?.onDownloadTicket(ticket) + } + + override fun getTicket(): Ticket? = ticket + + fun onCompletedDownloadedTicket() { + view?.hideProgress() + view?.clearVnScan() + } + + fun onError(exception: Throwable){ + view?.hideProgress() + view?.showError(exception.message.toString()) + } + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/VnTicketHeaderPresenter.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/VnTicketHeaderPresenter.kt new file mode 100644 index 0000000..a034b85 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/presenter/VnTicketHeaderPresenter.kt @@ -0,0 +1,45 @@ +package es.verdnatura.almacen.presenter + +import android.util.Log +import es.verdnatura.almacen.view.components.VnTicketHeader.VnTicketHeader +import es.verdnatura.almacen.view.view.VnHeaderView +import es.verdnatura.domain.entity.Ticket +import es.verdnatura.domain.interactor.GetMarkedTicketLinesUseCase +import io.reactivex.observers.DisposableObserver +import javax.inject.Inject + +/** + * Created by nelo on 28/4/17. + */ +class VnTicketHeaderPresenter @Inject constructor(getMarkedTicketLinesUseCase: GetMarkedTicketLinesUseCase) { + + private val useCaseMarkedLines: GetMarkedTicketLinesUseCase = getMarkedTicketLinesUseCase + private lateinit var header: VnHeaderView + + fun getMarkedLine(ticket: Ticket){ + useCaseMarkedLines.execute(GetMarkedLinesObserver(this, ticket), GetMarkedTicketLinesUseCase.Params.forGetMarkedLines(ticket)) + } + + fun setHeader(header: VnHeaderView){ + this.header = header + } + + fun setTicketsMarked(marked: Int, total: Int){ + header.setTicketsMarked(marked, total) + } + + class GetMarkedLinesObserver(val presenter: VnTicketHeaderPresenter, val ticket: Ticket): DisposableObserver() { + + override fun onError(e: Throwable?) { + presenter.setTicketsMarked(0, ticket.Details.size) + Log.e("Error when mark a line", e?.message.toString()) + } + + override fun onComplete() { + } + + override fun onNext(t: Int?) { + presenter.setTicketsMarked(t!!, ticket.Details.size) + } + } +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/BaseActivity.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/BaseActivity.kt new file mode 100644 index 0000000..fe95e15 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/BaseActivity.kt @@ -0,0 +1,42 @@ +package es.verdnatura.almacen.view.activity + +import android.app.Fragment +import android.content.Intent +import android.content.pm.ActivityInfo +import android.os.Bundle +import android.support.v7.app.AppCompatActivity +import es.verdnatura.almacen.AndroidApplication +import es.verdnatura.almacen.navigation.Navigator + + +/** + * Created by nelo on 20/2/17. + */ +open class BaseActivity : AppCompatActivity() { + + val app: AndroidApplication get() = application as AndroidApplication + val navigator: Navigator get() = app.navigator + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + + protected fun addFragment(containerViewId: Int, fragment: Fragment) { + val fragmentTransaction = this.fragmentManager.beginTransaction() + fragmentTransaction.add(containerViewId, fragment) + fragmentTransaction.commit() + } + + fun changeFragment(containerViewId: Int, fragment: Fragment) { + val transaccion = fragmentManager.beginTransaction() + transaccion.replace(containerViewId, fragment) + transaccion.addToBackStack(null) + transaccion.commit() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + } + +} diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/LoginActivity.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/LoginActivity.kt new file mode 100644 index 0000000..1d2d9d6 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/LoginActivity.kt @@ -0,0 +1,32 @@ +package es.verdnatura.almacen.view.activity + +import android.os.Bundle +import es.verdnatura.almacen.R +import es.verdnatura.almacen.di.HasComponent +import es.verdnatura.almacen.di.components.LoginComponent +import es.verdnatura.almacen.di.modules.LoginModule +import es.verdnatura.almacen.navigation.UserNavigator +import es.verdnatura.almacen.view.fragment.LoginFragment + +class LoginActivity : BaseActivity(), HasComponent, UserNavigator { + + val component by lazy { app.component.plus(LoginModule(this)) } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_layout) + + if(savedInstanceState == null) + addFragment(R.id.fragmentContainer, LoginFragment(R.layout.fragment_login)) + + } + + override fun getSubComponent(): LoginComponent { + return component + } + + override fun navigate() { + app.navigator.navigateToMain(this) + } + +} diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/MenuActivity.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/MenuActivity.kt new file mode 100644 index 0000000..fc36cbe --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/MenuActivity.kt @@ -0,0 +1,58 @@ +package es.verdnatura.almacen.view.activity + +import android.os.Bundle +import android.util.DisplayMetrics +import android.view.View +import butterknife.BindView +import butterknife.ButterKnife +import es.verdnatura.almacen.R +import es.verdnatura.almacen.adapter.MenuAdapter +import es.verdnatura.core.UtilsResources +import es.verdnatura.core.components.recylerview.VnRecyclerView +import java.util.* + +class MenuActivity : BaseActivity() { + + @BindView(R.id.list_menu) + lateinit var list: VnRecyclerView + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_menu) + ButterKnife.bind(this) + list.setAdapterGrid(getAdapter(), getColumns()) + } + + private fun getAdapter(): MenuAdapter{ + var adapter = MenuAdapter(this, getItems(), R.layout.vnmenuitem) + adapter.setOnClickListener(View.OnClickListener {v -> clickMenuItem(adapter.getItem(list.getChildAdapterPosition(v)) as MenuAdapter.MenuItem) }) + return adapter + } + + private fun getItems(): List{ + var items = ArrayList() + + items.add(MenuAdapter.MenuItem(R.id.MENU_CONTROLLER, R.drawable.controlador, UtilsResources.getResourceString(this, R.string.controller))) + //items.add(MenuAdapter.MenuItem(R.id.MENU_SERVER, R.drawable.sacador, "Sacador")) + //items.add(MenuAdapter.MenuItem(R.id.MENU_SERVER_MOVEMENT, R.drawable.sacador, "Sacador")) + + return items + } + + private fun clickMenuItem(item: MenuAdapter.MenuItem) { + when (item.id){ + R.id.MENU_CONTROLLER -> navigator.navigateToController(this) + } + } + + private fun getColumns(): Int { + return (getWidth() / resources.getDimension(R.dimen.vn_menu_item_width)).toInt() + } + + private fun getWidth(): Int { + val displaymetrics = DisplayMetrics() + getWindowManager().getDefaultDisplay().getMetrics(displaymetrics) + return displaymetrics.widthPixels + } + +} diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/ScanActivity.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/ScanActivity.kt new file mode 100644 index 0000000..d68513b --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/ScanActivity.kt @@ -0,0 +1,44 @@ +package es.verdnatura.almacen.view.activity + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import com.google.zxing.Result +import me.dm7.barcodescanner.zxing.ZXingScannerView + + +class ScanActivity : Activity(), ZXingScannerView.ResultHandler { + + private lateinit var mScannerView: ZXingScannerView + + companion object{ + val BARCODE = "BARCODE" + } + + public override fun onCreate(state: Bundle?) { + super.onCreate(state) + mScannerView = ZXingScannerView(this) + setContentView(mScannerView) + } + + public override fun onResume() { + super.onResume() + mScannerView.setResultHandler(this) + mScannerView.startCamera() + } + + public override fun onPause() { + super.onPause() + mScannerView.stopCamera() + } + + override fun handleResult(rawResult: Result) { + mScannerView.resumeCameraPreview(this) + + val returnIntent = Intent() + returnIntent.putExtra(BARCODE, rawResult.text) + setResult(RESULT_OK, returnIntent) + finish() + } + +} diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/TicketActivity.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/TicketActivity.kt new file mode 100644 index 0000000..9b3ef2d --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/activity/TicketActivity.kt @@ -0,0 +1,35 @@ +package es.verdnatura.almacen.view.activity + +import android.os.Bundle +import es.verdnatura.almacen.R +import es.verdnatura.almacen.di.HasComponent +import es.verdnatura.almacen.di.components.TicketComponent +import es.verdnatura.almacen.di.modules.TicketModule +import es.verdnatura.almacen.navigation.UserNavigator +import es.verdnatura.almacen.view.fragment.TicketFragment +import es.verdnatura.almacen.view.fragment.TicketHeader +import es.verdnatura.domain.entity.Ticket + +class TicketActivity : BaseActivity(), HasComponent, UserNavigator { + + val component by lazy { app.component.plus(TicketModule(this)) } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_layout) + addFragment(R.id.fragmentContainer, TicketFragment(R.layout.fragment_ticket)) + } + + override fun getSubComponent(): TicketComponent { + return component + } + + override fun navigate() { + navigator.navigateToScan(this) + } + + fun showHeader(ticket: Ticket) { + changeFragment(R.id.fragmentContainer, TicketHeader(R.layout.fragment_ticket_header, ticket)) + } + +} diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/components/VnTicketHeader/VnTicketHeader.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/components/VnTicketHeader/VnTicketHeader.kt new file mode 100644 index 0000000..a9646bf --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/components/VnTicketHeader/VnTicketHeader.kt @@ -0,0 +1,68 @@ +package es.verdnatura.almacen.view.components.VnTicketHeader + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.widget.RelativeLayout +import android.widget.TextView +import butterknife.BindView +import butterknife.ButterKnife +import es.verdnatura.almacen.R +import es.verdnatura.almacen.di.HasComponent +import es.verdnatura.almacen.di.components.TicketComponent +import es.verdnatura.almacen.presenter.VnTicketHeaderPresenter +import es.verdnatura.almacen.view.view.VnHeaderView +import es.verdnatura.domain.entity.Ticket +import javax.inject.Inject + +/** + * Created by nelo on 5/4/17. + */ +class VnTicketHeader : RelativeLayout, VnHeaderView { + + @BindView(R.id.ticket_header_client) lateinit var ticketClient: TextView + @BindView(R.id.ticket_header_numer_tickets) lateinit var ticketNumberTickets: TextView + @BindView(R.id.ticket_header_lines_marked) lateinit var ticketsMarked: TextView + + @Inject lateinit var presenter: VnTicketHeaderPresenter + + constructor(context: Context?) : super(context){ + render(context) + } + + constructor(context: Context?, attributeSet: AttributeSet?): super(context, attributeSet){ + render(context) + } + + constructor(context: Context?, attributeSet: AttributeSet?, defStyleAttr: Int): super(context, attributeSet, defStyleAttr){ + render(context) + } + + fun render(context: Context?){ + LayoutInflater.from(context).inflate(R.layout.view_ticket_header, this) + ButterKnife.bind(this) + (context as HasComponent).getSubComponent().inject(this) + presenter.setHeader(this) + } + + fun show(){ + visibility = View.VISIBLE + } + + fun hide(){ + visibility = View.GONE + } + + fun setHeader(ticket: Ticket){ + setDataTicket(ticket.IdTicket, ticket.ClientName) + setNumberTickets(ticket.Tickets) + presenter.getMarkedLine(ticket) + } + + private fun setDataTicket(IdTicket: Int, ClientName: String) = ticketClient.setText(IdTicket.toString() + "/" + ClientName) + + private fun setNumberTickets(numberTickets: Int) = ticketNumberTickets.setText(numberTickets.toString()) + + override fun setTicketsMarked(marked: Int, total: Int) = ticketsMarked.setText(marked.toString() + "/" + total.toString()) +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/components/VnTicketRecycler.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/components/VnTicketRecycler.kt new file mode 100644 index 0000000..b0a9045 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/components/VnTicketRecycler.kt @@ -0,0 +1,38 @@ +package es.verdnatura.almacen.view.components + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import es.verdnatura.almacen.R +import es.verdnatura.almacen.adapter.TicketAdapter +import es.verdnatura.core.components.recylerview.VnRecyclerView +import es.verdnatura.domain.entity.Ticket +import es.verdnatura.domain.entity.TicketDetail +import es.verdnatura.domain.interactor.GetMarkedTicketLinesUseCase +import javax.inject.Inject + +/** + * Created by nelo on 19/4/17. + */ +class VnTicketRecycler(context: Context, attributeSet: AttributeSet): VnRecyclerView(context, attributeSet) { + + lateinit var adapter: TicketAdapter + @Inject lateinit var caseTicket: GetMarkedTicketLinesUseCase + + fun createAdapter(ticket: Ticket){ + adapter = TicketAdapter(ticket.Details, R.layout.ticket_item) + setAdapterList(adapter) + adapter.setOnClickListener(View.OnClickListener {v -> markLine(v) }) + + } + + private fun changeAdapter(){ + adapter.notifyDataSetChanged() + } + + private fun markLine(v: View) { + var ticketDetail = adapter.getItem(getChildAdapterPosition(v)) as TicketDetail + ticketDetail.DetailState = TicketDetail.State.MARKED + changeAdapter() + } +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/BaseFragment.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/BaseFragment.kt new file mode 100644 index 0000000..d908f6e --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/BaseFragment.kt @@ -0,0 +1,61 @@ +package es.verdnatura.almacen.view.fragment + +import android.app.Activity +import android.app.Fragment +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import butterknife.ButterKnife +import butterknife.Unbinder +import es.verdnatura.almacen.di.HasComponent +import es.verdnatura.almacen.navigation.UserNavigator +import es.verdnatura.almacen.view.activity.BaseActivity +import es.verdnatura.core.components.snackbar.VnSnackbar + +/** + * Created by nelo on 21/2/17. + */ +open class BaseFragment(val layout: Int) : Fragment(){ + + private lateinit var unbinder: Unbinder + lateinit var userNavigatior: UserNavigator + + val app get() = (activity as BaseActivity).app + + override fun onAttach(activity: Activity?) { + super.onAttach(activity) + if(activity is UserNavigator) + userNavigatior = activity + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setHasOptionsMenu(true) + } + + override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View { + val fragmentView = inflater?.inflate(layout, container, false) + unbinder = ButterKnife.bind(this, fragmentView!!) + return fragmentView + } + + override fun onDestroyView() { + super.onDestroyView() + unbinder.unbind() + } + + fun showToastMessage(message: String){ + Toast.makeText(activity, message, Toast.LENGTH_SHORT).show() + } + + fun showSnackBarMessage(message: String){ + VnSnackbar.make(this.view, message) + } + + protected fun getComponent(componentType: Class): C { + return componentType.cast((activity as HasComponent).getSubComponent()) + } + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/LoginFragment.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/LoginFragment.kt new file mode 100644 index 0000000..92e5cfb --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/LoginFragment.kt @@ -0,0 +1,74 @@ +package es.verdnatura.almacen.view.fragment + +import android.os.Bundle +import android.text.method.HideReturnsTransformationMethod +import android.text.method.PasswordTransformationMethod +import android.view.View +import android.widget.EditText +import butterknife.* +import es.verdnatura.almacen.R +import es.verdnatura.almacen.di.components.LoginComponent +import es.verdnatura.almacen.presenter.LoginPresenterImpl +import es.verdnatura.almacen.view.view.LoginView +import es.verdnatura.core.components.dialogs.retry.DialogRetry +import es.verdnatura.core.components.progress.VnProgress +import javax.inject.Inject + +/** + * Created by nelo on 21/2/17. + */ +class LoginFragment(layout: Int) : BaseFragment(layout), LoginView { + + @Inject lateinit var loginPresenter: LoginPresenterImpl + + @BindView(R.id.edit_user) lateinit var editUser: EditText + @BindView(R.id.edit_password) lateinit var editPassword: EditText + @BindView(R.id.progress) lateinit var progress: VnProgress + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + } + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + this.getComponent(LoginComponent::class.java).inject(this) + this.loginPresenter.setView(this) + } + + @OnCheckedChanged(R.id.show_password) + fun showOrHidePassword(isChecked: Boolean){ + if(isChecked) editPassword.transformationMethod = HideReturnsTransformationMethod.getInstance() + else editPassword.transformationMethod = PasswordTransformationMethod.getInstance() + editPassword.setSelection(editPassword.text.length) + } + + @OnClick(R.id.button_login) + fun login() { + loginPresenter.login(editUser.text.toString(), editPassword.text.toString(), loginPresenter.getImei(activity), loginPresenter.getVersion(activity)) + } + + override fun showProgress() { + progress.show() + } + + override fun hideProgress() { + progress.hide() + } + + override fun showError(message: String) { + val dialog = DialogRetry(message, { login() }) + dialog.show(fragmentManager, "alert") + } + + override fun removeUser() { + editUser.setText("") + } + + override fun removePass() { + editPassword.setText("") + } + + override fun navigateToMain() { + userNavigatior.navigate() + } +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/TicketFragment.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/TicketFragment.kt new file mode 100644 index 0000000..937f58a --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/TicketFragment.kt @@ -0,0 +1,147 @@ +package es.verdnatura.almacen.view.fragment + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import android.view.* +import butterknife.BindView +import butterknife.OnClick +import es.verdnatura.almacen.R +import es.verdnatura.almacen.view.components.VnTicketHeader.VnTicketHeader +import es.verdnatura.almacen.di.components.TicketComponent +import es.verdnatura.almacen.presenter.TicketPresenterImpl +import es.verdnatura.almacen.view.activity.ScanActivity +import es.verdnatura.almacen.view.activity.TicketActivity +import es.verdnatura.almacen.view.components.VnTicketRecycler +import es.verdnatura.almacen.view.view.TicketView +import es.verdnatura.core.components.editscan.VnEditScan +import es.verdnatura.core.components.dialogs.retry.DialogRetry +import es.verdnatura.core.components.progress.VnProgress +import es.verdnatura.core.components.swiperefreshlayout.VnSwipeRefreshLayout +import es.verdnatura.domain.entity.Ticket +import es.verdnatura.domain.entity.TicketDetail +import javax.inject.Inject + +/** + * Created by nelo on 7/3/17. + */ +class TicketFragment(layout: Int) : BaseFragment(layout), TicketView { + + @Inject lateinit var presenter: TicketPresenterImpl + + @BindView(R.id.progress) lateinit var progress: VnProgress + @BindView(R.id.vnrecycler) lateinit var list: VnTicketRecycler + @BindView(R.id.edit_search_ticket) lateinit var editTicket: VnEditScan + @BindView(R.id.swipe_refresh_ticket) lateinit var swipeRefresh: VnSwipeRefreshLayout + @BindView(R.id.ticket_header) lateinit var vnTicketHeader: VnTicketHeader + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + this.getComponent(TicketComponent::class.java).inject(this) + this.presenter.setView(this) + } + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + hideHeader() + initVnScan() + checkTicketAlreadyExist() + initSwipeRefresh() + } + + override fun onDownloadTicket(ticket: Ticket) { + createAdapter(ticket) + showHeader() + setHeader(ticket) + hideVnScan() + enableVnSwipeRefresh() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (resultCode == Activity.RESULT_OK && requestCode == activity.resources.getInteger(R.integer.CAMERA) && data != null) { + editTicket.setTextScan(data!!.getStringExtra(ScanActivity.BARCODE)) + downloadTicket(editTicket.getText()) + } + } + + override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { + super.onCreateOptionsMenu(menu, inflater) + inflater?.inflate(R.menu.ticket_controller, menu) + } + + override fun onOptionsItemSelected(item: MenuItem?): Boolean { + when (item?.itemId) { + R.id.menu_ticket_controller_search -> changeVisibilityVnScan() + } + return super.onOptionsItemSelected(item) + } + + override fun showError(message: String) { + var dialog = DialogRetry(message, { downloadTicket(editTicket.getText()) }) + dialog.show(fragmentManager, "ticketRetry") + } + + override fun hideProgress() { + progress.hide() + swipeRefresh.hideProgress() + } + + fun initSwipeRefresh() { + swipeRefresh.setOnRefreshListener { onRefreshTicket() } + swipeRefresh.disableProgress() + } + + fun downloadTicket(ticket: String) { + showProgress() + presenter.downloadTicket(ticket) + } + + fun onRefreshTicket() { + swipeRefresh.showProgress() + presenter.onRefreshTicket() + } + + fun initVnScan() { + editTicket.onScan { downloadTicket(editTicket.getText()) } + editTicket.setScanAction { scan() } + } + + fun checkTicketAlreadyExist() { + if(presenter.getTicket() != null) onDownloadTicket(presenter.getTicket()!!) + } + + fun createAdapter(ticket: Ticket) { + list.createAdapter(ticket) + } + + fun markLine(v: View){ + var ticketDetail = list.adapter.getItem(list.getChildAdapterPosition(v)) as TicketDetail + ticketDetail.DetailState = TicketDetail.State.MARKED + } + + override fun clearVnScan() = editTicket.clear() + + override fun showProgress() = progress.show() + + fun setHeader(ticket: Ticket) = vnTicketHeader.setHeader(ticket) + + fun enableVnSwipeRefresh() = swipeRefresh.enableProgress() + + fun scan() = userNavigatior.navigate() + + fun changeVisibilityVnScan() = if (editTicket.isVisible()) hideVnScan() else showVnScan() + + fun showHeader() = vnTicketHeader.show() + + fun hideHeader() = vnTicketHeader.hide() + + fun hideVnScan() = editTicket.hide() + + fun showVnScan() = editTicket.show() + + /***** ELIMINAR ACOPLAMIENTO *****/ + + @OnClick(R.id.view_ticket_header) fun clickHeader() = (activity as TicketActivity).showHeader(presenter.getTicket()!!) + +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/TicketHeader.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/TicketHeader.kt new file mode 100644 index 0000000..9642799 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/fragment/TicketHeader.kt @@ -0,0 +1,49 @@ +package es.verdnatura.almacen.view.fragment + +import android.os.Bundle +import android.view.View +import butterknife.BindView +import es.verdnatura.almacen.R +import es.verdnatura.almacen.adapter.HeaderAdapter +import es.verdnatura.almacen.entity.KeyValue +import es.verdnatura.almacen.view.activity.TicketActivity +import es.verdnatura.core.UtilsResources +import es.verdnatura.core.components.recylerview.VnRecyclerView +import es.verdnatura.domain.entity.Ticket +import java.util.* + +/** + * Created by nelo on 20/3/17. + */ +class TicketHeader(layout: Int, var ticket: Ticket?): BaseFragment(layout) { + + @BindView(R.id.ticket_header_info) + lateinit var ticketHeaderInfo: VnRecyclerView + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + if(ticket != null) createAdapter(ticket!!) + } + + fun createAdapter(ticket: Ticket){ + ticketHeaderInfo.setAdapterList(HeaderAdapter(createItems(ticket), R.layout.ticket_header_item)) + } + + fun createItems(ticket: Ticket) : List { + var items = ArrayList() + items.add(KeyValue(getLabel(R.string.ticket_id), ticket.IdTicket.toString())) + items.add(KeyValue(getLabel(R.string.ticket_client), ticket.ClientCode + " - " +ticket.ClientName)) + items.add(KeyValue(getLabel(R.string.ticket_agency), ticket.Agency)) + items.add(KeyValue(getLabel(R.string.ticket_transport), ticket.Transport)) + items.add(KeyValue(getLabel(R.string.ticket_city), ticket.ClientCity)) + items.add(KeyValue(getLabel(R.string.ticket_date), ticket.Date)) + items.add(KeyValue(getLabel(R.string.ticket_server), ticket.Server)) + items.add(KeyValue(getLabel(R.string.ticket_commercial), ticket.Commercial)) + items.add(KeyValue(getLabel(R.string.ticket_observations), ticket.Observations)) + return items + } + + fun getLabel(resource: Int): String{ + return UtilsResources.getResourceString(activity, resource) + } +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/BaseView.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/BaseView.kt new file mode 100644 index 0000000..24926fa --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/BaseView.kt @@ -0,0 +1,6 @@ +package es.verdnatura.almacen.view.view + +/** + * Created by nelo on 8/3/17. + */ +interface BaseView \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/LoadDataView.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/LoadDataView.kt new file mode 100644 index 0000000..273ceb2 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/LoadDataView.kt @@ -0,0 +1,11 @@ +package es.verdnatura.almacen.view.view + +/** + * Created by nelo on 24/2/17. + */ +interface LoadDataView: BaseView { + + fun showProgress() + fun hideProgress() + fun showError(message: String) +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/LoginView.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/LoginView.kt new file mode 100644 index 0000000..67e048a --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/LoginView.kt @@ -0,0 +1,11 @@ +package es.verdnatura.almacen.view.view + + +/** + * Created by nelo on 21/2/17. + */ +interface LoginView : LoadDataView{ + fun removeUser() + fun removePass() + fun navigateToMain() +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/TicketView.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/TicketView.kt new file mode 100644 index 0000000..40be752 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/TicketView.kt @@ -0,0 +1,13 @@ +package es.verdnatura.almacen.view.view + +import es.verdnatura.domain.entity.Ticket +import es.verdnatura.domain.entity.TicketDetail + +/** + * Created by nelo on 7/3/17. + */ +interface TicketView : LoadDataView { + + fun clearVnScan() + fun onDownloadTicket(ticket: Ticket) +} \ No newline at end of file diff --git a/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/VnHeaderView.kt b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/VnHeaderView.kt new file mode 100644 index 0000000..b53d451 --- /dev/null +++ b/presentation/src/main/kotlin/es/verdnatura/almacen/view/view/VnHeaderView.kt @@ -0,0 +1,8 @@ +package es.verdnatura.almacen.view.view + +/** + * Created by nelo on 28/4/17. + */ +interface VnHeaderView: BaseView { + fun setTicketsMarked(marked: Int, total: Int) +} \ No newline at end of file diff --git a/presentation/src/main/res/drawable/comercial.png b/presentation/src/main/res/drawable/comercial.png new file mode 100644 index 0000000..206c2bd Binary files /dev/null and b/presentation/src/main/res/drawable/comercial.png differ diff --git a/presentation/src/main/res/drawable/controlador.png b/presentation/src/main/res/drawable/controlador.png new file mode 100644 index 0000000..2c9e702 Binary files /dev/null and b/presentation/src/main/res/drawable/controlador.png differ diff --git a/presentation/src/main/res/drawable/controlador_movimiento.png b/presentation/src/main/res/drawable/controlador_movimiento.png new file mode 100644 index 0000000..261684b Binary files /dev/null and b/presentation/src/main/res/drawable/controlador_movimiento.png differ diff --git a/presentation/src/main/res/drawable/header.png b/presentation/src/main/res/drawable/header.png new file mode 100644 index 0000000..e38f484 Binary files /dev/null and b/presentation/src/main/res/drawable/header.png differ diff --git a/presentation/src/main/res/drawable/ic_detail.xml b/presentation/src/main/res/drawable/ic_detail.xml new file mode 100644 index 0000000..f2986b7 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_detail.xml @@ -0,0 +1,9 @@ + + + diff --git a/presentation/src/main/res/drawable/ic_edit.xml b/presentation/src/main/res/drawable/ic_edit.xml new file mode 100644 index 0000000..e730edf --- /dev/null +++ b/presentation/src/main/res/drawable/ic_edit.xml @@ -0,0 +1,9 @@ + + + diff --git a/presentation/src/main/res/drawable/ic_print.xml b/presentation/src/main/res/drawable/ic_print.xml new file mode 100644 index 0000000..7a9bc00 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_print.xml @@ -0,0 +1,9 @@ + + + diff --git a/presentation/src/main/res/drawable/ic_search.xml b/presentation/src/main/res/drawable/ic_search.xml new file mode 100644 index 0000000..47432c1 --- /dev/null +++ b/presentation/src/main/res/drawable/ic_search.xml @@ -0,0 +1,9 @@ + + + diff --git a/presentation/src/main/res/drawable/login.png b/presentation/src/main/res/drawable/login.png new file mode 100644 index 0000000..97cb034 Binary files /dev/null and b/presentation/src/main/res/drawable/login.png differ diff --git a/presentation/src/main/res/drawable/pasillero.png b/presentation/src/main/res/drawable/pasillero.png new file mode 100644 index 0000000..b5dcfc3 Binary files /dev/null and b/presentation/src/main/res/drawable/pasillero.png differ diff --git a/presentation/src/main/res/drawable/sacador.png b/presentation/src/main/res/drawable/sacador.png new file mode 100644 index 0000000..b328e50 Binary files /dev/null and b/presentation/src/main/res/drawable/sacador.png differ diff --git a/presentation/src/main/res/drawable/sacador_movimiento.png b/presentation/src/main/res/drawable/sacador_movimiento.png new file mode 100644 index 0000000..a956707 Binary files /dev/null and b/presentation/src/main/res/drawable/sacador_movimiento.png differ diff --git a/presentation/src/main/res/drawable/settings.png b/presentation/src/main/res/drawable/settings.png new file mode 100644 index 0000000..f84a212 Binary files /dev/null and b/presentation/src/main/res/drawable/settings.png differ diff --git a/presentation/src/main/res/layouts/activity/layout/activity_layout.xml b/presentation/src/main/res/layouts/activity/layout/activity_layout.xml new file mode 100644 index 0000000..f3a24bf --- /dev/null +++ b/presentation/src/main/res/layouts/activity/layout/activity_layout.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/presentation/src/main/res/layouts/activity/layout/activity_menu.xml b/presentation/src/main/res/layouts/activity/layout/activity_menu.xml new file mode 100644 index 0000000..3d27882 --- /dev/null +++ b/presentation/src/main/res/layouts/activity/layout/activity_menu.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/presentation/src/main/res/layouts/fragment/layout/fragment_login.xml b/presentation/src/main/res/layouts/fragment/layout/fragment_login.xml new file mode 100644 index 0000000..8b05137 --- /dev/null +++ b/presentation/src/main/res/layouts/fragment/layout/fragment_login.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + +