/** * MIT License * * Copyright (c) 2016 Hishmad Abubakar Al-Amudi * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.stockita.stockitapointofsales.salespack.pendingpack; import android.app.DialogFragment; import android.app.LoaderManager; import android.content.Context; import android.content.CursorLoader; import android.content.Loader; import android.content.SharedPreferences; import android.database.Cursor; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.Nullable; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.TextView; import com.google.firebase.database.ServerValue; import com.stockita.stockitapointofsales.R; import com.stockita.stockitapointofsales.data.ContractData; import com.stockita.stockitapointofsales.data.SalesDetailModel; import com.stockita.stockitapointofsales.data.SalesHeaderModel; import com.stockita.stockitapointofsales.utilities.Constants; import com.stockita.stockitapointofsales.utilities.Utility; import java.util.ArrayList; import java.util.HashMap; import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; /** * This class is the checkout dialog for pending sales */ public class SalesPendingCheckoutDialogFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Cursor> { // Constant private static final String TAG_LOG = SalesPendingCheckoutDialogFragment.class.getSimpleName(); private static final int LOADER_IDE_ONE = 1; private static final String KEY_ONE = TAG_LOG + ".KEY_ONE"; private static final String KEY_TWO = TAG_LOG + ".KEY_TWO"; /** * The user's uid */ private String mUserUid; /** * The total amount before invoice discount and invoice tax, * this is passed from the {@link SalesPendingListFragmentUI} */ private String mTotalAmount; /** * An arrayList of type {@link SalesDetailModel}, the cursor will pack * the data into this list, so later we can pass them to the server */ private ArrayList<SalesDetailModel> mSalesDetailPendingList; /** * An arrayList of type String, to pack the push() key of each salesDetail * from the /salesDetailPending node */ private ArrayList<String> mSalesDetailPendingKeyList; // Views @Bind(R.id.checkbox_customer_name_form) EditText mCustomerNameForm; @Bind(R.id.checkbox_number_of_items_form) TextView mNumberOfItemsForm; @Bind(R.id.checkbox_total_amount_form) TextView mTotalAmountForm; @Bind(R.id.checkout_discount_value_form) TextView mDiscountAmountForm; @Bind(R.id.checkbox_service_charge_form) TextView mServiceChargeForm; @Bind(R.id.checkbox_tax_value_form) TextView mTaxAmountForm; @Bind(R.id.checkout_grand_total) TextView mGrandTotalForm; @Bind(R.id.checkout_cash_received) EditText mCashReceivedForm; @Bind(R.id.checkout_change) TextView mChangeForm; /** * Empty constructor */ public SalesPendingCheckoutDialogFragment() { } /** * Statics method as constructor to get the data pass into here * * @param userUid The user's UID * @return This fragment */ public static SalesPendingCheckoutDialogFragment newInstance(String userUid, String total) { SalesPendingCheckoutDialogFragment fragment = new SalesPendingCheckoutDialogFragment(); Bundle args = new Bundle(); args.putString(KEY_ONE, userUid); args.putString(KEY_TWO, total); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get it from the newInstance mUserUid = getArguments().getString(KEY_ONE); // Get it from SharedPreference. mTotalAmount = Utility.getAnyString(getActivity(), "checkout_total", "0"); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Start the loader, and initialize them. getLoaderManager().initLoader(LOADER_IDE_ONE, null, this); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Initialize the view and the layout View view = inflater.inflate(R.layout.dialog_fragment_sales_checkout, container); // Bind the view with ButterKnife ButterKnife.bind(this, view); // Update the UI mTotalAmountForm.setText(mTotalAmount); // Calculate the numbers calculate(); mCashReceivedForm.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { // Get the users typed String getTheUserTyped = editable.toString(); /** * Calculate the change below.. */ double getTheUserTypedInDouble; try { getTheUserTypedInDouble = Double.parseDouble(getTheUserTyped); } catch (Exception e) { getTheUserTypedInDouble = 0; } double getTheGrandTotal; try { getTheGrandTotal = Double.parseDouble(mGrandTotalForm.getText().toString()); } catch (Exception e) { getTheGrandTotal = 0; } double calculateTheChange = getTheUserTypedInDouble - getTheGrandTotal; // Update the UI mChangeForm.setText(String.valueOf(calculateTheChange)); } }); // Return the view return view; } /** * Calculate all the number then update the UI */ private void calculate() { // SharedPreferences SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity()); /** * Calculate the discount */ // Get the total amount from the UI parse them to double double totalAmountFromTheUi; try { totalAmountFromTheUi = Double.parseDouble(mTotalAmountForm.getText().toString()); } catch (Exception e) { totalAmountFromTheUi = 0; } // Get the discount rate from the sharedPreferences double discountRateFromSharedPreferences; try { discountRateFromSharedPreferences = Double.parseDouble(pref.getString("pref_discount", "0")); } catch (Exception e) { discountRateFromSharedPreferences = 0; } // Calculate the discount amount double discountAmount; try { discountAmount = totalAmountFromTheUi * discountRateFromSharedPreferences / 100; } catch (Exception e) { discountAmount = 0; } // Update the UI for discount amount mDiscountAmountForm.setText(String.valueOf(discountAmount)); /** * Calculate the service charges */ // Get the total amount after discount double totalAmountAfterDiscount; try { totalAmountAfterDiscount = totalAmountFromTheUi - discountAmount; } catch (Exception e) { totalAmountAfterDiscount = 0; } // Get the service charge rate from the SharedPreferences double serviceChargeRateFromSharedPreferences; try { serviceChargeRateFromSharedPreferences = Double.parseDouble(pref.getString("pref_service", "0"));; } catch (Exception e) { serviceChargeRateFromSharedPreferences = 0; } // Calculate the service charge amount double serviceChargeAmount; try { serviceChargeAmount = totalAmountAfterDiscount * serviceChargeRateFromSharedPreferences / 100; } catch (Exception e) { serviceChargeAmount = 0; } // Update the UI for service charge amount mServiceChargeForm.setText(String.valueOf(serviceChargeAmount)); /** * Calculate the Tax */ // Get the total amount after service charge double totalAmountAfterServiceCharges; try { totalAmountAfterServiceCharges = totalAmountAfterDiscount + serviceChargeAmount; } catch (Exception e) { totalAmountAfterServiceCharges = 0; } // Get the tax rate from the SharedPreferences double taxRateFromSharedPreferences; try { taxRateFromSharedPreferences = Double.parseDouble(pref.getString("pref_tax", "0")); } catch (Exception e) { taxRateFromSharedPreferences = 0; } // Calculate the tax amount double taxAmount; try { taxAmount = totalAmountAfterServiceCharges * taxRateFromSharedPreferences / 100; } catch (Exception e) { taxAmount = 0; } // Update the UI for the tax amount mTaxAmountForm.setText(String.valueOf(taxAmount)); /** * Calculate the grand total */ // Get the total amount after discount after server charge after tax double grandTotal; try { grandTotal = totalAmountAfterServiceCharges + taxAmount; } catch (Exception e) { grandTotal = 0; } // Update the Grand Total UI mGrandTotalForm.setText(String.valueOf(grandTotal)); } /** * Helper method when the user clicked the pay button * Using indirect {@link SalesPendingPayButtonIntentService#insertPay(Context, String, SalesHeaderModel, ArrayList, String, String, String, String)} * to do background processes via {@link com.stockita.stockitapointofsales.activities.MainActivity#onPayButton(String, SalesHeaderModel, ArrayList, String, String)} */ private void onPayButton() { // Check if the list of detail is not null and has data if (mSalesDetailPendingList != null && mSalesDetailPendingList.size() > 0) { // Gather data from UI String customerName = mCustomerNameForm.getText().toString(); String totalAmount = mTotalAmountForm.getText().toString(); String discountAmount = mDiscountAmountForm.getText().toString(); String serviceCharge = mServiceChargeForm.getText().toString(); String taxAmount = mTaxAmountForm.getText().toString(); String grandTotal = mGrandTotalForm.getText().toString(); String cashPaid = mCashReceivedForm.getText().toString(); String changeCash = mChangeForm.getText().toString(); // Instantiate the Sales Header Model SalesHeaderModel salesHeaderModel = new SalesHeaderModel(); // Get data from the UI then pass them into a model salesHeaderModel.setCustomerName(customerName); salesHeaderModel.setTotalAmount(totalAmount); salesHeaderModel.setDiscountAmount(discountAmount); salesHeaderModel.setServiceCharge(serviceCharge); salesHeaderModel.setTaxAmount(taxAmount); salesHeaderModel.setGrandTotal(grandTotal); // Create a HashMap for the server time stamp HashMap<String, Object> timeStamp = new HashMap<>(); timeStamp.put(Constants.FIREBASE_PROPERTY_TIMESTAMP, ServerValue.TIMESTAMP); // Pass the map into the pojo salesHeaderModel.setServerDate(timeStamp); // Pass the data to the activity for later background process ((PaymentButtonFromSalesPendingCheckoutDialogFragment) getActivity()) .onPayButton(mUserUid, salesHeaderModel, mSalesDetailPendingList, cashPaid, changeCash); // dismiss this dialog getDialog().dismiss(); } } /** * Helper method when the user clicked open bill button * Using {@link SalesPendingPayButtonIntentService#insertOpenBill(Context, String, SalesHeaderModel, ArrayList)} * to do background processes */ private void onOpenBillButton() { if (mSalesDetailPendingList != null && mSalesDetailPendingList.size() >0) { // Create an object then store the UI into it // Instantiate the Sales Header Model SalesHeaderModel salesHeaderModel = new SalesHeaderModel(); // Get data from the UI then pass them into a model for open bill only // customer name and total amount salesHeaderModel.setCustomerName(mCustomerNameForm.getText().toString()); salesHeaderModel.setTotalAmount(mTotalAmountForm.getText().toString()); // Create a HashMap for the server time stamp HashMap<String, Object> timeStamp = new HashMap<>(); timeStamp.put(Constants.FIREBASE_PROPERTY_TIMESTAMP, ServerValue.TIMESTAMP); // Pass the map into the pojo salesHeaderModel.setServerDate(timeStamp); // Call the intest service SalesPendingPayButtonIntentService.insertOpenBill(getActivity(), mUserUid, salesHeaderModel, mSalesDetailPendingList); // dismiss getDialog().dismiss(); } } /** * When the user click pay button */ @OnClick(R.id.pay_button) void clickPayButton() { onPayButton(); } /** * When the user click open bill button */ @OnClick(R.id.open_bill_button) void clickOpenBillButton() { onOpenBillButton(); } /** * When the user click cancel */ @OnClick(R.id.cancel_button) void clickCancelButton() { // Just dismiss the dialog, and have some fun. getDialog().dismiss(); } /** * Code below, is for retrieving data from local database... */ @Override public Loader<Cursor> onCreateLoader(int id, Bundle bundle) { // Return new cursor with the following query parameters. CursorLoader loader = null; switch (id) { case LOADER_IDE_ONE: loader = new CursorLoader(getActivity(), ContractData.SalesDetailPendingEntry.CONTENT_URI, null, null, null, null); break; } return loader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // A switch-case is useful when dealing with multiple Loader/IDs switch (loader.getId()) { case LOADER_IDE_ONE: // The asynchronous load is complete and the data // is now available for use. Only now we can associate // the required Cursor with the adapter. // Set the cursor to first position; data.moveToFirst(); // Get the number of rows. int dataCount = data.getCount(); // Instantiate new ArrayList<ModelMovie> mSalesDetailPendingList = new ArrayList<>(); mSalesDetailPendingKeyList = new ArrayList<>(); // Add each row into an array element. for (int i = 0; i < dataCount; i++) { SalesDetailModel model = new SalesDetailModel(); model.setItemNumber(data.getString(ContractData.SalesDetailPendingEntry.INDEX_COL_ITEM_NUMBER)); model.setItemDesc(data.getString(ContractData.SalesDetailPendingEntry.INDEX_COL_ITEM_DESC)); model.setItemUnit(data.getString(ContractData.SalesDetailPendingEntry.INDEX_COL_ITEM_UNIT)); model.setItemPrice(data.getString(ContractData.SalesDetailPendingEntry.INDEX_COL_ITEM_PRICE)); model.setItemQuantity(data.getString(ContractData.SalesDetailPendingEntry.INDEX_COL_ITEM_QUANTITY)); model.setItemDiscount(data.getString(ContractData.SalesDetailPendingEntry.INDEX_COL_ITEM_DISCOUNT)); model.setItemDiscountAmout(data.getString(ContractData.SalesDetailPendingEntry.INDEX_COL_ITEM_DISCOUNT_AMOUNT)); model.setItemAmount(data.getString(ContractData.SalesDetailPendingEntry.INDEX_COL_ITEM_AMOUNT)); // Pack the model into a list mSalesDetailPendingList.add(model); // Pack the key into a list mSalesDetailPendingKeyList.add(data.getString(ContractData.SalesDetailPendingEntry.INDEX_COL_PUSH_KEY)); // Make the cursor move to next if any data.moveToNext(); } /** * Update the UI below */ // calculate the number of items then update the UI int numberOfItems = mSalesDetailPendingList.size(); mNumberOfItemsForm.setText(String.valueOf(numberOfItems)); } } @Override public void onLoaderReset(Loader<Cursor> loader) { loader = null; } /** * This is an interface to pass data to {@link com.stockita.stockitapointofsales.activities.MainActivity} * This callback then will call the credit card later, then later will call InterService {@link SalesPendingPayButtonIntentService} * to store data into the server */ public interface PaymentButtonFromSalesPendingCheckoutDialogFragment { void onPayButton(String encodedEmail, SalesHeaderModel salesHeaderModel, ArrayList<SalesDetailModel> salesDetailModelList, String cashPaid, String changeCash); } }