First commit

This commit is contained in:
nelo 2017-09-15 07:41:54 +02:00
commit 368df6f647
139 changed files with 3716 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild

10
.hgignore Normal file
View File

@ -0,0 +1,10 @@
syntax: glob
*.iml
.gradle
.idea/dictionaries
.idea/libraries
.idea/tasks.xml
.idea/workspace.xml
build
gen
local.properties

22
.idea/compiler.xml Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
<entry name="!?*.aj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

View File

@ -0,0 +1,3 @@
<component name="CopyrightManager">
<settings default="" />
</component>

6
.idea/encodings.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

22
.idea/gradle.xml Normal file
View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.14.1" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/core" />
<option value="$PROJECT_DIR$/data" />
<option value="$PROJECT_DIR$/domain" />
<option value="$PROJECT_DIR$/presentation" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

7
.idea/kotlinc.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinCommonCompilerArguments">
<option name="languageVersion" value="1.0" />
<option name="apiVersion" value="1.0" />
</component>
</project>

46
.idea/misc.xml Normal file
View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

12
.idea/modules.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Almacen.iml" filepath="$PROJECT_DIR$/Almacen.iml" />
<module fileurl="file://$PROJECT_DIR$/core/core.iml" filepath="$PROJECT_DIR$/core/core.iml" />
<module fileurl="file://$PROJECT_DIR$/data/data.iml" filepath="$PROJECT_DIR$/data/data.iml" />
<module fileurl="file://$PROJECT_DIR$/domain/domain.iml" filepath="$PROJECT_DIR$/domain/domain.iml" />
<module fileurl="file://$PROJECT_DIR$/presentation/presentation.iml" filepath="$PROJECT_DIR$/presentation/presentation.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

41
build.gradle Normal file
View File

@ -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'
}

13
buildsystem/ci.gradle Normal file
View File

@ -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
}
}
}

View File

@ -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}",
]
}

1
data/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

59
data/build.gradle Normal file
View File

@ -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()
}

17
data/proguard-rules.pro vendored Normal file
View File

@ -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 *;
#}

View File

@ -0,0 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="es.verdnatura.data">
<application android:allowBackup="true" android:label="@string/app_name"
android:supportsRtl="true">
</application>
</manifest>

View File

@ -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<String> = ArrayList()
val Discount: Float = 0.0F
val Reserved: Int = 0
val Price: Float = 0.0F
val Path: String = ""
}

View File

@ -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<TicketDetailDto> = ArrayList()
}

View File

@ -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))

View File

@ -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))

View File

@ -0,0 +1,6 @@
package es.verdnatura.data.exceptions
/**
* Created by nelo on 1/3/17.
*/
class ServerException(override var message: String) : RuntimeException(message)

View File

@ -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))

View File

@ -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<Int>
@POST("warehouse/get_ticket_controller")
fun getTicketController(@Body vararg args: Any): Observable<TicketDto>
}

View File

@ -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<Int> {
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<Ticket>{
return mWarehouseApi!!.getTicketController(ticket)
.map { ticket -> serializer.serialize(ticket, TicketDto::class.java) }
.map { json -> serializer.deserialize(json, Ticket::class.java) }
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Data</string>
</resources>

View File

@ -0,0 +1,10 @@
<resources>
<!--<string name="host">http://172.16.200.2/silex/</string>-->
<string name="app_name">Data</string>
<string name="error_500">Internal server error</string>
<string name="error_404">Resource not found</string>
<string name="time_out">Connection timeout</string>
<string name="error_login">Invalid user or pass</string>
</resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--<string name="host">https://app.verdnatura.es/</string>-->
</resources>

1
domain/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

1
domain/.hgignore Normal file
View File

@ -0,0 +1 @@
/build

40
domain/build.gradle Normal file
View File

@ -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()
}

View File

@ -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
}
}
}

View File

@ -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<TicketDetail> = ArrayList()
}

View File

@ -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<String> = 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
}
}

View File

@ -0,0 +1,15 @@
package es.verdnatura.domain.interactor
import io.reactivex.observers.DisposableObserver
/**
* Created by nelo on 27/2/17.
*/
open class DefaultObserver<T> : DisposableObserver<T>() {
override fun onNext(t: T) {}
override fun onComplete() {}
override fun onError(exception: Throwable ){}
}

View File

@ -0,0 +1,20 @@
package es.verdnatura.domain.interactor
/**
* Created by nelo on 16/2/17.
*/
class DefaultObserver<T> : DisposableObserver<T>() {
override fun onComplete() {
}
override fun onError(e: Throwable?) {
}
override fun onNext(value: T) {
}
}

View File

@ -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<Ticket, DownloadTicketUseCase.Params> {
val repository: WarehouseRepository
@Inject
constructor(repository: WarehouseRepository, uiThread: Scheduler, mExecutorThread: Scheduler) : super(uiThread, mExecutorThread) {
this.repository = repository
}
override fun buildUseCaseObservable(params: Params): Observable<Ticket> {
return this.repository.getTicketController(params.ticket)
}
class Params private constructor(val ticket: String) {
companion object{
fun forGetTicket(ticket: String): Params {
return Params(ticket)
}
}
}
}

View File

