Skip to content

App illustrating the Inventory App Project, done as part of Udacity's Android Basics Nanodegree course.

License

Notifications You must be signed in to change notification settings

kaushiknsanji/StoreApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

StoreApp - The Store Inventory App

GitHub GitHub code size in bytes GitHub repo size GitHub release (latest by date) GitHub All Releases GitHub search hit counter Minimum API level

This App has been developed as part of the Udacity Android Basics Nanodegree Course for the Exercise Project "Inventory App". This App allows a Store to keep track of the inventory of its Products across the listed Suppliers of Products, along with their Price and Pictures of the Product.


App Compatibility

Android device running with Android OS 4.0.4 (API Level 15) or above. Best experienced on Android Nougat 7.1 and above. Designed for Phones and NOT for Tablets.


Rubric followed for the Project

  • App contains products and allows to configure a new product.
  • The List Item shows -
    • The Product Name
    • Current Quantity of the Product
    • Price of the Product.
  • Each List Item contains a Sale button that reduces the Quantity by 1. This should ensure not to display negative quantities.
  • The Detail layout needs to -
    • Display the remainder of the details stored in the database.
    • Contain buttons that vary the Available Quantity of the Product.
    • Contain a button to order more from the Supplier.
    • Contain a button to delete the Product entirely.
  • When there are no Products in the database, layout should display a TextView with instructions on how to populate the database.

Things explored/developed in addition to the above defined Rubric

  • Storing required information in a SQLite database.
  • Designing and developing the Database Schema with relationships between Product, Supplier, Selling Price, Inventory, Images, Additional Product information and Supplier Contact Information to enable -
    • Multiple Seller registration per Product with their own Selling Price, Availability and Contact information.
    • Multiple Contacts per Seller, supporting different Contact Types like Phone and Email.
    • Multiple Product Photos.
    • Additional Attibutes that further defines the Product.
  • Integrating Android’s File storage systems into the database for Images. Images are persisted by saving the Image files' Content URI in the database instead of storing the entire BLOB of the Image.
  • Communicating with and managing the Database through a Content Provider.
  • Communicating with the File Storage through a File Provider for saving and accessing the Images of a Product.
  • Presenting information from Files and SQLite databases to users.
  • Designing layouts with TextInputLayout and TextInputEditText to capture User input, validating the captured information to display the required error, and updating the database with the information.
  • Creating intents to other apps such as the File Picker App for selecting images and the Image Capture App for taking pictures, using stored information.
    • Capturing Images is accomplished using ACTION_IMAGE_CAPTURE Intent, and processing the Image for storage is done using a custom ImageStorageUtility in a Disk thread provided by AppExecutors.
    • Selecting Images is accomplished using ACTION_GET_CONTENT/ACTION_OPEN_DOCUMENT Intent, based on the Android system version.
  • Promoting the separation of concerns using the MVP Architecture with Content Providers along with Repository pattern for Datasource that includes local files and database storage. Dependency injection is accomplished using a static InjectorUtility.
  • Designing layouts using CoordinatorLayout and ConstraintLayout.
  • Designing Item Views using CardView.
  • Loading of Images using a custom Headless Fragment through an AsyncTaskLoader and caching recently loaded images using BitmapImageCache that internally uses android.util.LruCache.
  • Live Debugging using Stetho to see and validate the changes following any CRUD operation during the development process, in order to ensure that the operations are working as intended.
  • Presenting Product Attributes information using a TableLayout with its data populated dynamically.

Design Workflow

App is structured as an Inventory App that allows a Store to keep track of its Product inventory and record sales information. It allows to store every information of a Product along with its pictures and Suppliers information with their price and available to sell quantity. It also features Product procurement from Suppliers via the supplied Contact information of Suppliers recorded.

The Home Screen or the Main Activity of the App

Products Tab Suppliers Tab Sales Tab
productstabempty supplierstabempty salestabempty

