com.fullmeadalchemist.mustwatch.ui.batch.form.BatchFormFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.fullmeadalchemist.mustwatch.ui.batch.form.BatchFormFragment.java

Source

/*
 * Copyright (c) 2017 Full Mead Alchemist, LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.fullmeadalchemist.mustwatch.ui.batch.form;

import android.app.Activity;
import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelProviders;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;

import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.fullmeadalchemist.mustwatch.R;
import com.fullmeadalchemist.mustwatch.databinding.BatchFormFragmentBinding;
import com.fullmeadalchemist.mustwatch.di.Injectable;
import com.fullmeadalchemist.mustwatch.ui.common.BatchIngredientView;
import com.fullmeadalchemist.mustwatch.ui.common.DatePickerFragment;
import com.fullmeadalchemist.mustwatch.ui.common.NavigationController;
import com.fullmeadalchemist.mustwatch.ui.common.TimePickerFragment;
import com.fullmeadalchemist.mustwatch.vo.Batch;
import com.fullmeadalchemist.mustwatch.vo.Batch.BatchStatusEnum;
import com.fullmeadalchemist.mustwatch.vo.BatchIngredient;

import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import javax.inject.Inject;

import timber.log.Timber;

import static com.fullmeadalchemist.mustwatch.core.UnitMapper.toVolume;
import static com.fullmeadalchemist.mustwatch.core.UnitMapper.unitToStringResource;
import static com.fullmeadalchemist.mustwatch.core.UnitMapper.unitToTextAbbr;
import static com.fullmeadalchemist.mustwatch.core.ValueParsers.toDouble;
import static com.fullmeadalchemist.mustwatch.core.ValueParsers.toFloat;
import static com.fullmeadalchemist.mustwatch.ui.batch.form.AddIngredientDialog.AMOUNT;
import static com.fullmeadalchemist.mustwatch.ui.batch.form.AddIngredientDialog.INGREDIENT;
import static com.fullmeadalchemist.mustwatch.ui.batch.form.AddIngredientDialog.INGREDIENT_SET_EVENT;
import static com.fullmeadalchemist.mustwatch.ui.batch.form.AddIngredientDialog.INGREDIENT_TYPE;
import static com.fullmeadalchemist.mustwatch.ui.batch.form.AddIngredientDialog.UNIT;
import static com.fullmeadalchemist.mustwatch.ui.common.DatePickerFragment.DATE_SET_EVENT;
import static com.fullmeadalchemist.mustwatch.ui.common.DatePickerFragment.DAY_OF_MONTH;
import static com.fullmeadalchemist.mustwatch.ui.common.DatePickerFragment.MONTH;
import static com.fullmeadalchemist.mustwatch.ui.common.DatePickerFragment.YEAR;
import static com.fullmeadalchemist.mustwatch.ui.common.TimePickerFragment.HOUR;
import static com.fullmeadalchemist.mustwatch.ui.common.TimePickerFragment.MINUTE;
import static com.fullmeadalchemist.mustwatch.ui.common.TimePickerFragment.TIME_SET_EVENT;
import static com.fullmeadalchemist.mustwatch.util.FormatUtils.calendarToLocaleDate;
import static com.fullmeadalchemist.mustwatch.util.FormatUtils.calendarToLocaleTime;
import static com.fullmeadalchemist.mustwatch.vo.Batch.BATCH_ID;
import static com.fullmeadalchemist.mustwatch.vo.Batch.BatchStatusEnum.PLANNING;
import static com.fullmeadalchemist.mustwatch.vo.Ingredient.IngredientType.NUTRIENT;
import static com.fullmeadalchemist.mustwatch.vo.Ingredient.IngredientType.STABILIZER;
import static com.fullmeadalchemist.mustwatch.vo.Ingredient.IngredientType.SUGAR;
import static com.fullmeadalchemist.mustwatch.vo.Ingredient.IngredientType.YEAST;
import static com.fullmeadalchemist.mustwatch.vo.Recipe.RECIPE_ID;
import static systems.uom.common.Imperial.GALLON_UK;
import static systems.uom.common.Imperial.OUNCE_LIQUID;
import static systems.uom.common.USCustomary.FAHRENHEIT;
import static systems.uom.common.USCustomary.FLUID_OUNCE;
import static systems.uom.common.USCustomary.GALLON_DRY;
import static systems.uom.common.USCustomary.GALLON_LIQUID;
import static systems.uom.common.USCustomary.LITER;
import static systems.uom.common.USCustomary.OUNCE;
import static systems.uom.common.USCustomary.POUND;
import static systems.uom.common.USCustomary.TEASPOON;
import static tec.units.ri.unit.Units.CELSIUS;
import static tec.units.ri.unit.Units.GRAM;
import static tec.units.ri.unit.Units.KILOGRAM;

public class BatchFormFragment extends Fragment implements Injectable {

    private static final int DATE_REQUEST_CODE = 1;
    private static final int TIME_REQUEST_CODE = 2;
    private static final int INGREDIENT_REQUEST_CODE = 3;

    private Activity activity;

    @Inject
    ViewModelProvider.Factory viewModelFactory;

    @Inject
    NavigationController navigationController;
    BatchFormFragmentBinding dataBinding;
    Map<String, String> abbreviationMap = new HashMap<>();
    private MODES FORM_MODE;
    private BatchFormViewModel viewModel;
    private BroadcastReceiver timePickerMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Timber.d("Received TIME_SET_EVENT");
            Integer hourOfDay = intent.getIntExtra(HOUR, 0);
            Integer minute = intent.getIntExtra(TimePickerFragment.MINUTE, 0);
            viewModel.batch.createDate.set(Calendar.HOUR, hourOfDay);
            viewModel.batch.createDate.set(Calendar.MINUTE, minute);
            Timber.d("Time was set by user with TimePickerFragment to %s:%s", hourOfDay, minute);
            updateUiDateTime();
        }
    };
    private BroadcastReceiver datePickerMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Timber.d("Received DATE_SET_EVENT");
            Integer year = intent.getIntExtra(DatePickerFragment.YEAR, 0);
            Integer month = intent.getIntExtra(DatePickerFragment.MONTH, 0);
            Integer dayOfMonth = intent.getIntExtra(DatePickerFragment.DAY_OF_MONTH, 0);
            viewModel.batch.createDate.set(Calendar.YEAR, year);
            viewModel.batch.createDate.set(Calendar.MONTH, month);
            viewModel.batch.createDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
            Timber.d("Date was set by user with DatePickerFragment to %s/%s/%s", dayOfMonth, month, year);
            updateUiDateTime();
        }
    };

    private BroadcastReceiver ingredientPickerMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (activity == null) {
                // FIXME: the app will crash if this is true.
                Timber.e("Application Context is null");
            }
            Timber.d("Received INGREDIENT_SET_EVENT");
            String ingredientString = intent.getStringExtra(INGREDIENT);
            float amount = intent.getFloatExtra(AMOUNT, 0.0f);
            String unitString = intent.getStringExtra(UNIT);
            Timber.v("Got values from AddIngredientDialog: %s %s %s", ingredientString, amount, unitString);
            BatchIngredient batchIngredient = new BatchIngredient();
            batchIngredient.ingredientId = ingredientString;

            batchIngredient.quantityVol = toVolume(amount, abbreviationMap.get(unitString));
            viewModel.addIngredient(batchIngredient);
            updateUiIngredientsTable();
        }
    };

    private void updateUiIngredientsTable() {
        if (viewModel.batch.ingredients != null) {
            // FIXME: this is not performant and looks ghetto.
            Timber.d("Found %s BatchIngredients for this Batch; adding them to the ingredientsList",
                    viewModel.batch.ingredients.size());
            LinearLayout ingredientsList = activity.findViewById(R.id.ingredients_list);
            ingredientsList.removeAllViews();
            for (BatchIngredient ingredient : viewModel.batch.ingredients) {
                BatchIngredientView ingredientView = new BatchIngredientView(activity);
                ingredientView.setBatchIngredient(ingredient);
                ingredientsList.addView(ingredientView);
            }
        } else {
            Timber.d("No Ingredients found for this Recipe.");
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        activity = (Activity) context;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        dataBinding = DataBindingUtil.inflate(inflater, R.layout.batch_form_fragment, container, false);

        // FIXME: Mess. This should be moved somewhere else so other classes can use it
        abbreviationMap.put(getResources().getString(R.string.DEGREES_C), unitToTextAbbr(CELSIUS));
        abbreviationMap.put(getResources().getString(R.string.DEGREES_F), unitToTextAbbr(FAHRENHEIT));
        abbreviationMap.put(getResources().getString(R.string.LITER), unitToTextAbbr(LITER));
        abbreviationMap.put(getResources().getString(R.string.GALLON_LIQUID_US), unitToTextAbbr(GALLON_LIQUID));
        abbreviationMap.put(getResources().getString(R.string.GALLON_DRY_US), unitToTextAbbr(GALLON_DRY));
        abbreviationMap.put(getResources().getString(R.string.GALLON_LIQUID_UK), unitToTextAbbr(GALLON_UK));
        abbreviationMap.put(getResources().getString(R.string.OUNCE_LIQUID_US), unitToTextAbbr(FLUID_OUNCE));
        abbreviationMap.put(getResources().getString(R.string.OUNCE_LIQUID_UK), unitToTextAbbr(OUNCE_LIQUID));
        abbreviationMap.put(getResources().getString(R.string.TEASPOON), unitToTextAbbr(TEASPOON));
        abbreviationMap.put(getResources().getString(R.string.GRAM), unitToTextAbbr(GRAM));
        abbreviationMap.put(getResources().getString(R.string.KILOGRAM), unitToTextAbbr(KILOGRAM));
        abbreviationMap.put(getResources().getString(R.string.OUNCE), unitToTextAbbr(OUNCE));
        abbreviationMap.put(getResources().getString(R.string.POUND), unitToTextAbbr(POUND));

        viewModel = ViewModelProviders.of(this, viewModelFactory).get(BatchFormViewModel.class);

        Bundle bundle = this.getArguments();
        if (bundle != null) {
            Timber.i("Got Batch ID %d from the NavigationController. Acting as a Batch Editor.");

            long batchId = bundle.getLong(BATCH_ID, Long.MIN_VALUE);
            long recipeId = bundle.getLong(RECIPE_ID, Long.MIN_VALUE);
            if (batchId != Long.MIN_VALUE) {
                viewModel.getBatch(batchId).observe(this, batch -> {
                    if (batch != null) {
                        viewModel.batch = batch;
                        dataBinding.setBatch(batch);
                        if (batch.status != null) {
                            dataBinding.status.setText(batch.status.toString());
                        } else {
                            dataBinding.status.setText(PLANNING.toString());
                        }
                        updateUiDateTime();
                        viewModel.getBatchIngredients(batchId).observe(this, batchIngredients -> {
                            if (batchIngredients != null) {
                                Timber.v("Loaded %s Batch ingredients", batchIngredients.size());
                                viewModel.batch.ingredients = batchIngredients;
                                updateUiIngredientsTable();
                            } else {
                                Timber.w(
                                        "Received nothing from the RecipeRepository when trying to get ingredients for Batch %s",
                                        batchId);
                            }
                            Timber.i("Loaded Batch with ID %d:\n%s", batch.id, batch);
                        });
                        updateSpinners(viewModel.batch);
                    } else {
                        Timber.e("Got a null Batch!");
                    }
                });
            } else if (recipeId != Long.MIN_VALUE) {
                viewModel.getRecipe(recipeId).observe(this, recipe -> {
                    if (recipe != null) {
                        viewModel.batch = new Batch();
                        viewModel.batch.name = recipe.name;
                        viewModel.batch.outputVolume = recipe.outputVol;
                        viewModel.batch.targetSgStarting = recipe.startingSG;
                        viewModel.batch.targetSgFinal = recipe.finalSG;
                        viewModel.batch.status = PLANNING;
                        viewModel.batch.createDate = Calendar.getInstance();
                        viewModel.getCurrentUserId().observe(this, userId -> {
                            if (userId == null) {
                                Timber.e("Could not set the Batch User ID, since it's null?!");
                                return;
                            }
                            Timber.d("Setting batch user ID to %s", userId);
                            viewModel.batch.userId = userId;
                        });
                        dataBinding.setBatch(viewModel.batch);

                        dataBinding.status.setText(viewModel.batch.status.toString());
                        updateUiDateTime();
                        viewModel.getRecipeIngredients(recipeId).observe(this, recipeIngredients -> {
                            if (recipeIngredients != null) {
                                Timber.v("Loaded %s Recipe ingredients", recipeIngredients.size());
                                viewModel.batch.ingredients = recipeIngredients;
                                updateUiIngredientsTable();
                            } else {
                                Timber.w(
                                        "Received nothing from the RecipeRepository when trying to get ingredients for Batch %s",
                                        batchId);
                            }
                            Timber.i("Loaded Recipe with ID %d:\n%s", recipe.id, recipe);
                        });
                        updateSpinners(viewModel.batch);
                    } else {
                        Timber.e("Got a null Recipe!");
                    }
                });
            }
        } else {
            Timber.i("No Batch ID was received. Acting as a Batch Creation form.");
            viewModel.batch = new Batch();
            viewModel.batch.createDate = Calendar.getInstance();
            viewModel.getCurrentUserId().observe(this, userId -> {
                if (userId == null) {
                    Timber.e("Could not set the Batch User ID, since it's null?!");
                    return;
                }
                Timber.d("Setting batch user ID to %s", userId);
                viewModel.batch.userId = userId;
            });
            dataBinding.setBatch(viewModel.batch);
        }
        return dataBinding.getRoot();
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        if (viewModel.batch != null) {
            // We're in "edit" mode, so set the title accordingly
            FORM_MODE = MODES.EDIT;
            TextView formTitle = getActivity().findViewById(R.id.batchFormTitleTV);
            if (formTitle != null) {
                String title = getResources().getString(R.string.edit_batch_title);
                title = String.format(title, viewModel.batch.id);
                formTitle.setText(title);
            }
        } else {
            FORM_MODE = MODES.CREATE;
        }
        updateUiDateTime();

        TextView dateField = getActivity().findViewById(R.id.createDateDate);
        if (dateField != null) {
            dateField.setOnClickListener(v -> {
                Timber.i("Date was clicked!");
                DialogFragment newFragment = new DatePickerFragment();
                Bundle args = new Bundle();
                args.putInt(YEAR, viewModel.batch.createDate.get(Calendar.YEAR));
                args.putInt(MONTH, viewModel.batch.createDate.get(Calendar.MONTH));
                args.putInt(DAY_OF_MONTH, viewModel.batch.createDate.get(Calendar.DAY_OF_MONTH));
                newFragment.setArguments(args);
                newFragment.setTargetFragment(this, DATE_REQUEST_CODE);
                newFragment.show(getActivity().getSupportFragmentManager(), "datePicker");
            });
        }

        TextView timeField = getActivity().findViewById(R.id.createDateTime);
        if (timeField != null) {
            timeField.setOnClickListener(v -> {
                Timber.i("Time was clicked!");
                DialogFragment newFragment = new TimePickerFragment();
                Bundle args = new Bundle();
                args.putInt(HOUR, viewModel.batch.createDate.get(Calendar.HOUR));
                args.putInt(MINUTE, viewModel.batch.createDate.get(Calendar.MINUTE));
                newFragment.setArguments(args);
                newFragment.setTargetFragment(this, TIME_REQUEST_CODE);
                newFragment.show(getActivity().getSupportFragmentManager(), "timePicker");
            });
        }

        Button addSugarButton = getActivity().findViewById(R.id.add_sugar_button);
        if (addSugarButton != null) {
            addSugarButton.setOnClickListener(v -> {
                Timber.i("addSugarButton was clicked!");
                DialogFragment newFragment = new AddIngredientDialog();
                Bundle args = new Bundle();
                args.putString(INGREDIENT_TYPE, SUGAR.toString());
                newFragment.setArguments(args);
                newFragment.setTargetFragment(this, INGREDIENT_REQUEST_CODE);
                newFragment.show(getActivity().getSupportFragmentManager(), "sugarPicker");
            });
        }

        Button addNutrientButton = getActivity().findViewById(R.id.add_nutrient_button);
        if (addNutrientButton != null) {
            addNutrientButton.setOnClickListener(v -> {
                Timber.i("addNutrientButton was clicked!");
                DialogFragment newFragment = new AddIngredientDialog();
                Bundle args = new Bundle();
                args.putString(INGREDIENT_TYPE, NUTRIENT.toString());
                newFragment.setArguments(args);
                newFragment.setTargetFragment(this, INGREDIENT_REQUEST_CODE);
                newFragment.show(getActivity().getSupportFragmentManager(), "nutrientPicker");
            });
        }

        Button addYeastButton = getActivity().findViewById(R.id.add_yeast_button);
        if (addYeastButton != null) {
            addYeastButton.setOnClickListener(v -> {
                Timber.i("addYeastButton was clicked!");
                DialogFragment newFragment = new AddIngredientDialog();
                Bundle args = new Bundle();
                args.putString(INGREDIENT_TYPE, YEAST.toString());
                newFragment.setArguments(args);
                newFragment.setTargetFragment(this, INGREDIENT_REQUEST_CODE);
                newFragment.show(getActivity().getSupportFragmentManager(), "yeastPicker");
            });
        }

        Button addStabilizerButton = getActivity().findViewById(R.id.add_stabilizer_button);
        if (addStabilizerButton != null) {
            addStabilizerButton.setOnClickListener(v -> {
                Timber.i("addStabilizerButton was clicked!");
                DialogFragment newFragment = new AddIngredientDialog();
                Bundle args = new Bundle();
                args.putString(INGREDIENT_TYPE, STABILIZER.toString());
                newFragment.setArguments(args);
                newFragment.setTargetFragment(this, INGREDIENT_REQUEST_CODE);
                newFragment.show(getActivity().getSupportFragmentManager(), "stabilizerPicker");
            });
        }

        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(datePickerMessageReceiver,
                new IntentFilter(DATE_SET_EVENT));
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(timePickerMessageReceiver,
                new IntentFilter(TIME_SET_EVENT));
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(ingredientPickerMessageReceiver,
                new IntentFilter(INGREDIENT_SET_EVENT));

        Button submitButton = getActivity().findViewById(R.id.button_submit);
        if (submitButton != null) {
            submitButton.setOnClickListener(v -> {
                Timber.i("Submit button clicked!");
                FORM_MODE = (viewModel.batch.id == null) ? MODES.CREATE : MODES.EDIT;
                viewModel.batch.name = dataBinding.name.getText().toString().trim();
                viewModel.batch.targetSgStarting = toDouble(
                        dataBinding.targetSgStarting.getText().toString().trim());
                viewModel.batch.targetSgFinal = toDouble(dataBinding.targetSgFinal.getText().toString().trim());
                viewModel.batch.targetABV = toFloat(dataBinding.targetABV.getText().toString().trim());
                viewModel.batch.startingPh = toFloat(dataBinding.startingPh.getText().toString().trim());
                viewModel.batch.startingTemp = toFloat(dataBinding.startingTemp.getText().toString().trim());

                viewModel.batch.outputVolume = toVolume(dataBinding.outputVolumeAmount.getText().toString(),
                        abbreviationMap.get(dataBinding.outputVolumeAmountUnit.getSelectedItem().toString()));

                viewModel.batch.status = BatchStatusEnum.fromString(dataBinding.status.getText().toString().trim());
                viewModel.batch.notes = dataBinding.notes.getText().toString().trim();

                if (FORM_MODE == MODES.CREATE) {
                    Timber.d("We are in CREATE mode.");
                    Timber.d("Current batch state:\n%s", viewModel.batch.toString());
                    viewModel.saveNewBatch().observe(this, savedBatchId -> {
                        if (savedBatchId != null) {
                            Timber.i("Successfully saved Batch, which now has ID=%s", savedBatchId);
                            LocalBroadcastManager.getInstance(getActivity())
                                    .unregisterReceiver(datePickerMessageReceiver);
                            LocalBroadcastManager.getInstance(getActivity())
                                    .unregisterReceiver(timePickerMessageReceiver);
                            LocalBroadcastManager.getInstance(getActivity())
                                    .unregisterReceiver(ingredientPickerMessageReceiver);
                            Snackbar snackbar = Snackbar.make(getActivity().findViewById(R.id.container),
                                    "Saved batch!", Snackbar.LENGTH_LONG);
                            snackbar.show();
                            Answers.getInstance().logCustom(new CustomEvent("Batch create success"));
                            navigationController.navigateFromAddBatch(savedBatchId);
                        } else {
                            Answers.getInstance().logCustom(new CustomEvent("Batch create failed"));
                            Snackbar snackbar = Snackbar.make(getActivity().findViewById(R.id.container),
                                    "Failed to save batch!", Snackbar.LENGTH_LONG);
                            snackbar.show();
                        }
                    });
                } else {
                    Timber.d("We are in EDIT mode for batch #%s", viewModel.batch.id);
                    Timber.d("Current batch state:\n%s", viewModel.batch.toString());
                    viewModel.updateBatch();
                    LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(datePickerMessageReceiver);
                    LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(timePickerMessageReceiver);
                    LocalBroadcastManager.getInstance(getActivity())
                            .unregisterReceiver(ingredientPickerMessageReceiver);
                    Snackbar snackbar = Snackbar.make(getActivity().findViewById(R.id.container), "Updated batch!",
                            Snackbar.LENGTH_LONG);
                    snackbar.show();
                    Answers.getInstance().logCustom(new CustomEvent("Batch edit success"));
                    navigationController.navigateFromEditBatch(viewModel.batch.id);
                }

            });
        } else {
            Timber.e("Cannot find submit button in view");
        }
    }

    private int getIndex(Spinner spinner, String myString) {
        int index = 0;
        for (int i = 0; i < spinner.getCount(); i++) {
            if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(myString)) {
                index = i;
                break;
            }
        }
        return index;
    }

    private void updateSpinners(Batch batch) {
        if (batch == null) {
            Timber.e("Could not update spinners because batch is null");
            return;
        }
        if (batch.outputVolume != null) {
            double volumeAmount = (double) batch.outputVolume.getValue();
            DecimalFormat f = new DecimalFormat("#.##");
            dataBinding.outputVolumeAmount.setText(f.format(volumeAmount));
            Spinner volSpin = dataBinding.outputVolumeAmountUnit;
            String unitString = getResources().getString(unitToStringResource(batch.outputVolume.getUnit()));
            volSpin.setSelection(getIndex(volSpin, unitString));

            //            volSpin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            //                public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
            //                    Timber.v("Volume spinner item selected: pos=%s, id=%s, string=%s", pos, id, volSpin.getItemAtPosition(pos).toString()));
            //
            //                    Object item = parent.getItemAtPosition(pos);
            //                }
            //
            //                public void onNothingSelected(AdapterView<?> parent) {
            //                }
            //            });
        }
    }

    private void updateUiDateTime() {
        if (viewModel.batch == null) {
            return;
        }
        TextView timeField = getActivity().findViewById(R.id.createDateTime);
        if (timeField != null) {
            timeField.setText(calendarToLocaleTime(viewModel.batch.createDate));
        } else {
            Timber.e("Could not find createDateTime in View");
        }

        TextView dateField = getActivity().findViewById(R.id.createDateDate);
        if (dateField != null) {
            dateField.setText(calendarToLocaleDate(viewModel.batch.createDate));
        } else {
            Timber.e("Could not find createDateDate in View");
        }
    }

    private enum MODES {
        CREATE, EDIT
    }
}