@ -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<Int, GetMarkedTicketLinesUseCase.Params> {
@Inject
constructor(uiThread: Scheduler, mExecutorThread: Scheduler) : super(uiThread, mExecutorThread)
override fun buildUseCaseObservable(params: Params): Observable<Int> {
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)
}
}
}
}

View File

@ -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<Int, LoginUseCase.Params>{
val repository: WarehouseRepository
@Inject
constructor(repository: WarehouseRepository, uiThread: Scheduler, mExecutorThread: Scheduler) : super(uiThread, mExecutorThread) {
this.repository = repository
}
override fun buildUseCaseObservable(params: Params): Observable<Int> {
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)
}
}
}
}

View File

@ -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<T, Params> {
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<T>
open fun execute(observer: DisposableObserver<T>, params: Params) {
Preconditions.checkNotNull(params)
Preconditions.checkNotNull(observer)
val observable: Observable<T> = 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)
}
}

View File

@ -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<Int>
fun getTicketController(ticket: String): Observable<Ticket>
}

View File

@ -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)
}
}

View File

@ -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()
}

View File

@ -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)
}
}

17
gradle.properties Normal file
View File

@ -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

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -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

160
gradlew vendored Executable file
View File

@ -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 "$@"

90
gradlew.bat vendored Normal file
View File

@ -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

1
presentation/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

1
presentation/.hgignore Normal file
View File

@ -0,0 +1 @@
/build

110
presentation/build.gradle Normal file
View File

@ -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
}

17
presentation/proguard-rules.pro vendored Normal file
View File

@ -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 *;
#}

View File

@ -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>(LoginActivity::class.java){
}

View File

@ -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>(LoginFragment::class.java, R.layout.fragment_login) {
@Rule @JvmField
public var mFragmentTestRule: FragmentTestRule<LoginFragment> = 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()))
}
}

View File

@ -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<T : Activity>(clazz: Class<T>) {
@Rule @JvmField
val testRule: ActivityTestRule<T> = IntentsTestRule(clazz)
val checkThat: Matchers = Matchers()
val events: Events = Events()
}

View File

@ -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())
}
}

View File

@ -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<F: BaseFragment> : ActivityTestRule<TestActivity> {
private var mFragmentClass: Class<F>
private var mFragment: F? = null
private val layout: Int
constructor(fragmentClass: Class<F>, 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
}
}

View File

@ -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 <T : Activity> nextOpenActivityIs(clazz: Class<T>) {
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)))
}
}

View File

@ -0,0 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="es.verdnatura.almacen">
<application>
<activity android:name=".TestActivity"/>
</application>
</manifest>

View File

@ -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)
}
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="es.verdnatura.almacen">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:name=".AndroidApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".view.activity.LoginActivity"
android:theme="@style/ThemeVerdnaturaWhitoutActionBar.">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".view.activity.MenuActivity" android:label="@string/app_name"/>
<activity android:name=".view.activity.TicketActivity"></activity>
<activity android:name=".view.activity.ScanActivity"></activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -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)
}
}*/
}

View File

@ -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<KeyValue>, 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)
}
}

View File

@ -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<MenuItem>, 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)
}

View File

@ -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<TicketDetail>, 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))
}
}
}

View File

@ -0,0 +1,8 @@
package es.verdnatura.almacen.di
/**
* Created by nelo on 21/2/17.
*/
interface HasComponent<C> {
fun getSubComponent(): C
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)

View File

@ -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*/
}

View File

@ -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)
}*/
}

View File

@ -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))
}
}

View File

@ -0,0 +1,10 @@
package es.verdnatura.almacen.navigation
/**
* Created by nelo on 27/4/17.
*/
interface UserNavigator {
fun navigate()
}

View File

@ -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<Int>() {
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)
}
}*/

View File

@ -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<Ticket>(){
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)
}
}

View File

@ -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)
}

View File

@ -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<Int>(){
override fun onComplete() {
super.onComplete()
lp.manageLoginSucces()
}
override fun onError(exception: Throwable) {
super.onError(exception)
lp.manageLoginError(exception.message!!)
lp.hideViewLoading()
}
}
}

View File

@ -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()
}

View File

@ -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())
}
}

View File

@ -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<Int>() {
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)
}
}
}

View File

@ -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)
}
}

View File

@ -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<LoginComponent>, 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)
}
}

View File

@ -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<MenuAdapter.MenuItem>{
var items = ArrayList<MenuAdapter.MenuItem>()
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
}
}

View File

@ -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()
}
}

View File

@ -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<TicketComponent>, 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))
}
}

View File

@ -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<TicketComponent>).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())
}

View File

@ -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()
}
}

View File

@ -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 <C> getComponent(componentType: Class<C>): C {
return componentType.cast((activity as HasComponent<C>).getSubComponent())
}
}

View File

@ -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()
}
}

View File

@ -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()!!)
}

View File

@ -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<KeyValue> {
var items = ArrayList<KeyValue>()
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)
}
}

View File

@ -0,0 +1,6 @@
package es.verdnatura.almacen.view.view
/**
* Created by nelo on 8/3/17.
*/
interface BaseView

View File

@ -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)
}

Some files were not shown because too many files have changed in this diff Show More