The Main Activity displays a Tab Layout with three tabs -

  1. Products Tab
    • Shows a list of Products configured if any.
    • Allows to configure a New Product in the database.
  2. Suppliers Tab
    • Shows a list of Suppliers configured if any.
    • Allows to configure a New Supplier in the database.
  3. Sales Tab
    • Shows a list of Products configured with their Sales information.
    • Allows to quick sell a quantity of any Product shown.

Products Tab - ProductListFragment

PORTRAIT LANDSCAPE
productslistportrait productslistlandscape
  • Displays a list of Products configured.
  • Each Product Card shown will contain -
    • The Product Name and SKU.
    • The Category of the Product.
    • The Default image given for the Product if any. If there is no Image, then a vector image of a generic Product will be shown.
  • Each Product Card has options for deleting and editing the Product.
    • When "DELETE" is clicked, the entire Product and its relationship data will be deleted.
    • When "EDIT" is clicked, the selected Product will be launched for editing via the ProductConfig Activity/Fragment.
    • ProductConfig Activity/Fragment for a Product can also be launched by just clicking on the entire Product Card.
  • The screen also has a FAB "+" button, which launches the ProductConfig Activity/Fragment to configure a New Product into the database.

ProductConfig Activity/Fragment

Add Product Edit Product
addproduct1
addproduct2
editproduct1

Images for Validations

Mandatory SKU Error Duplicate SKU Error
addproductmandatoryskuerror addproductskudupeerror
  • The First step in setting up the Store is configuring the Products which is done in this Activity/Fragment.
  • This can be launched by clicking on any Product shown in the Products Tab (for Editing an existing Product) or clicking on the FAB "+" button of the Products Tab (for configuring a New Product).
  • Allows to record Product Name, SKU, Description, Category and Additional Attributes.
  • SKU is limited to 10 alphanumeric characters and needs to be unique.
    • Error message will be shown when the entered SKU already exists (Not unique).
    • Error message will also be shown when the field is left blank.
    • This field will be disabled when the Activity is launched for Editing an existing Product.
  • Category "Other" allows to define a custom Category which is persisted in the database on "Save" of the Product details entered.
    • If an existing Category is being defined under Category "Other", that existing category will be selected automatically, thereby avoiding duplicate entry.
    • If Category "Other" is selected, and custom category is not defined, then an error message will be shown on "Save" of the Product details entered.
  • Additional Attributes are entered as a Name-Value pair.
    • Name should remain unique. An error message will be shown if there is an entry with the same Name.
    • If there is an Additional Attribute entry with NO value entered in the Value part of the Name-Value pair, then an error message will be shown on "Save" of the Product details entered.
    • If there is an Additional Attribute entry with NO value entered in both parts of Name-Value pair, then that entry will be removed silently on "Save" of the Product details entered.
  • This screen also shows the Default Image selected for the Product. Images can be added using the edit button present on it.

ProductImage Activity/Fragment

No Images With Images Images selected for Delete
productimageempty productimages productimagemultidelete
  • Launches via the edit button placed on the default Image of the Product shown in the ProductConfig Activity/Fragment.
  • Allows to add images for the Product and maintain a Gallery of Product's Images.
  • Once the Images are added, one can select an Image from the list to be shown as the default Image for the Product.
  • Images can be loaded either by selecting/picking them from the Gallery app of the Android System or capturing an Image through Camera.
    • URIs to the Image files of the Product are persisted in the database and NOT the BLOB of the Images.
    • Images captured through Camera are stored either in Primary Storage Area or Secondary Storage Area of the App based on their availability. Secondary Storage Area of the App will be given the preference when they are available.
    • Multiple Images can be picked from the Gallery App of the Android Sytem. When the same image(s) are being picked, an error message will be shown.
  • Multiple Images from the Product can be selected for delete in this screen as it supports Contextual Action for Delete. Image files that were captured by this App will only be deleted and does NOT delete the Image files that were picked through the Gallery System App.
  • One of the Images loaded for the Product should be selected as a Default Image. This will be enforced within this screen and one of the images if present (the first image in the list when none are selected) will be auto-selected as Default if the user decides to navigate back to the parent without executing/saving their selection.
  • If a defaulted Image is deleted, then the first image in the list will be auto-defaulted to ensure that one image remains defaulted always.
  • Images/URIs loaded for the Product in this screen will stay persisted even if the user decides to navigate back to the parent without saving.
  • For a New Product entry, the Images/URIs persisted for the Product in this screen will be deleted silently in case the user decides to discard the New Product entry details.
  • For an Existing Product entry, the Images/URIs persisted for the Product will be deleted when the Product is deleted in the ProductConfig Activity/Fragment.

