/** * Copyright (c) 2012 Vinayak Solutions Private Limited * See the file license.txt for copying permission. */ package com.vinsol.expensetracker.expenselisting; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; import com.flurry.android.FlurryAgent; import com.vinsol.expensetracker.BaseActivity; import com.vinsol.expensetracker.Constants; import com.vinsol.expensetracker.R; import com.vinsol.expensetracker.entry.CameraEntry; import com.vinsol.expensetracker.entry.Text; import com.vinsol.expensetracker.entry.Voice; import com.vinsol.expensetracker.expenselisting.dialog.UnknownEntryDialog; import com.vinsol.expensetracker.helpers.CheckEntryComplete; import com.vinsol.expensetracker.helpers.ConvertCursorToListString; import com.vinsol.expensetracker.helpers.DatabaseAdapter; import com.vinsol.expensetracker.helpers.DateHelper; import com.vinsol.expensetracker.helpers.DisplayDate; import com.vinsol.expensetracker.helpers.StringProcessing; import com.vinsol.expensetracker.models.Entry; import com.vinsol.expensetracker.models.ListDatetimeAmount; import com.vinsol.expensetracker.show.ShowCamera; import com.vinsol.expensetracker.show.ShowText; import com.vinsol.expensetracker.show.ShowVoice; import com.vinsol.expensetracker.sync.SyncHelper; import com.vinsol.expensetracker.utils.GetArrayListFromString; import com.vinsol.expensetracker.utils.Log; import com.vinsol.expensetracker.utils.Strings; abstract class ListingAbstract extends BaseActivity implements OnItemClickListener { protected List<ListDatetimeAmount> mDataDateList; protected SeparatedListAdapter mSeparatedListAdapter; protected List<Entry> mSubList; protected ConvertCursorToListString mConvertCursorToListString; protected StringProcessing mStringProcessing; protected ListView mListView; protected String highlightID = null; protected UnknownEntryDialog unknownDialog; private static final int RESULT = 35; protected Bundle intentExtras; private DatabaseAdapter mDatabaseAdapter; protected int type; @Override protected void onStart() { super.onStart(); FlurryAgent.onStartSession(this, getString(R.string.flurry_key)); } @Override protected void onStop() { super.onStop(); FlurryAgent.onEndSession(this); } @Override public boolean removeGenerateReport(Menu menu) { return false; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(); intentExtras = new Bundle(); mConvertCursorToListString = new ConvertCursorToListString(this); mStringProcessing = new StringProcessing(); mDatabaseAdapter = new DatabaseAdapter(this); Bundle intentExtras = getIntent().getExtras(); if(intentExtras != null && intentExtras.containsKey(Constants.KEY_HIGHLIGHT)) { highlightID = intentExtras.getString(Constants.KEY_HIGHLIGHT); } type = getType(intentExtras); } protected int getType(Bundle intentExtras) { return 0; } protected Entry getListCurrentWeek(int j) { Entry templist = new Entry(); templist.id = mSubList.get(j).id; templist.deleted = mSubList.get(j).deleted; templist.myHash = mSubList.get(j).myHash; templist.fileToDownload = mSubList.get(j).fileToDownload; templist.fileUploaded = mSubList.get(j).fileUploaded; templist.timeInMillis = mSubList.get(j).timeInMillis; if (mSubList.get(j).description != null && !mSubList.get(j).description.equals("")) { templist.description = mSubList.get(j).description; } else { CheckEntryComplete mCheckEntryComplete = new CheckEntryComplete(); if (mSubList.get(j).type.equals(getString(R.string.camera))) { if(mCheckEntryComplete.isEntryComplete(mSubList.get(j),this)) { templist.description = getString(R.string.finished_cameraentry); } else { templist.description = getString(R.string.unfinished_cameraentry); } } else if (mSubList.get(j).type.equals(getString(R.string.voice))) { if(mCheckEntryComplete.isEntryComplete(mSubList.get(j),this)) { templist.description = getString(R.string.finished_voiceentry); } else { templist.description = getString(R.string.unfinished_voiceentry); } } else if (mSubList.get(j).type.equals(getString(R.string.text))) { if(mCheckEntryComplete.isEntryComplete(mSubList.get(j),this)) { templist.description = getString(R.string.finished_textentry); } else { templist.description = getString(R.string.unfinished_textentry); } } else if (mSubList.get(j).type.equals(getString(R.string.favorite_entry))) { templist.description = "Unfinished Favorite Entry"; } else if (mSubList.get(j).type.equals(getString(R.string.unknown))) { templist.description = getString(R.string.unknown_entry); } } if (mSubList.get(j).amount != null&& !mSubList.get(j).amount.equals("")) { templist.amount = mStringProcessing.getStringDoubleDecimal(mSubList.get(j).amount); } else { templist.amount = "?"; } if (mSubList.get(j).favorite != null && !mSubList.get(j).favorite.equals("")) { templist.favorite = mSubList.get(j).favorite; } else { templist.favorite = ""; } if (mSubList.get(j).type != null && !mSubList.get(j).type.equals("")) { templist.type = mSubList.get(j).type; } else { templist.type = ""; } if(Strings.isEmpty(mSubList.get(j).idFromServer)) { templist.idFromServer = ""; } else { templist.idFromServer = mSubList.get(j).idFromServer; } if(Strings.isEmpty(mSubList.get(j).syncBit)) { templist.syncBit = ""; } else { templist.syncBit = mSubList.get(j).syncBit; } if(Strings.isEmpty(mSubList.get(j).updatedAt)) { templist.updatedAt = ""; } else { templist.updatedAt = mSubList.get(j).updatedAt; } if(Strings.isEmpty(mSubList.get(j).fileUpdatedAt)) { templist.fileUpdatedAt = ""; } else { templist.fileUpdatedAt = mSubList.get(j).fileUpdatedAt; } if(Strings.isEmpty(mSubList.get(j).location)) { templist.location = ""; } else { templist.location = mSubList.get(j).location; } return templist; } @Override public void onItemClick(final AdapterView<?> adapter, View v,final int position, long arg3) { final Entry mTempClickedList = (Entry) adapter.getItemAtPosition(position); String id = mTempClickedList.id; if (!id.contains(",")) { Bundle bundle = new Bundle(); bundle.putParcelable(Constants.KEY_ENTRY_LIST_EXTRA, mTempClickedList); bundle.putInt(Constants.KEY_POSITION, position); CheckEntryComplete mCheckEntryComplete = new CheckEntryComplete(); if (mTempClickedList.type.equals(getString(R.string.unknown))) { unknownDialog = new UnknownEntryDialog(this,mTempClickedList,new OnClickListener() { @Override public void onClick(View v) { DatabaseAdapter mDatabaseAdapter = new DatabaseAdapter(ListingAbstract.this); mDatabaseAdapter.open(); mDatabaseAdapter.deleteExpenseEntryByID(mTempClickedList.id); mDatabaseAdapter.close(); unknownDialog.dismiss(); unknownDialogAction(mTempClickedList.id); Toast.makeText(ListingAbstract.this, "Deleted", Toast.LENGTH_SHORT).show(); } }); } else { Intent intent = null; if (mTempClickedList.type.equals(getString(R.string.camera))) { if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { if(!mCheckEntryComplete.isEntryComplete(mTempClickedList,this)) { intent = new Intent(this,CameraEntry.class); } else { intent = new Intent(this,ShowCamera.class); } } else { Toast.makeText(this, "sdcard not available",Toast.LENGTH_SHORT).show(); } } else if (mTempClickedList.type.equals(getString(R.string.text))) { if(!mCheckEntryComplete.isEntryComplete(mTempClickedList,this)) { intent = new Intent(this, Text.class); } else { intent = new Intent(this,ShowText.class); } } else if (mTempClickedList.type.equals(getString(R.string.voice))) { if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { if(!mCheckEntryComplete.isEntryComplete(mTempClickedList,this)) { intent = new Intent(this, Voice.class); } else { intent = new Intent(this,ShowVoice.class); } } else { Toast.makeText(this, "sdcard not available", Toast.LENGTH_SHORT).show(); } } if(intent != null) { intent.putExtras(bundle); startActivityForResult(intent,RESULT); } } } else { onClickElse(mTempClickedList,position); } } protected void doOperationsOnListview() { mListView = (ListView) findViewById(R.id.expense_listing_listview); mListView.setOnItemClickListener(this); mListView.setAdapter(mSeparatedListAdapter); noItemLayout(); registerForContextMenu(mListView); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { AdapterView.AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; if(new DateHelper(mDataDateList.get(Integer.parseInt(mSeparatedListAdapter.getSectionNumber(info.position))).dateTime).isCurrentWeek()) { super.onCreateContextMenu(menu, v, menuInfo); switch (v.getId()) { case R.id.expense_listing_listview: String[] menuItems = getResources().getStringArray(R.array.listcontextmenu); for (int i = 0; i<menuItems.length; i++) { menu.add(Menu.NONE, i, i, menuItems[i]); } break; default: break; } } } @Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); switch (item.getItemId()) { //Edit Action case 0: FlurryAgent.onEvent(getString(R.string.editing_using_context_menu)); startEditPage(info.position); break; //Delete Action case 1: FlurryAgent.onEvent(getString(R.string.deleting_using_context_menu)); Toast.makeText(this, "Deleted", Toast.LENGTH_SHORT).show(); removeItem(info.position); ExpenseListing.resetUnfinishedEntryCount(); SyncHelper.startSync(); break; default: break; } return super.onContextItemSelected(item); } private void removeItem(int position) { Entry tempEntry = ((Entry)mSeparatedListAdapter.getItem(position)); mDatabaseAdapter.open(); // if(Strings.isEmpty(tempEntry.updatedAt)) { // mDatabaseAdapter.permanentDeleteEntryTableEntryID(tempEntry.id); // } else { mDatabaseAdapter.deleteExpenseEntryByID(tempEntry.id); // } mDatabaseAdapter.close(); //XXX if(!mSeparatedListAdapter.remove(position)) { initListView(); return; } setModifiedValues(); noItemLayout(); } private void startEditPage(int position) { Entry mTempClickedList = (Entry) mSeparatedListAdapter.getItem(position); Intent intent = null; Bundle bundle = new Bundle(); bundle.putParcelable(Constants.KEY_ENTRY_LIST_EXTRA, mTempClickedList); bundle.putInt(Constants.KEY_POSITION, position); if (mTempClickedList.type.equals(getString(R.string.text))) { intent = new Intent(this, Text.class); } else { if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { if (mTempClickedList.type.equals(getString(R.string.camera))) { intent = new Intent(this, CameraEntry.class); } else if (mTempClickedList.type.equals(getString(R.string.voice))) { intent = new Intent(this, Voice.class); } } else { Toast.makeText(this, "sdcard not available",Toast.LENGTH_SHORT).show(); } } if(intent != null) { intent.putExtras(bundle); startActivityForResult(intent,RESULT); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (RESULT == requestCode) { if(data != null && data.getExtras() != null){ intentExtras = data.getExtras(); } else { intentExtras = null; } if(Activity.RESULT_OK == resultCode) { if(intentExtras != null && intentExtras.containsKey(Constants.KEY_DATA_CHANGED)) { updateListView(intentExtras); intentExtras.remove(Constants.KEY_DATA_CHANGED); } else { initListView(); } } else if(Activity.RESULT_CANCELED == resultCode) { int position = -1; if(intentExtras != null && intentExtras.containsKey(Constants.KEY_POSITION)) { position = intentExtras.getInt(Constants.KEY_POSITION); } if(position != -1) { removeItem(position); } else { initListView(); } } } } protected void updateListView(Bundle bundle) { Entry updatedEntry = bundle.getParcelable(Constants.KEY_ENTRY_LIST_EXTRA); int position = -1; if(bundle.containsKey(Constants.KEY_POSITION)) {position = bundle.getInt(Constants.KEY_POSITION);} Log.d("************************"); Log.d("updating "+position); Log.d("************************"); if(position != -1) { String sectionNumber = mSeparatedListAdapter.getSectionNumber(position); Object prevEntry = mSeparatedListAdapter.getItem(position); if(sectionNumber != null && !sectionNumber.equals("") && prevEntry != null && !prevEntry.equals("")) { try{ mSeparatedListAdapter.update(updatedEntry, position, sectionNumber, (Entry) prevEntry); } catch (Exception e) { //XXX dont want to do this but sometimes it throwing error // initListView(); } } else { initListView(); } noItemLayout(); } } @SuppressWarnings("unchecked") protected void addSections() { int j = 0; List<ListDatetimeAmount> dateListToSend = new ArrayList<ListDatetimeAmount>(); int sectionNum = 0; @SuppressWarnings("rawtypes") List listString = new ArrayList<List<Entry>>(); for (int i = 0; i < mDataDateList.size(); i++) { List<Entry> mList = new ArrayList<Entry>(); String date = mDataDateList.get(i).dateTime; if(j < mSubList.size()) { Calendar toCHeckCal = Calendar.getInstance(); toCHeckCal.setTimeInMillis(mSubList.get(j).timeInMillis); toCHeckCal.setFirstDayOfWeek(Calendar.MONDAY); while (j < mSubList.size() && date.equals(new DisplayDate(toCHeckCal).getHeaderFooterListDisplayDate(type))) { Entry templist = new Entry(); Calendar mCalendar = Calendar.getInstance(); mCalendar.setTimeInMillis(mSubList.get(j).timeInMillis); mCalendar.set(mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH),0,0,0); mCalendar.setFirstDayOfWeek(Calendar.MONDAY); DisplayDate mDisplayDate = new DisplayDate(mCalendar); if(!condition(mDisplayDate)) { j = mSubList.size() + 1; break; } if (type == R.string.sublist_thisweek) { templist = getListCurrentWeek(j); mList.add(templist); j++; if (j < mSubList.size()) { toCHeckCal.setTimeInMillis(mSubList.get(j).timeInMillis); toCHeckCal.setFirstDayOfWeek(Calendar.MONDAY); } else { break; } } else if (type == R.string.sublist_thismonth || type == R.string.sublist_thisyear || type == R.string.sublist_all) { toCHeckCal.setTimeInMillis(mSubList.get(j).timeInMillis); toCHeckCal.setFirstDayOfWeek(Calendar.MONDAY); while (mDataDateList.get(i).dateTime.equals(new DisplayDate(toCHeckCal).getHeaderFooterListDisplayDate(type))) { ////// Adding i+" "+j as id Entry mTempSubList = new Entry(); mTempSubList.id = mSubList.get(j).id +","; ///// Adding tag Calendar tempCalendar = Calendar.getInstance(); tempCalendar.setTimeInMillis(mSubList.get(j).timeInMillis); tempCalendar.set(tempCalendar.get(Calendar.YEAR), tempCalendar.get(Calendar.MONTH), tempCalendar.get(Calendar.DAY_OF_MONTH),0,0,0); tempCalendar.setFirstDayOfWeek(Calendar.MONDAY); mDisplayDate = new DisplayDate(tempCalendar); DisplayDate tempDisplayDate = new DisplayDate(tempCalendar); int isWeekOfMonth = tempCalendar.get(Calendar.WEEK_OF_MONTH); int isCurrentMonth = tempCalendar.get(Calendar.MONTH); int isCurrentYear = tempCalendar.get(Calendar.YEAR); mTempSubList.description = tempDisplayDate.getSubListTag(type); ///// Adding Amount double temptotalAmount = 0; String totalAmountString = null; boolean isTempAmountNull = false; do { String tempAmount = mSubList.get(j).amount; if (tempAmount != null && !tempAmount.equals("")) { try { temptotalAmount += Double.parseDouble(tempAmount); } catch (NumberFormatException e) { e.printStackTrace(); } } else { isTempAmountNull = true; } j++; if (j < mSubList.size()) { toCHeckCal.setTimeInMillis(mSubList.get(j).timeInMillis); toCHeckCal.setFirstDayOfWeek(Calendar.MONDAY); tempCalendar.setTimeInMillis(mSubList.get(j).timeInMillis); tempCalendar.set(tempCalendar.get(Calendar.YEAR), tempCalendar.get(Calendar.MONTH), tempCalendar.get(Calendar.DAY_OF_MONTH),0,0,0); tempCalendar.setFirstDayOfWeek(Calendar.MONDAY); tempDisplayDate = new DisplayDate(tempCalendar); if(getLoopCondition(tempCalendar,isWeekOfMonth,isCurrentMonth,isCurrentYear)) { mTempSubList.id = mTempSubList.id + mSubList.get(j).id+","; } } else { break; } } while (getLoopCondition(tempCalendar,isWeekOfMonth,isCurrentMonth,isCurrentYear)); if (isTempAmountNull) { if (temptotalAmount != 0) { totalAmountString = temptotalAmount + " ?"; } else { totalAmountString = "?"; } } else { totalAmountString = temptotalAmount + ""; } mTempSubList.amount = mStringProcessing.getStringDoubleDecimal(totalAmountString); mTempSubList.type = getString(type); mTempSubList.timeInMillis = 0L; mTempSubList.deleted = false; mTempSubList.fileToDownload = false; mTempSubList.fileUpdatedAt = ""; mTempSubList.fileUploaded = false; mTempSubList.idFromServer = ""; mTempSubList.myHash = ""; mTempSubList.syncBit = ""; mTempSubList.updatedAt = ""; if(highlightID != null) { if (j <= mSubList.size()) { if(mTempSubList.id.contains(highlightID)) { startSubListing(mTempSubList); } } } mList.add(mTempSubList); if (j == mSubList.size()) { break; } } } } } else { break; } listString.add(mList); @SuppressWarnings("rawtypes") List tt = (List) listString.get(i); if(tt.size() > 0) { int temp = i; if(i == 0 && !new DisplayDate(mSubList.get(0).timeInMillis).isCurrentWeek()) {temp++;} dateListToSend.add(mDataDateList.get(temp)); Log.d("************ Amount ***************** "+temp); Log.d("mDataDateList "+mDataDateList.get(temp).amount); mSeparatedListAdapter.addSection(sectionNum + "", new ArrayAdapter<Entry>(this, R.layout.expense_listing_tab, tt), dateListToSend); sectionNum++; } } doOperationsOnListview(); } protected void startSubListing(Entry entry) { ArrayList<String> mArrayList = new GetArrayListFromString().getListFromTextArea(entry.id); for(int checkI=0; checkI<mArrayList.size(); checkI++) { if(mArrayList.get(checkI).equals(highlightID)) { Intent expenseSubListing = new Intent(this, ExpenseSubListing.class); Bundle extras = new Bundle(); extras.putParcelable(Constants.KEY_ENTRY_LIST_EXTRA, entry); extras.putInt(Constants.KEY_TYPE, getSubListType()); if(highlightID != null) extras.putString(Constants.KEY_HIGHLIGHT, highlightID); expenseSubListing.putExtras(extras); startActivityForResult(expenseSubListing, RESULT); finish(); } } } protected int getSubListType() { switch (type) { case R.string.sublist_all: return R.string.sublist_thisyear; case R.string.sublist_thismonth: return R.string.sublist_thisweek; case R.string.sublist_thisyear: return R.string.sublist_thismonth; default: return R.string.sublist_thisweek; } } protected boolean getLoopCondition(Calendar tempCalendar, int isWeekOfMonth, int isCurrentMonth, int isCurrentYear) { switch (type) { case R.string.sublist_all: return tempCalendar.get(Calendar.YEAR) == isCurrentYear; case R.string.sublist_thismonth: case R.string.sublist_thisweek: return tempCalendar.get(Calendar.WEEK_OF_MONTH) == isWeekOfMonth && tempCalendar.get(Calendar.MONTH) == isCurrentMonth && tempCalendar.get(Calendar.YEAR) == isCurrentYear; case R.string.sublist_thisyear: return tempCalendar.get(Calendar.MONTH) == isCurrentMonth && tempCalendar.get(Calendar.YEAR) == isCurrentYear; default: return false; } } protected void onClickElse(Entry entry,int position) { Intent mSubListIntent = new Intent(this, ExpenseSubListing.class); Bundle extras = new Bundle(); extras.putParcelable(Constants.KEY_ENTRY_LIST_EXTRA, entry); extras.putInt(Constants.KEY_POSITION, position); extras.putInt(Constants.KEY_TYPE, getSubListType()); mSubListIntent.putExtras(extras); startActivityForResult(mSubListIntent,RESULT); } protected abstract void unknownDialogAction(String id); protected abstract void noItemButtonAction(Button noItemButton); protected abstract void noItemLayout(); protected abstract void setContentView(); protected abstract boolean condition(DisplayDate mDisplayDate); protected abstract void initListView(); protected abstract void setModifiedValues(); }