diff --git a/app/src/main/java/com/rockthevote/grommet/data/api/RegistrationService.java b/app/src/main/java/com/rockthevote/grommet/data/api/RegistrationService.java
index 44c1b3ae..39a3c4a6 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/api/RegistrationService.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/api/RegistrationService.java
@@ -19,6 +19,7 @@
import com.rockthevote.grommet.data.api.model.ApiContactMethod;
import com.rockthevote.grommet.data.api.model.ApiGeoLocation;
import com.rockthevote.grommet.data.api.model.ApiName;
+import com.rockthevote.grommet.data.api.model.ApiRegistrationHelper;
import com.rockthevote.grommet.data.api.model.ApiRockyRequest;
import com.rockthevote.grommet.data.api.model.ApiRockyRequestWrapper;
import com.rockthevote.grommet.data.api.model.ApiSignature;
@@ -49,15 +50,20 @@
import rx.schedulers.Schedulers;
import timber.log.Timber;
+import static com.rockthevote.grommet.data.db.model.Address.Type.ASSISTANT_ADDRESS;
import static com.rockthevote.grommet.data.db.model.Address.Type.MAILING_ADDRESS;
import static com.rockthevote.grommet.data.db.model.Address.Type.PREVIOUS_ADDRESS;
import static com.rockthevote.grommet.data.db.model.Address.Type.REGISTRATION_ADDRESS;
+import static com.rockthevote.grommet.data.db.model.ContactMethod.Type.ASSISTANT_PHONE;
+import static com.rockthevote.grommet.data.db.model.Name.Type.ASSISTANT_NAME;
+import static com.rockthevote.grommet.data.db.model.Name.Type.CURRENT_NAME;
+import static com.rockthevote.grommet.data.db.model.Name.Type.PREVIOUS_NAME;
import static com.rockthevote.grommet.data.db.model.RockyRequest.GENERATED_DATE;
import static com.rockthevote.grommet.data.db.model.RockyRequest.STATUS;
import static com.rockthevote.grommet.data.db.model.RockyRequest.Status.ABANDONED;
import static com.rockthevote.grommet.data.db.model.RockyRequest.Status.FORM_COMPLETE;
import static com.rockthevote.grommet.data.db.model.RockyRequest.Status.IN_PROGRESS;
-import static com.rockthevote.grommet.data.db.model.RockyRequest.Status.REGISTER_FAILURE;
+import static com.rockthevote.grommet.data.db.model.RockyRequest.Status.REGISTER_SERVER_FAILURE;
import static com.rockthevote.grommet.data.db.model.RockyRequest.Status.REGISTER_SUCCESS;
import static java.util.Map.Entry;
@@ -148,7 +154,7 @@ private void doWork(final RockyRequest rockyRequest) {
.subscribe(regResponse -> {
RockyRequest.Status status =
!regResponse.isError() && regResponse.response().isSuccessful()
- ? REGISTER_SUCCESS : REGISTER_FAILURE;
+ ? REGISTER_SUCCESS : REGISTER_SERVER_FAILURE;
UploadNotification.notify(getApplicationContext(), status);
@@ -164,7 +170,7 @@ private void doWork(final RockyRequest rockyRequest) {
/**
* check for
* {@link RockyRequest.Status#ABANDONED},
- * {@link RockyRequest.Status#REGISTER_FAILURE},
+ * {@link RockyRequest.Status#REGISTER_SERVER_FAILURE},
* {@link RockyRequest.Status#REGISTER_SUCCESS}
* as well as {@link RockyRequest.Status#IN_PROGRESS} that are more than one hour old
* rows and delete them
@@ -174,7 +180,7 @@ private void cleanup() {
String completedRows = ""
+ STATUS + " IN ("
+ "'" + ABANDONED + "', "
- + "'" + REGISTER_FAILURE + "',"
+ + "'" + REGISTER_SERVER_FAILURE + "',"
+ "'" + REGISTER_SUCCESS + "'"
+ ")";
@@ -255,7 +261,7 @@ public , Object> Observable> toEnumMap(
* @param additionalInfo
* @return {@link ApiRockyRequestWrapper} object
*/
- @SuppressWarnings("Convert2streamapi")
+ @SuppressWarnings({"Convert2streamapi", "ArraysAsListWithZeroOrOneArgument"})
private ApiRockyRequestWrapper zipRockyRequest(RockyRequest rockyRequest,
EnumMap addresses,
EnumMap contactMethods,
@@ -265,47 +271,74 @@ private ApiRockyRequestWrapper zipRockyRequest(RockyRequest rockyRequest,
EnumMap additionalInfo) {
- ApiAddress apiRegAddress = ApiAddress.fromDb(addresses.get(REGISTRATION_ADDRESS));
+ // Get address info objects
+ ApiAddress apiRegAddress = ApiAddress.fromAddress(addresses.get(REGISTRATION_ADDRESS));
ApiAddress apiMailAddress = rockyRequest.hasMailingAddress() ?
- ApiAddress.fromDb(addresses.get(MAILING_ADDRESS)) : null;
+ ApiAddress.fromAddress(addresses.get(MAILING_ADDRESS)) : null;
ApiAddress apiPrevAddress = rockyRequest.hasPreviousAddress() ?
- ApiAddress.fromDb(addresses.get(PREVIOUS_ADDRESS)) : null;
+ ApiAddress.fromAddress(addresses.get(PREVIOUS_ADDRESS)) : null;
- ApiName apiName = ApiName.fromDb(names.get(Name.Type.CURRENT_NAME));
+ // Get name info objects
+ ApiName apiName = ApiName.fromName(names.get(CURRENT_NAME));
ApiName apiPrevName = rockyRequest.hasPreviousName() ?
- ApiName.fromDb(names.get(Name.Type.PREVIOUS_NAME)) : null;
-
- List apiContactMethods = new ArrayList<>(contactMethods.size());
+ ApiName.fromName(names.get(PREVIOUS_NAME)) : null;
+ // Get registrant contact info objects
+ List apiContactMethods = new ArrayList<>();
for (Entry entry : contactMethods.entrySet()) {
- apiContactMethods.add(ApiContactMethod.fromDb(entry.getValue(), rockyRequest.phoneType()));
+ if (ASSISTANT_PHONE != entry.getKey()) {
+ apiContactMethods.add(ApiContactMethod.fromContactMethod(
+ entry.getValue(), rockyRequest.phoneType()));
+ }
}
+ // Get voter classification objects
List apiClassifications = new ArrayList<>();
for (Entry entry : classifications.entrySet()) {
- apiClassifications.add(ApiVoterClassification.fromDb(entry.getValue()));
+ apiClassifications.add(ApiVoterClassification.fromVoterClassification(entry.getValue()));
}
+ // Get voter ID objects
List apiVoterIds = new ArrayList<>();
for (Entry entry : voterIds.entrySet()) {
- apiVoterIds.add(ApiVoterId.fromDb(entry.getValue()));
+ apiVoterIds.add(ApiVoterId.fromVoterId(entry.getValue()));
}
+ // get additional info objects
List apiAdditionalInfo = new ArrayList<>();
for (Entry entry : additionalInfo.entrySet()) {
- apiAdditionalInfo.add(ApiAdditionalInfo.fromDb(entry.getValue()));
+ apiAdditionalInfo.add(ApiAdditionalInfo.fromAdditionalInfo(entry.getValue()));
}
ApiSignature apiSignature = ApiSignature.fromDb(rockyRequest);
ApiGeoLocation apiGeoLocation = ApiGeoLocation.fromDb(rockyRequest);
+ // build voter registration helper object
+ List helperContactMethods = new ArrayList<>();
+ for (Entry entry : contactMethods.entrySet()) {
+ if (ASSISTANT_PHONE == entry.getKey()) {
+ helperContactMethods.add(ApiContactMethod.fromContactMethod(
+ entry.getValue(), rockyRequest.phoneType()));
+ }
+ }
+
+ ApiRegistrationHelper helper = !rockyRequest.hasAssistant() ? null :
+ ApiRegistrationHelper.builder()
+ .address(ApiAddress.fromAddress(addresses.get(ASSISTANT_ADDRESS)))
+ .name(ApiName.fromName(names.get(ASSISTANT_NAME)))
+ .contactMethods(helperContactMethods)
+ .build();
+
+ // build voter registration api object
ApiVoterRegistration apiVoterRegistration = ApiVoterRegistration.fromDb(rockyRequest,
apiMailAddress, apiPrevAddress, apiRegAddress, apiName, apiPrevName, apiClassifications,
- apiSignature, apiVoterIds, apiContactMethods, apiAdditionalInfo);
+ apiSignature, apiVoterIds, apiContactMethods, apiAdditionalInfo, helper);
+ // build voter records request api object
ApiVoterRecordsRequest apiVoterRecordsRequest = ApiVoterRecordsRequest.fromDb(rockyRequest,
apiVoterRegistration);
+ // build rocky request api object
ApiRockyRequest apiRockyRequest = ApiRockyRequest.fromDb(rockyRequest,
apiVoterRecordsRequest, apiGeoLocation);
diff --git a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiAdditionalInfo.java b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiAdditionalInfo.java
index 87a1130c..4a4c5e0a 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiAdditionalInfo.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiAdditionalInfo.java
@@ -34,7 +34,7 @@ abstract static class Builder {
}
@Nullable
- public static ApiAdditionalInfo fromDb(AdditionalInfo additionalInfo) {
+ public static ApiAdditionalInfo fromAdditionalInfo(AdditionalInfo additionalInfo) {
if (null == additionalInfo) {
return null;
}
diff --git a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiAddress.java b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiAddress.java
index 98885c1b..fc28ed31 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiAddress.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiAddress.java
@@ -168,7 +168,7 @@ public void toJson(JsonWriter writer, ApiAddress value) throws IOException {
}
@Nullable
- public static ApiAddress fromDb(Address address) {
+ public static ApiAddress fromAddress(Address address) {
if(null == address){
return null;
}
diff --git a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiContactMethod.java b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiContactMethod.java
index 0076dded..a0adf587 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiContactMethod.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiContactMethod.java
@@ -37,14 +37,15 @@ abstract static class Builder{
}
@Nullable
- public static ApiContactMethod fromDb(ContactMethod contactMethod, PhoneType phoneType){
+ public static ApiContactMethod fromContactMethod(ContactMethod contactMethod, PhoneType phoneType) {
if (null == contactMethod) {
return null;
}
List capabilities = new ArrayList<>();
// right now we only support phone (no fax)
- if(contactMethod.type() == ContactMethod.Type.PHONE){
+ if (contactMethod.type() == ContactMethod.Type.PHONE ||
+ contactMethod.type() == ContactMethod.Type.ASSISTANT_PHONE) {
capabilities.add(ContactMethod.Capability.VOICE.toString());
if(phoneType == PhoneType.MOBILE){
capabilities.add(ContactMethod.Capability.SMS.toString());
diff --git a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiName.java b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiName.java
index 1ad83deb..1b2d6870 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiName.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiName.java
@@ -49,7 +49,7 @@ abstract static class Builder {
}
@Nullable
- public static ApiName fromDb(Name name) {
+ public static ApiName fromName(Name name) {
if (null == name) {
return null;
}
diff --git a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiRegistrationHelper.java b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiRegistrationHelper.java
new file mode 100644
index 00000000..01638731
--- /dev/null
+++ b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiRegistrationHelper.java
@@ -0,0 +1,46 @@
+package com.rockthevote.grommet.data.api.model;
+
+import com.google.auto.value.AutoValue;
+import com.squareup.moshi.Json;
+import com.squareup.moshi.JsonAdapter;
+import com.squareup.moshi.Moshi;
+
+import java.util.List;
+
+@AutoValue
+public abstract class ApiRegistrationHelper {
+
+ @Json(name = "registration_helper_type")
+ public abstract String type();
+
+ public abstract ApiName name();
+
+ public abstract ApiAddress address();
+
+ @Json(name = "contact_methods")
+ abstract List contactMethods();
+
+
+ public static JsonAdapter jsonAdapter(Moshi moshi) {
+ return new AutoValue_ApiRegistrationHelper.MoshiJsonAdapter(moshi);
+ }
+
+ public static Builder builder() {
+ return new AutoValue_ApiRegistrationHelper.Builder()
+ .type("assistant");
+ }
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+
+ public abstract Builder type(String type);
+
+ public abstract Builder name(ApiName name);
+
+ public abstract Builder address(ApiAddress address);
+
+ public abstract Builder contactMethods(List contactMethods);
+
+ public abstract ApiRegistrationHelper build();
+ }
+}
diff --git a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterClassification.java b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterClassification.java
index e9179a35..04985909 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterClassification.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterClassification.java
@@ -30,7 +30,7 @@ abstract static class Builder {
abstract ApiVoterClassification build();
}
- public static ApiVoterClassification fromDb(VoterClassification classification) {
+ public static ApiVoterClassification fromVoterClassification(VoterClassification classification) {
return builder()
.type(classification.type().toString())
.assertion(classification.assertion())
diff --git a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterId.java b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterId.java
index c3aececc..0b67845b 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterId.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterId.java
@@ -36,7 +36,7 @@ abstract static class Builder {
abstract ApiVoterId build();
}
- public static ApiVoterId fromDb(VoterId voterId) {
+ public static ApiVoterId fromVoterId(VoterId voterId) {
return builder()
.type(voterId.type().toString())
.stringValue(voterId.value())
diff --git a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterRegistration.java b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterRegistration.java
index 34585e6c..c4993c82 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterRegistration.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/api/model/ApiVoterRegistration.java
@@ -18,6 +18,10 @@
@AutoValue
public abstract class ApiVoterRegistration {
+ @Json(name = "registration_helper")
+ @Nullable
+ abstract ApiRegistrationHelper registrationHelper();
+
@Json(name = "date_of_birth")
abstract String dateOfBirth();
@@ -61,6 +65,7 @@ public abstract class ApiVoterRegistration {
@Json(name = "additional_info")
abstract List additionalInfo();
+
public static JsonAdapter jsonAdapter(Moshi moshi) {
return new AutoValue_ApiVoterRegistration.MoshiJsonAdapter(moshi);
}
@@ -71,6 +76,8 @@ static Builder builder() {
@AutoValue.Builder
abstract static class Builder {
+ abstract Builder registrationHelper(ApiRegistrationHelper registrationHelper);
+
abstract Builder dateOfBirth(String value);
abstract Builder mailingAddress(ApiAddress value);
@@ -114,7 +121,8 @@ public static ApiVoterRegistration fromDb(RockyRequest rockyRequest,
ApiSignature signature,
List voterIds,
List contactMethods,
- List additionalInfo) {
+ List additionalInfo,
+ ApiRegistrationHelper registrationHelper) {
return builder()
.dateOfBirth(Dates.formatAsISO8601_ShortDate(rockyRequest.dateOfBirth()))
.mailingAddress(mailingAddress)
@@ -131,6 +139,7 @@ public static ApiVoterRegistration fromDb(RockyRequest rockyRequest,
.voterIds(voterIds)
.contactMethods(contactMethods)
.additionalInfo(additionalInfo)
+ .registrationHelper(registrationHelper)
.build();
}
}
diff --git a/app/src/main/java/com/rockthevote/grommet/data/db/DbOpenHelper.java b/app/src/main/java/com/rockthevote/grommet/data/db/DbOpenHelper.java
index 71fb22cf..b5345d22 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/db/DbOpenHelper.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/db/DbOpenHelper.java
@@ -44,7 +44,8 @@ public class DbOpenHelper extends SQLiteOpenHelper {
+ RockyRequest.LATITUDE + " REAL,"
+ RockyRequest.LONGITUDE + " REAL,"
+ RockyRequest.HAS_PREVIOUS_NAME + " INTEGER DEFAULT " + Db.BOOLEAN_FALSE + ","
- + RockyRequest.HAS_PREVIOUS_ADDRESS + " INTEGER DEFAULT " + Db.BOOLEAN_FALSE
+ + RockyRequest.HAS_PREVIOUS_ADDRESS + " INTEGER DEFAULT " + Db.BOOLEAN_FALSE + ","
+ + RockyRequest.HAS_ASSISTANT + " INTEGER DEFAULT " + Db.BOOLEAN_FALSE
+ ")";
private static final String CREATE_ADDRESS = ""
diff --git a/app/src/main/java/com/rockthevote/grommet/data/db/model/RockyRequest.java b/app/src/main/java/com/rockthevote/grommet/data/db/model/RockyRequest.java
index e4b103c8..5a5bdd32 100644
--- a/app/src/main/java/com/rockthevote/grommet/data/db/model/RockyRequest.java
+++ b/app/src/main/java/com/rockthevote/grommet/data/db/model/RockyRequest.java
@@ -41,6 +41,7 @@ public abstract class RockyRequest implements Parcelable, BaseColumns {
public static final String LONGITUDE = "longitude";
public static final String HAS_PREVIOUS_NAME = "has_previous_name";
public static final String HAS_PREVIOUS_ADDRESS = "has_previous_address";
+ public static final String HAS_ASSISTANT = "has_assistant";
public static final String SELECT_BY_ID = ""
+ "SELECT * FROM "
@@ -107,6 +108,8 @@ public abstract class RockyRequest implements Parcelable, BaseColumns {
public abstract boolean hasPreviousAddress();
+ public abstract boolean hasAssistant();
+
public static final Func1 MAPPER = cursor -> {
long id = Db.getLong(cursor, _ID);
Status status = Status.fromString(Db.getString(cursor, STATUS));
@@ -131,12 +134,13 @@ public abstract class RockyRequest implements Parcelable, BaseColumns {
long longitude = Db.getLong(cursor, LONGITUDE);
boolean hasPreviousName = Db.getBoolean(cursor, HAS_PREVIOUS_NAME);
boolean hasPreviousAddress = Db.getBoolean(cursor, HAS_PREVIOUS_ADDRESS);
+ boolean hasAssistant = Db.getBoolean(cursor, HAS_ASSISTANT);
return new AutoValue_RockyRequest(id, status, language, phoneType, partnerId, optInEmail, optInSMS,
optInVolunteer, partnerOptInSMS, partnerOptInEmail,
sourceTrackingId, partnerTrackingId, openTrackingId,
generatedDate, dateOfBirth, hasMailingAddress, race, party, signature,
- latitude, longitude, hasPreviousName, hasPreviousAddress);
+ latitude, longitude, hasPreviousName, hasPreviousAddress, hasAssistant);
};
public static final class Builder {
@@ -262,6 +266,11 @@ public Builder hasPreviousAddress(boolean hasPreviousAddress) {
return this;
}
+ public Builder hasAssistant(boolean hasAssistant) {
+ values.put(HAS_ASSISTANT, hasAssistant);
+ return this;
+ }
+
public ContentValues build() {
return values;
}
@@ -333,7 +342,8 @@ public enum Status {
ABANDONED("abandoned"),
FORM_COMPLETE("form_complete"),
REGISTER_SUCCESS("register_success"),
- REGISTER_FAILURE("register_failure");
+ REGISTER_SERVER_FAILURE("register_server_failure"),
+ REGISTER_CLIENT_FAILURE("register_client_failure");
private final String status;
diff --git a/app/src/main/java/com/rockthevote/grommet/ui/UploadNotification.java b/app/src/main/java/com/rockthevote/grommet/ui/UploadNotification.java
index bd0d662e..c4bb6156 100644
--- a/app/src/main/java/com/rockthevote/grommet/ui/UploadNotification.java
+++ b/app/src/main/java/com/rockthevote/grommet/ui/UploadNotification.java
@@ -72,7 +72,7 @@ int getNotifTitle(RockyRequest.Status status) {
case REGISTER_SUCCESS:
return R.string.upload_notification_title_success;
default:
- case REGISTER_FAILURE:
+ case REGISTER_SERVER_FAILURE:
return R.string.upload_notification_title_failure;
}
}
@@ -82,7 +82,7 @@ private static int getNotificationId(RockyRequest.Status status) {
case REGISTER_SUCCESS:
return NOTIFICATION_SUCCESS_ID;
default:
- case REGISTER_FAILURE:
+ case REGISTER_SERVER_FAILURE:
return NOTIFICATION_FAILURE_ID;
}
}
@@ -92,7 +92,7 @@ private static String getNotificationTag(RockyRequest.Status status) {
case REGISTER_SUCCESS:
return NOTIFICATION_SUCCESS_TAG;
default:
- case REGISTER_FAILURE:
+ case REGISTER_SERVER_FAILURE:
return NOTIFICATION_FAILURE_TAG;
}
}
diff --git a/app/src/main/java/com/rockthevote/grommet/ui/registration/AdditionalInfoFragment.java b/app/src/main/java/com/rockthevote/grommet/ui/registration/AdditionalInfoFragment.java
index d1aaeaed..2b7dc95f 100644
--- a/app/src/main/java/com/rockthevote/grommet/ui/registration/AdditionalInfoFragment.java
+++ b/app/src/main/java/com/rockthevote/grommet/ui/registration/AdditionalInfoFragment.java
@@ -1,7 +1,5 @@
package com.rockthevote.grommet.ui.registration;
-import android.app.Activity;
-import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
@@ -98,7 +96,7 @@ public class AdditionalInfoFragment extends BaseRegistrationFragment {
@Inject BriteDatabase db;
private ObservableValidator validator;
- private CompositeSubscription subscriptions;
+ private CompositeSubscription subscriptions = new CompositeSubscription();
private EnumAdapter raceEnumAdapter;
private EnumAdapter partyEnumAdapter;
@@ -161,7 +159,6 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
@Override
public void onResume() {
super.onResume();
- subscriptions = new CompositeSubscription();
phoneFormatter = new PhoneNumberFormattingTextWatcher();
phone.addTextChangedListener(phoneFormatter);
diff --git a/app/src/main/java/com/rockthevote/grommet/ui/registration/AssistantInfoFragment.java b/app/src/main/java/com/rockthevote/grommet/ui/registration/AssistantInfoFragment.java
index aa884d4b..4bcf9cb5 100644
--- a/app/src/main/java/com/rockthevote/grommet/ui/registration/AssistantInfoFragment.java
+++ b/app/src/main/java/com/rockthevote/grommet/ui/registration/AssistantInfoFragment.java
@@ -2,25 +2,70 @@
import android.os.Bundle;
import android.support.annotation.Nullable;
+import android.support.design.widget.TextInputLayout;
+import android.telephony.PhoneNumberFormattingTextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.EditText;
import com.f2prateek.rx.preferences.Preference;
+import com.jakewharton.rxbinding.widget.RxTextView;
+import com.mobsandgeeks.saripaar.Validator;
+import com.mobsandgeeks.saripaar.annotation.Checked;
import com.rockthevote.grommet.R;
+import com.rockthevote.grommet.data.db.model.ContactMethod;
+import com.rockthevote.grommet.data.db.model.RockyRequest;
import com.rockthevote.grommet.data.prefs.CurrentRockyRequestId;
+import com.rockthevote.grommet.ui.misc.ObservableValidator;
+import com.rockthevote.grommet.ui.views.AddressView;
+import com.rockthevote.grommet.ui.views.NameView;
+import com.rockthevote.grommet.util.PhoneOrEmpty;
import com.squareup.sqlbrite.BriteDatabase;
+import java.util.concurrent.TimeUnit;
+
import javax.inject.Inject;
+import butterknife.BindView;
import butterknife.ButterKnife;
+import butterknife.OnCheckedChanged;
+import rx.Observable;
+import rx.schedulers.Schedulers;
+import rx.subscriptions.CompositeSubscription;
+
+import static com.rockthevote.grommet.data.db.Db.DEBOUNCE;
+import static com.rockthevote.grommet.data.db.model.ContactMethod.Type.ASSISTANT_PHONE;
public class AssistantInfoFragment extends BaseRegistrationFragment {
+ @BindView(R.id.assistant_fields) View assistantFields;
+
+ @BindView(R.id.assistant_name) NameView nameView;
+
+ @BindView(R.id.assistant_address) AddressView addressView;
+
+ @PhoneOrEmpty(messageResId = R.string.phone_format_error)
+ @BindView(R.id.til_assistant_phone) TextInputLayout phoneTIL;
+
+ @BindView(R.id.assistant_phone) EditText phoneEditText;
+
+ @BindView(R.id.checkbox_has_assistant) CheckBox hasAssistant;
+
+ @Checked
+ @BindView(R.id.checkbox_assistant_affirmation) CheckBox assistantAffirmation;
+
@Inject @CurrentRockyRequestId Preference rockyRequestRowId;
@Inject BriteDatabase db;
+ private ObservableValidator validator;
+
+ private PhoneNumberFormattingTextWatcher phoneFormatter;
+
+ private CompositeSubscription subscriptions = new CompositeSubscription();
+
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -32,5 +77,59 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
+
+ Validator.registerAnnotation(PhoneOrEmpty.class);
+ validator = new ObservableValidator(this, getActivity());
+
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ phoneFormatter = new PhoneNumberFormattingTextWatcher();
+ phoneEditText.addTextChangedListener(phoneFormatter);
+
+ subscriptions.add(RxTextView.afterTextChangeEvents(phoneEditText)
+ .observeOn(Schedulers.io())
+ .debounce(DEBOUNCE, TimeUnit.MILLISECONDS)
+ .skip(1)
+ .subscribe(event -> {
+ ContactMethod.insertOrUpdate(db, rockyRequestRowId.get(), ASSISTANT_PHONE,
+ new ContactMethod.Builder()
+ .value(event.editable().toString())
+ .build()
+ );
+ }));
+
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ phoneEditText.removeTextChangedListener(phoneFormatter);
+ subscriptions.unsubscribe();
+ }
+
+ @OnCheckedChanged(R.id.checkbox_has_assistant)
+ public void onHasAssistantChecked(boolean checked) {
+ assistantFields.setVisibility(checked ? View.VISIBLE : View.GONE);
+
+ db.update(RockyRequest.TABLE,
+ new RockyRequest.Builder()
+ .hasAssistant(checked)
+ .build(),
+ RockyRequest._ID + " = ? ", String.valueOf(rockyRequestRowId.get()));
+
+ }
+
+ @Override
+ public Observable verify() {
+
+ if (!hasAssistant.isChecked()) {
+ return super.verify();
+ }
+
+ return Observable.zip(nameView.verify(), addressView.verify(), validator.validate(),
+ (name, address, other) -> name && address && other);
}
}
diff --git a/app/src/main/java/com/rockthevote/grommet/ui/registration/RegistrationPagerAdapter.java b/app/src/main/java/com/rockthevote/grommet/ui/registration/RegistrationPagerAdapter.java
index 3bb682ca..8934bbd7 100644
--- a/app/src/main/java/com/rockthevote/grommet/ui/registration/RegistrationPagerAdapter.java
+++ b/app/src/main/java/com/rockthevote/grommet/ui/registration/RegistrationPagerAdapter.java
@@ -20,8 +20,8 @@ public RegistrationPagerAdapter(FragmentManager fm, Context context) {
titles.put(0, context.getString(R.string.fragment_title_new_registrant));
titles.put(1, context.getString(R.string.fragment_title_personal_info));
titles.put(2, context.getString(R.string.fragment_title_additional_info));
-// titles.put(3, context.getString(R.string.fragment_title_assistant_info));
- titles.put(3, context.getString(R.string.fragment_title_review));
+ titles.put(3, context.getString(R.string.fragment_title_assistant_info));
+ titles.put(4, context.getString(R.string.fragment_title_review));
}
@Override
@@ -37,9 +37,9 @@ private Fragment getNewFragment(int position) {
return new PersonalInfoFragment();
case 2:
return new AdditionalInfoFragment();
-// case 3:
-// return new AssistantInfoFragment();
case 3:
+ return new AssistantInfoFragment();
+ case 4:
return new ReviewAndConfirmFragment();
default:
throw new IllegalStateException("Unknown fragment position: " + position);
@@ -55,7 +55,7 @@ public Object instantiateItem(ViewGroup container, int position) {
@Override
public int getCount() {
- return 4;
+ return 5;
}
@Override
diff --git a/app/src/main/java/com/rockthevote/grommet/ui/views/AddressView.java b/app/src/main/java/com/rockthevote/grommet/ui/views/AddressView.java
index 7423fd25..4b1a6fac 100644
--- a/app/src/main/java/com/rockthevote/grommet/ui/views/AddressView.java
+++ b/app/src/main/java/com/rockthevote/grommet/ui/views/AddressView.java
@@ -122,83 +122,84 @@ public AddressView(Context context, AttributeSet attrs, int defStyleAttr) {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- ButterKnife.bind(this);
- validator = new ObservableValidator(this, getContext());
-
- switch (type) {
- case REGISTRATION_ADDRESS:
- sectionTitle.setText(R.string.section_label_registration_address);
- break;
- case MAILING_ADDRESS:
- sectionTitle.setText(R.string.section_label_mailing_address);
- break;
- case PREVIOUS_ADDRESS:
- sectionTitle.setText(R.string.section_label_previous_address);
- break;
- case ASSISTANT_ADDRESS:
- sectionTitle.setText(R.string.section_label_registration_address);
- }
-
- countyAdapter = ArrayAdapter.createFromResource(getContext(),
- R.array.pa_counties, android.R.layout.simple_list_item_1);
- countyAdapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
-
- countySpinner.setAdapter(countyAdapter);
- countySpinner.setHeight((int) getResources().getDimension(R.dimen.list_pop_up_max_height));
- countySpinner.setOnItemClickListener((adapterView, view, i, l) -> {
- countySpinner.getEditText().setText(countyAdapter.getItem(i));
- countySpinner.dismiss();
- });
-
- stateAdapter = ArrayAdapter.createFromResource(getContext(),
- R.array.states, android.R.layout.simple_list_item_1);
- stateAdapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
-
- stateSpinner.setAdapter(stateAdapter);
- stateSpinner.setHeight((int) getResources().getDimension(R.dimen.list_pop_up_max_height));
- stateSpinner.setOnItemClickListener((adapterView, view, i, l) -> {
- stateSpinner.getEditText().setText(stateAdapter.getItem(i));
-
- if(!PA_ABREV.equals(stateAdapter.getItem(i))){
- countySpinner.setErrorEnabled(false);
- countySpinner.setEnabled(false);
- countySpinner.getEditText().setText("");
- countySpinner.getEditText().setEnabled(false);
- } else {
- countySpinner.getEditText().setEnabled(true);
- countySpinner.setEnabled(true);
+ if (!isInEditMode()) {
+ ButterKnife.bind(this);
+ validator = new ObservableValidator(this, getContext());
+
+ switch (type) {
+ case REGISTRATION_ADDRESS:
+ sectionTitle.setText(R.string.section_label_registration_address);
+ break;
+ case MAILING_ADDRESS:
+ sectionTitle.setText(R.string.section_label_mailing_address);
+ break;
+ case PREVIOUS_ADDRESS:
+ sectionTitle.setText(R.string.section_label_previous_address);
+ break;
+ case ASSISTANT_ADDRESS:
+ sectionTitle.setText(R.string.section_label_registration_address);
}
- stateSpinner.dismiss();
- });
- stateSpinner.getEditText().setText(stateAdapter.getItem(stateAdapter.getPosition(PA_ABREV)));
+ countyAdapter = ArrayAdapter.createFromResource(getContext(),
+ R.array.pa_counties, android.R.layout.simple_list_item_1);
+ countyAdapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
+
+ countySpinner.setAdapter(countyAdapter);
+ countySpinner.setHeight((int) getResources().getDimension(R.dimen.list_pop_up_max_height));
+ countySpinner.setOnItemClickListener((adapterView, view, i, l) -> {
+ countySpinner.getEditText().setText(countyAdapter.getItem(i));
+ countySpinner.dismiss();
+ });
+
+ stateAdapter = ArrayAdapter.createFromResource(getContext(),
+ R.array.states, android.R.layout.simple_list_item_1);
+ stateAdapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
+
+ stateSpinner.setAdapter(stateAdapter);
+ stateSpinner.setHeight((int) getResources().getDimension(R.dimen.list_pop_up_max_height));
+ stateSpinner.setOnItemClickListener((adapterView, view, i, l) -> {
+ stateSpinner.getEditText().setText(stateAdapter.getItem(i));
+
+ if (!PA_ABREV.equals(stateAdapter.getItem(i))) {
+ countySpinner.setErrorEnabled(false);
+ countySpinner.setEnabled(false);
+ countySpinner.getEditText().setText("");
+ countySpinner.getEditText().setEnabled(false);
+ } else {
+ countySpinner.getEditText().setEnabled(true);
+ countySpinner.setEnabled(true);
+ }
+ stateSpinner.dismiss();
+ });
+ stateSpinner.getEditText().setText(stateAdapter.getItem(stateAdapter.getPosition(PA_ABREV)));
+ }
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
-
- subscriptions.add(Observable.combineLatest(RxTextView.afterTextChangeEvents(streetEditText),
- RxTextView.afterTextChangeEvents(unitEditText),
- RxTextView.afterTextChangeEvents(cityEditText),
- RxTextView.afterTextChangeEvents(stateSpinner.getEditText()),
- RxTextView.afterTextChangeEvents(zipEditText),
- RxTextView.afterTextChangeEvents(stateSpinner.getEditText()),
- (street, unit, city, state, zip, county) -> new Address.Builder()
- .streetName(street.editable().toString())
- .subAddress(unit.editable().toString())
- .municipalJurisdiction(city.editable().toString())
- .state(state.editable().toString())
- .zip(zip.editable().toString())
- .county(county.editable().toString())
- .build())
- .observeOn(Schedulers.io())
- .debounce(DEBOUNCE, TimeUnit.MILLISECONDS)
- .subscribe(contentValues -> {
- Address.insertOrUpdate(db, rockyRequestRowId.get(), type, contentValues);
- }));
-
+ if (!isInEditMode()) {
+ subscriptions.add(Observable.combineLatest(RxTextView.afterTextChangeEvents(streetEditText),
+ RxTextView.afterTextChangeEvents(unitEditText),
+ RxTextView.afterTextChangeEvents(cityEditText),
+ RxTextView.afterTextChangeEvents(stateSpinner.getEditText()),
+ RxTextView.afterTextChangeEvents(zipEditText),
+ RxTextView.afterTextChangeEvents(stateSpinner.getEditText()),
+ (street, unit, city, state, zip, county) -> new Address.Builder()
+ .streetName(street.editable().toString())
+ .subAddress(unit.editable().toString())
+ .municipalJurisdiction(city.editable().toString())
+ .state(state.editable().toString())
+ .zip(zip.editable().toString())
+ .county(county.editable().toString())
+ .build())
+ .observeOn(Schedulers.io())
+ .debounce(DEBOUNCE, TimeUnit.MILLISECONDS)
+ .subscribe(contentValues -> {
+ Address.insertOrUpdate(db, rockyRequestRowId.get(), type, contentValues);
+ }));
+ }
}
@Override
diff --git a/app/src/main/java/com/rockthevote/grommet/ui/views/NameView.java b/app/src/main/java/com/rockthevote/grommet/ui/views/NameView.java
index fad24362..7acd9f19 100644
--- a/app/src/main/java/com/rockthevote/grommet/ui/views/NameView.java
+++ b/app/src/main/java/com/rockthevote/grommet/ui/views/NameView.java
@@ -115,59 +115,62 @@ public NameView(Context context, AttributeSet attrs, int defStyleAttr) {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- ButterKnife.bind(this);
-
- validator = new ObservableValidator(this, getContext());
-
- switch (type) {
- case CURRENT_NAME:
- sectionTitle.setText(R.string.section_label_name);
- break;
- case PREVIOUS_NAME:
- sectionTitle.setText(R.string.section_label_previous_name);
- break;
- case ASSISTANT_NAME:
- sectionTitle.setText(R.string.section_label_name);
- break;
- }
+ if (!isInEditMode()) {
+ ButterKnife.bind(this);
+
+ validator = new ObservableValidator(this, getContext());
+
+ switch (type) {
+ case CURRENT_NAME:
+ sectionTitle.setText(R.string.section_label_name);
+ break;
+ case PREVIOUS_NAME:
+ sectionTitle.setText(R.string.section_label_previous_name);
+ break;
+ case ASSISTANT_NAME:
+ sectionTitle.setText(R.string.section_label_name);
+ break;
+ }
- titleEnumAdapter = new EnumAdapter<>(getContext(), Name.Prefix.class);
- titleSpinner.setAdapter(titleEnumAdapter);
- titleSpinner.setOnItemClickListener((adapterView, view, i, l) -> {
- titleSpinner.getEditText().setText(titleEnumAdapter.getItem(i).toString());
- titleSpinner.dismiss();
- });
-
- suffixEnumAdapter = new EnumAdapter<>(getContext(), Name.Suffix.class);
- suffixSpinner.setAdapter(suffixEnumAdapter);
- suffixSpinner.setOnItemClickListener((adapterView, view, i, l) -> {
- suffixSpinner.getEditText().setText(suffixEnumAdapter.getItem(i).toString());
- suffixSpinner.dismiss();
- });
+ titleEnumAdapter = new EnumAdapter<>(getContext(), Name.Prefix.class);
+ titleSpinner.setAdapter(titleEnumAdapter);
+ titleSpinner.setOnItemClickListener((adapterView, view, i, l) -> {
+ titleSpinner.getEditText().setText(titleEnumAdapter.getItem(i).toString());
+ titleSpinner.dismiss();
+ });
+
+ suffixEnumAdapter = new EnumAdapter<>(getContext(), Name.Suffix.class);
+ suffixSpinner.setAdapter(suffixEnumAdapter);
+ suffixSpinner.setOnItemClickListener((adapterView, view, i, l) -> {
+ suffixSpinner.getEditText().setText(suffixEnumAdapter.getItem(i).toString());
+ suffixSpinner.dismiss();
+ });
+ }
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
-
- subscriptions.add(Observable.combineLatest(RxTextView.afterTextChangeEvents(firstNameEditText),
- RxTextView.afterTextChangeEvents(middleNameEditText),
- RxTextView.afterTextChangeEvents(lastNameEditText),
- RxTextView.afterTextChangeEvents(titleSpinner.getEditText()),
- RxTextView.afterTextChangeEvents(suffixSpinner.getEditText()),
- (firstName, middleName, lastName, title, suffix) -> new Name.Builder()
- .firstName(firstName.editable().toString())
- .middleName(middleName.editable().toString())
- .lastName(lastName.editable().toString())
- .prefix(Prefix.fromString(title.editable().toString()))
- .suffix(Suffix.fromString(suffix.editable().toString()))
- .build())
- .observeOn(Schedulers.io())
- .debounce(DEBOUNCE, TimeUnit.MILLISECONDS)
- .skip(1)
- .subscribe(contentValues -> {
- Name.insertOrUpdate(db, rockyRequestRowId.get(), type, contentValues);
- }));
+ if (!isInEditMode()) {
+ subscriptions.add(Observable.combineLatest(RxTextView.afterTextChangeEvents(firstNameEditText),
+ RxTextView.afterTextChangeEvents(middleNameEditText),
+ RxTextView.afterTextChangeEvents(lastNameEditText),
+ RxTextView.afterTextChangeEvents(titleSpinner.getEditText()),
+ RxTextView.afterTextChangeEvents(suffixSpinner.getEditText()),
+ (firstName, middleName, lastName, title, suffix) -> new Name.Builder()
+ .firstName(firstName.editable().toString())
+ .middleName(middleName.editable().toString())
+ .lastName(lastName.editable().toString())
+ .prefix(Prefix.fromString(title.editable().toString()))
+ .suffix(Suffix.fromString(suffix.editable().toString()))
+ .build())
+ .observeOn(Schedulers.io())
+ .debounce(DEBOUNCE, TimeUnit.MILLISECONDS)
+ .skip(1)
+ .subscribe(contentValues -> {
+ Name.insertOrUpdate(db, rockyRequestRowId.get(), type, contentValues);
+ }));
+ }
}
@Override
diff --git a/app/src/main/res/layout/fragment_assistant_info.xml b/app/src/main/res/layout/fragment_assistant_info.xml
index f54a2104..b9da992b 100644
--- a/app/src/main/res/layout/fragment_assistant_info.xml
+++ b/app/src/main/res/layout/fragment_assistant_info.xml
@@ -1,89 +1,136 @@
-
-
-
-
-
-
-
+ android:text="@string/label_has_assistant"
+ />
-
+ tools:visibility="gone"
+ >
-
+
-
+ android:layout_columnSpan="2"
+ android:layout_marginEnd="@dimen/content_margin"
+ android:layout_marginStart="@dimen/content_margin"
+ android:paddingTop="@dimen/content_area_padding"
+ android:text="@string/section_label_assistant_name"
+ android:textAppearance="@android:style/TextAppearance.Material.Subhead"/>
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5401d4f8..4f3508fc 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -106,7 +106,10 @@
Check "I do not know" if you don\'t know your PennDOT number
Check "I do not know" if you don\'t know your SSN last four
Did someone helped you with this form?
- Helper Info
+ Helper Name
+ Helper Address
+ Helper Contact Info
+ I have reviewed the above information, and it is true and accurate to the best of my knowledge.
Review
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index f526c8d7..a9e95956 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -11,7 +11,8 @@
- @color/colorPrimary
- @color/colorPrimaryDark
- @color/colorAccent
- - @android:style/Widget.Material.Spinner.Underlined
+ - @android:color/holo_red_dark
+