ProductImage Picker DialogFragment

PORTRAIT LANDSCAPE
imagepickerdialogportrait imagepickerdialoglandscape
  • Launches via the FAB shown on ProductImage Activity screen.
  • Provides two options -
    1. Take Photo
      • Launches the Camera app to click Photos.
    2. Pick from Gallery
      • Launches the File Picker for Images with multi-select option enabled.

Suppliers Tab - SupplierListFragment

  • Displays a list of Suppliers configured.
  • Each Supplier Card shown will contain -
    • The Supplier Name and Code.
    • Number of Products the Supplier sells.
    • Defaulted Phone Contact if present and Defaulted Email Contact if present.
  • Clicking on the Defaulted Phone Contact launches a System Dialer with the Phone number to dial.
  • Clicking on the Defaulted Email Contact launches an Email application with the address populated in the "TO" field.
  • Each Supplier Card has options for deleting and editing a Supplier.
    • When "DELETE" is clicked, the entire Supplier and its relationship data will be deleted.
    • When "EDIT" is clicked, the selected Supplier will be launched for editing via the SupplierConfig Activity/Fragment.
    • SupplierConfig Activity/Fragment for a Supplier can also be launched by just clicking on the entire Supplier Card.
  • The screen also has a FAB "+" button, which launches the SupplierConfig Activity/Fragment to configure a New Supplier into the database.

SupplierConfig Activity/Fragment

Add Supplier Supplier with Product Picked Edit Supplier
addsupplier1 addsupplier2 editsupplier

Images for Validations

Invalid Phone Duplicate Phone Invalid Email Duplicate Email
invalidphone duplicatephoneerror invalidemail duplicateemailerror
  • The Second step in setting up the Store is configuring the Suppliers for the Products which is done in this Activity/Fragment.
  • This can be launched by clicking on any Supplier shown in the Suppliers Tab (for Editing an existing Supplier) or clicking on the FAB "+" button of the Suppliers Tab (for configuring a New Supplier).
  • Allows to record Supplier Name, Supplier Code, Supplier Contacts (Phone and Email) and Supplier's list of Products with their Selling Price information.
  • Supplier Code is limited to 12 alphanumeric characters and needs to be unique.
    • Error message will be shown when the entered Supplier Code already exists (Not unique).
    • Error message will also be shown when the field is left blank.
    • This field will be disabled when the Activity is launched for Editing an existing Supplier.
  • Supplier Contacts are Phone Contacts and/or Email Contacts. Contact details are required for Product procurement process.
    • If a Contact entry has been added and the Contact value is not present, then the entry will be removed silently on "Save" of the Supplier details entered.
    • If a Contact value has been defined more than once, then an error message will be shown when the user has navigated away from the entry or on "Save" of the Supplier details entered.
    • If the input Contact value is invalid, then an error message will be shown when the user has navigated away from the entry or on "Save" of the Supplier details entered.
    • There should be atleast one contact for a Supplier and needs to be defaulted. If there is no contact entered for a Supplier, then an error message will be shown on "Save" of the Supplier details entered.
    • Any first Contact entry, will be auto-defaulted. In case a defaulted Contact is removed, then the first one in the list (Phone Contacts or Emails) will be auto-defaulted to ensure that one contact remains defaulted always.
  • Supplier's Products are added by picking the Products to sell via the SupplierProductPicker Activity/Fragment.
    • Once the Products are picked, user can input the Selling Price for each of the Products.
    • There is no validation on the Selling Price. User can input the value or leave it blank. If left blank, the value will be defaulted to "0.0".
    • Products that are already picked will not appear for picking again in the SupplierProductPicker Activity/Fragment. This avoids duplications.
    • When a registered Product is swiped/removed from the list, the Supplier-Product link will be removed along with their Selling Price and availability if any. The Product entry will NOT be deleted.

