at.florian_lentsch.expirysync.AddProductActivity.java Source code

Java tutorial

Introduction

Here is the source code for at.florian_lentsch.expirysync.AddProductActivity.java

Source

/*
* This file is part of ExpirySync.
*
* ExpirySync is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
    
* ExpirySync is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
    
* You should have received a copy of the GNU General Public License
* along with ExpirySync.  If not, see <http://www.gnu.org/licenses/>
*/

package at.florian_lentsch.expirysync;

import java.util.ArrayList;
import java.util.GregorianCalendar;

import org.joda.time.DateTime;

import android.annotation.TargetApi;
import android.app.ActionBar;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;

import at.florian_lentsch.expirysync.db.DatabaseManager;
import at.florian_lentsch.expirysync.model.Article;
import at.florian_lentsch.expirysync.model.ArticleImage;
import at.florian_lentsch.expirysync.model.ProductEntry;
import at.florian_lentsch.expirysync.net.ServerProxy;
import at.florian_lentsch.expirysync.util.Util;

/**
 * Activity displaying a form to add new product entries
 * 
 * @author Florian Lentsch <office@florian-lentsch.at>
 * 
 */
public class AddProductActivity extends ProductCrudActivity {
    // activities result codes:
    public static final int RESULT_OK_ADD_ANOTHER = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.product_form);
        loadPhotoFromSaveInstanceState(savedInstanceState);

        initFormFields();

        // Default values etc:
        EditText amountField = (EditText) findViewById(R.id.amount_field);
        String hint = amountField.getHint().toString();
        hint += " (" + getResources().getText(R.string.default_value) + ": " + DEFAULT_AMOUNT + ")";
        amountField.setHint(hint);

        // Show the Up button in the action bar.
        setupActionBar();

        boolean scanBarcodeOnStart = savedInstanceState != null
                ? savedInstanceState.getBoolean("scanBarcodeOnStart", true)
                : true;
        if (scanBarcodeOnStart) {
            Intent intent = new Intent(this, ScanBarcodeActivity.class);
            startActivityForResult(intent, SCAN_BARCODE_RESULT);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("scanBarcodeOnStart", false);
    }

    /**
     * Set up the {@link android.app.ActionBar}, if the API is available.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void setupActionBar() {
        ActionBar actionBar = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && (actionBar = getActionBar()) != null) {
            actionBar.setDisplayHomeAsUpEnabled(true); // TODO: Find out, why
            // this is not being
            // done for android 4
            // for example
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.add_product, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            break;
        case R.id.action_save:
            this.addProduct(false);
            break;
        case R.id.action_save_and_add_product:
            this.addProduct(true);
            break;
        case R.id.action_cancel_adding:
            setResult(RESULT_CANCELED);
            finish();
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * Saves the form data and then ends the activity
     * 
     * @param addAnotherAfterwards
     *            if true, the calling activity is asked to open another add
     *            activity directly after finishing this one
     */
    public void addProduct(final boolean addAnotherAfterwards) {
        // validation:
        if (!validateForm()) {
            return;
        }

        // show the loader:
        Util.showProgress(this);

        // populate db models with form data:
        final Article article = createArticleFromFormData();
        final ArrayList<ArticleImage> imagesList = addFormImageToArticle(article);
        final ProductEntry productEntry = createProductEntryFromFormData(article);

        ServerProxy entryProxy = ServerProxy.getInstanceFromConfig(this);
        if (entryProxy.getCurrentUser() != null) {
            // add the entry on the server:
            entryProxy.createProductEntry(productEntry, imagesList, entryProxy.new ProductEntryCallback() {
                @Override
                public void onReceive(ProductEntry receivedEntry) {
                    AddProductActivity.this.onProductEntryAddedOnServer(receivedEntry, productEntry,
                            addAnotherAfterwards);
                }
            });
        } else {
            // no user to add the entry with on the server -> exit the activity
            // straight away:
            finishAdding(addAnotherAfterwards);
        }

        // save the entry in the local database:
        final DatabaseManager dbManager = DatabaseManager.getInstance();
        dbManager.addProductEntry(productEntry);
    }

    /**
     * Creates an {@link Article} from the data entered by the user
     * 
     * @return the requested {@link Article}
     */
    private Article createArticleFromFormData() {
        EditText nameField = ((EditText) findViewById(R.id.product_name_field));

        Article article = new Article();

        article.barcode = ((EditText) findViewById(R.id.barcode_field)).getText().toString();
        article.name = nameField.getText().toString();

        return article;
    }

    /**
     * Adds the image from the form to {@link Article#images} (if there is one)
     * 
     * @param article
     *            the article to add the image to
     * @return list of images (currently only contains 1 or 0
     *         {@link ArticleImage}s)
     */
    private ArrayList<ArticleImage> addFormImageToArticle(Article article) {
        final DatabaseManager dbManager = DatabaseManager.getInstance();
        final ArrayList<ArticleImage> imagesList = new ArrayList<ArticleImage>();
        final ImageView productImageView = (ImageView) findViewById(R.id.product_img);
        final BitmapDrawable drawable = ((BitmapDrawable) productImageView.getDrawable());
        final Bitmap productBitmap = drawable != null ? drawable.getBitmap() : null;

        article = dbManager.updateOrAddArticle(article);
        if (this.photoPath != null || productBitmap != null) {
            final Resources res = getResources();
            ArticleImage image = new ArticleImage();
            // TODO: Make hardcoded dimensions configurable:
            image.imageData = (this.photoPath != null) ? getPhotoData(300, 200)
                    : getBitmapData(productBitmap, res.getDimensionPixelSize(R.dimen.product_img_width),
                            res.getDimensionPixelSize(R.dimen.product_img_height));
            image.article = article;
            article.images = dbManager.initializeArticleImagesCollection();
            article.images.add(image);
            imagesList.add(image);
        }

        return imagesList;
    }

    /**
     * Creates a {@link ProductEntry} from the form data
     * 
     * @param article
     *            the article associated with the entry
     * @return the requested {@link ProductEntry}
     */
    private ProductEntry createProductEntryFromFormData(Article article) {
        final ProductEntry productEntry = new ProductEntry();
        productEntry.article = article;

        EditText amountField = ((EditText) findViewById(R.id.amount_field));
        String amountStr = amountField.getText().toString();
        if (amountStr.trim().equals("")) {
            amountStr = DEFAULT_AMOUNT;
        }
        productEntry.amount = Integer.parseInt(amountStr);
        productEntry.created_at = new DateTime();
        productEntry.updated_at = new DateTime();
        productEntry.description = ((EditText) findViewById(R.id.product_description_field)).getText().toString();

        DatePicker datePicker = (DatePicker) findViewById(R.id.expiration_date_field);
        productEntry.expiration_date = (new GregorianCalendar(datePicker.getYear(), datePicker.getMonth(),
                datePicker.getDayOfMonth())).getTime();
        productEntry.location = ProductListActivity.currentLocation;

        productEntry.inSync = false;

        return productEntry;
    }

    /**
     * Sets the newly added entry's serverId in the local database and ends the
     * activity
     * 
     * @param receivedEntry
     *            entry received from the server
     * @param productEntry
     *            entry as in the local db
     * @param addAnotherAfterwards
     *            if true, the calling activity is asked to open another add
     *            activity directly after finishing this one
     */
    private void onProductEntryAddedOnServer(ProductEntry receivedEntry, ProductEntry productEntry,
            boolean addAnotherAfterwards) {
        if (receivedEntry != null) {
            final DatabaseManager dbManager = DatabaseManager.getInstance();

            productEntry.serverId = receivedEntry.serverId;
            productEntry.inSync = true;
            productEntry.created_at = receivedEntry.created_at;
            productEntry.updated_at = receivedEntry.updated_at;
            dbManager.updateProductEntry(productEntry);
        } else {
            Util.showMessage(this, "Adding to server failed");
        }

        finishAdding(addAnotherAfterwards);
    }

    /**
     * hides the loader, sets the result, and finished the activity
     * 
     * @param addAnotherAfterwards
     *            if true, the calling activity is asked to open another add
     *            activity directly after finishing this one
     */
    private void finishAdding(boolean addAnotherAfterwards) {
        Util.hideProgress();
        if (addAnotherAfterwards) {
            setResult(RESULT_OK_ADD_ANOTHER);
        } else {
            setResult(RESULT_OK);
        }
        finish();
    }
}