SupplierProductPicker Activity/Fragment

Picker List Picker Multi Select
productpickerlist productpickermultiselect

Images for Search Filter

Search Results Search Error
productpickersearchcorrect productpickerincorrectsearch
  • Launches via the "ADD ITEM" button placed on the "Supplier Items" section of the Supplier shown in the SupplierConfig Activity/Fragment.
  • Allows to pick Products for a Supplier to sell.
  • Prior to displaying the list, it filters the already registered list of Products to sell and shows only the remaining products which are available to sell. Hence, this avoids picking already picked products.
  • Allows to pick multiple products at once.
  • Provides a SearchView which can filter the list by Product Name/SKU/Category.

Sales Tab - SalesListFragment

List With Inventory List with Out-Of-Stock
saleslist saleslistoos
  • Displays a list of Products configured with its Sales information.
  • Each Product Card shown will contain -
    • The Product Name and SKU.
    • The Category of the Product.
    • The Default image given for the Product if any. If there is no Image, then a vector image of a generic Product will be shown.
    • The Total Available Quantity of the Product.
    • Supplier with highest availability (Top Supplier).
      • Supplier Name and Supplier Code.
      • Supplier's Selling Price.
      • Supplier's current availability of the Product.
  • Each Product Card shown has options for deleting the Product and selling 1 quantity of the Product from the Top Supplier being displayed.
    • When "DELETE PRODUCT" is clicked, the entire Product and its relationship data will be deleted.
    • When "SELL 1" is clicked, one quantity from the Top Supplier will be reduced to indicate that one quantity has been shipped from the Supplier's Stock. This recalculates the next Top Supplier and Supplier's details shown will be refreshed to reflect the next Top Supplier.
    • SalesConfig Activity/Fragment can be launched by just clicking on the Product Card.
  • There is no FAB button for this screen, as this gets populated based on the configurations of Products and its Suppliers.

SalesConfig Activity/Fragment

Product Details Product Availability Product's Suppliers
salesproduct1 Out of Stock
salesproduct2oos

With Availability
salesproductavail
Suppliers with Availability
salessuppliers

Suppliers with OOS
salessuppliersoos
  • The Third step in setting up the Store is configuring the Availability of the Products at each of its Suppliers which is done in this Activity/Fragment.
  • This can be launched by clicking on any Product shown in the Sales Tab.
  • Displays all details of the Product launched and its list of Suppliers with their Price and availability information (at Supplier and Product level).
  • One can launch the ProductConfig Activity/Fragment to edit the Product from the Product details edit button. Also, one can edit any Supplier by clicking on their "EDIT" option to launch the SupplierConfig Activity/Fragment.
  • Allows to change the availability of the Product at the listed Suppliers.
  • Allows to dispatch a Product Procurement request to any Supplier. User needs to click on the "PROCURE" button against any listed Supplier to launch the SalesProcurement Activity/Fragment for initiating the Product Procurement.
  • Deleting the Product removes the Product details and its relationship data from the database.
  • Swiping/removing the listed Supplier, will delete the Product-Supplier link along with their Selling Price and availability if any. The Supplier entry will NOT be deleted.

SalesProcurement Activity/Fragment

Procurement Options Email Sample for Procurement via Email
Via Phone
salesprocureoos1

Via Email by specifying the quantity needed
salesprocureqty
salesprocureemailtemplate
  • Launches via the "PROCURE" button on any listed Supplier of the Product in SalesConfig Activity/Fragment.
  • Displays the Available quantity at the selected Supplier, Phone Contacts if any and an option for Sending an Email to Supplier if any Email Contacts are present.
  • Clicking on any of the Phone Contacts displayed, will launch the System Dialer with the Phone number that was selected.
  • If the Email option is present, it will have a field for entering the "quantity required from the Supplier" for Procurement. Clicking on Send, will launch an Email pre-templated with a message Body, with the defaulted address in the "TO" field and other addresses if any in the "CC" field. The Message body will contain -
    • The Name and SKU of the Product.
    • The current availability at the Supplier.
    • The required quantity mentioned. If the quantity is not mentioned, then 0 quantity will be passed by default.

About Activity

  • Launches via the "About" Menu available in the MainActivity.
  • This page describes in brief about the app, and has links to my bio and the course details hosted by Udacity.

App Architecture

Implementation Architecture

Illustrates the introduction of a content provider in this version of the app.

  • App follows the MVP pattern as described in the Google Samples for MVP with Content Providers.
  • Activities and DialogFragments that do not need any access to Repository are excluded from the MVP architecture.
  • Access to the Repository is governed by the StoreRepository which interfaces with two other repositories -
    1. Local Database Storage - StoreLocalRepository
      • For the Database management that stores and manages the Products, Suppliers and their Sales information.
    2. Local File Storage - StoreFileRepository
      • For the Products' Images storage and their management.

Database Schema

  • The Store Database is made up of the following tables that have relationship with each other as shown in the above Schema -

    • "item" Table.
      • Stores the Product information.
    • "item_category" Table.
      • Stores a list of Categories that can used to categorize a Product.
    • "item_image" Table.
      • Stores the Images of a Product.
    • "item_attr" Table.
      • Stores the Additional Attributes information of a Product.
    • "supplier" Table.
      • Stores the Supplier information.
    • "contact_type" Table.
      • Stores the different Contact types of a Supplier Contact information.
    • "supplier_contact" Table.
      • Stores the contact information of a Supplier.
    • "item_supplier_info" Table.
      • Stores the Supplier's listed Price for a Product.
    • "item_supplier_inventory" Table.
      • Stores the Supplier's available to sell quantity for a Product.
  • The Queries executed for retrieving the required information in each Fragment/Activity are provided by the Utility class QueryArgsUtility. Each of the queries executed are documented in this class.

  • For more information on the Database Schema, read the Store Database Schema Wiki.


Branches in this Repository

  • udacity
    • Contains the code submitted for review, along with review suggestions incorporated.
    • Updated Gradle version and applied valid lint corrections.
    • Added Copyright info.
  • release_v1.0
    • Used ConstrainedWidth to enforce WRAP_CONTENT constraints on Views and MaxLines on TextViews to optimize the UI - (commit) and (commit).
    • Saving Product Images to the database and file storage, only when there is an update/change - (commit).
    • Displaying unsaved changes dialog only when there is an update/change - (commit).
    • Deleting Product Images when the Product is deleted from the database, either from the Product/Sales Configuration screens and the Product/Sales List screens - (commit).
    • Releasing orientation lock when a dialog is canceled on touch from outside - (commit).
    • Enabled logging for debuggable build types only, through the use of custom Logger which is a wrapper to the android.util.Log - (commit).
    • Pressing home/up button or back key on an unsaved New Config entry, displays the unsaved changes dialog - (commit).
    • Using Product Attributes copy for detecting any changes later in the Product configuration - (commit).
    • Null Pointer check when a Supplier Contact is deleted while another Supplier Contact is being validated and recorded - (commit).
    • Passing 0 as the required quantity to procure when no quantity is provided while procuring by Email - (commit).
    • Invalidating/reloading Item decorations when new data item is added/updated/removed in the Product/Supplier/Sales lists - (commit).
    • Configured an Activity Alias to launch the MainActivity - (commit).
    • Other minor changes to prepare the app for local release.

Icon and Image credits


Review from the Reviewer (Udacity)

review


License

Copyright 2018 Kaushik N. Sanji

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.