1 /*******************************************************
2 Copyright (C) 2006 Madhan Kanagavel
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 ********************************************************/
18
19 #include "attachmentdialog.h"
20 #include "billsdepositspanel.h"
21 #include "billsdepositsdialog.h"
22 #include "constants.h"
23
24 #include "model/Model_Account.h"
25 #include "model/Model_Attachment.h"
26 #include "model/Model_Category.h"
27 #include "model/Model_Payee.h"
28 #include "model/Model_Setting.h"
29
30 #include "../resources/attachment.xpm"
31 #include "../resources/downarrow.xpm"
32 #include "../resources/error.xpm"
33 #include "../resources/rightarrow.xpm"
34 #include "../resources/rt_exec_auto.xpm"
35 #include "../resources/rt_exec_user.xpm"
36 #include "../resources/tipicon.xpm"
37 #include "../resources/uparrow.xpm"
38
39
40 enum
41 {
42 MENU_TREEPOPUP_NEW = wxID_HIGHEST + 1300,
43 MENU_TREEPOPUP_EDIT,
44 MENU_TREEPOPUP_DELETE,
45 MENU_POPUP_BD_ENTER_OCCUR,
46 MENU_POPUP_BD_SKIP_OCCUR,
47 MENU_TREEPOPUP_ORGANIZE_ATTACHMENTS,
48 };
49
50 const wxString BILLSDEPOSITS_REPEATS[] =
51 {
52 wxTRANSLATE("None"),
53 wxTRANSLATE("Weekly"),
54 wxTRANSLATE("Bi-Weekly"),
55 wxTRANSLATE("Monthly"),
56 wxTRANSLATE("Bi-Monthly"),
57 wxTRANSLATE("Quarterly"),
58 wxTRANSLATE("Half-Yearly"),
59 wxTRANSLATE("Yearly"),
60 wxTRANSLATE("Four Months"),
61 wxTRANSLATE("Four Weeks"),
62 wxTRANSLATE("Daily"),
63 wxTRANSLATE("In %s Days"),
64 wxTRANSLATE("In %s Months"),
65 wxTRANSLATE("Every %s Days"),
66 wxTRANSLATE("Every %s Months"),
67 wxTRANSLATE("Monthly (last day)"),
68 wxTRANSLATE("Monthly (last business day)")
69
70 };
71
72 /*******************************************************/
wxBEGIN_EVENT_TABLE(mmBillsDepositsPanel,wxPanel)73 wxBEGIN_EVENT_TABLE(mmBillsDepositsPanel, wxPanel)
74 EVT_BUTTON(wxID_NEW, mmBillsDepositsPanel::OnNewBDSeries)
75 EVT_BUTTON(wxID_EDIT, mmBillsDepositsPanel::OnEditBDSeries)
76 EVT_BUTTON(wxID_DELETE, mmBillsDepositsPanel::OnDeleteBDSeries)
77 EVT_BUTTON(wxID_PASTE, mmBillsDepositsPanel::OnEnterBDTransaction)
78 EVT_BUTTON(wxID_IGNORE, mmBillsDepositsPanel::OnSkipBDTransaction)
79 EVT_BUTTON(wxID_FILE, mmBillsDepositsPanel::OnOpenAttachment)
80 wxEND_EVENT_TABLE()
81 /*******************************************************/
82 wxBEGIN_EVENT_TABLE(billsDepositsListCtrl, mmListCtrl)
83 EVT_LIST_ITEM_ACTIVATED(wxID_ANY, billsDepositsListCtrl::OnListItemActivated)
84 EVT_RIGHT_DOWN(billsDepositsListCtrl::OnItemRightClick)
85 EVT_LEFT_DOWN(billsDepositsListCtrl::OnListLeftClick)
86 EVT_LIST_ITEM_SELECTED(wxID_ANY, billsDepositsListCtrl::OnListItemSelected)
87
88 EVT_MENU(MENU_TREEPOPUP_NEW, billsDepositsListCtrl::OnNewBDSeries)
89 EVT_MENU(MENU_TREEPOPUP_EDIT, billsDepositsListCtrl::OnEditBDSeries)
90 EVT_MENU(MENU_TREEPOPUP_DELETE, billsDepositsListCtrl::OnDeleteBDSeries)
91 EVT_MENU(MENU_POPUP_BD_ENTER_OCCUR, billsDepositsListCtrl::OnEnterBDTransaction)
92 EVT_MENU(MENU_POPUP_BD_SKIP_OCCUR, billsDepositsListCtrl::OnSkipBDTransaction)
93 EVT_MENU(MENU_TREEPOPUP_ORGANIZE_ATTACHMENTS, billsDepositsListCtrl::OnOrganizeAttachments)
94
95 EVT_LIST_KEY_DOWN(wxID_ANY, billsDepositsListCtrl::OnListKeyDown)
96 wxEND_EVENT_TABLE()
97 /*******************************************************/
98
99 billsDepositsListCtrl::billsDepositsListCtrl(mmBillsDepositsPanel* bdp, wxWindow *parent, wxWindowID winid)
100 : mmListCtrl(parent, winid)
101 , m_bdp(bdp)
102 {
103 // load the global variables
104 m_selected_col = Model_Setting::instance().GetIntSetting("BD_SORT_COL", m_bdp->col_sort());
105 m_asc = Model_Setting::instance().GetBoolSetting("BD_ASC", true);
106
107 m_columns.push_back(std::make_tuple(" ", 25, wxLIST_FORMAT_LEFT));
108 m_columns.push_back(std::make_tuple(_("ID"), wxLIST_AUTOSIZE, wxLIST_FORMAT_RIGHT));
109 m_columns.push_back(std::make_tuple(_("Payment Date"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
110 m_columns.push_back(std::make_tuple(_("Due Date"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
111 m_columns.push_back(std::make_tuple(_("Account"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
112 m_columns.push_back(std::make_tuple(_("Payee"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
113 m_columns.push_back(std::make_tuple(_("Status"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
114 m_columns.push_back(std::make_tuple(_("Category"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
115 m_columns.push_back(std::make_tuple(_("Type"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
116 m_columns.push_back(std::make_tuple(_("Amount"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_RIGHT));
117 m_columns.push_back(std::make_tuple(_("Frequency"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
118 m_columns.push_back(std::make_tuple(_("Repetitions"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
119 m_columns.push_back(std::make_tuple(_("Autorepeat"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
120 m_columns.push_back(std::make_tuple(_("Payment"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
121 m_columns.push_back(std::make_tuple(_("Number"), wxLIST_AUTOSIZE_USEHEADER, wxLIST_FORMAT_LEFT));
122 m_columns.push_back(std::make_tuple(_("Notes"), 150, wxLIST_FORMAT_LEFT));
123
124 m_col_width = "BD_COL%d_WIDTH";
125 m_default_sort_column = m_bdp->col_sort();
126 }
127
~billsDepositsListCtrl()128 billsDepositsListCtrl::~billsDepositsListCtrl()
129 {
130 }
131
OnColClick(wxListEvent & event)132 void billsDepositsListCtrl::OnColClick(wxListEvent& event)
133 {
134 int ColumnNr;
135 if (event.GetId() != MENU_HEADER_SORT)
136 ColumnNr = event.GetColumn();
137 else
138 ColumnNr = m_ColumnHeaderNbr;
139 if (0 > ColumnNr || ColumnNr >= m_bdp->getColumnsNumber() || ColumnNr == 0) return;
140
141 if (m_selected_col == ColumnNr && event.GetId() != MENU_HEADER_SORT) m_asc = !m_asc;
142
143 wxListItem item;
144 item.SetMask(wxLIST_MASK_IMAGE);
145 item.SetImage(-1);
146 SetColumn(m_selected_col, item);
147
148 m_selected_col = ColumnNr;
149
150 Model_Setting::instance().Set("BD_ASC", m_asc);
151 Model_Setting::instance().Set("BD_SORT_COL", m_selected_col);
152
153 if (m_selected_row >= 0)
154 refreshVisualList(m_bdp->initVirtualListControl(m_bdp->bills_[m_selected_row].BDID));
155 else
156 refreshVisualList(m_bdp->initVirtualListControl(-1));
157 }
158
mmBillsDepositsPanel(wxWindow * parent,wxWindowID winid,const wxPoint & pos,const wxSize & size,long style,const wxString & name)159 mmBillsDepositsPanel::mmBillsDepositsPanel(wxWindow *parent, wxWindowID winid
160 , const wxPoint& pos, const wxSize& size, long style, const wxString& name)
161 : m_imageList(nullptr)
162 , listCtrlAccount_(nullptr)
163 , transFilterDlg_(nullptr)
164 , bitmapTransFilter_(nullptr)
165 , m_infoTextMini(nullptr)
166 , m_infoText(nullptr)
167 {
168 this->tips_.Add(_("MMEX allows regular payments to be set up as transactions. These transactions can also be regular deposits, or transfers that will occur at some future time. These transactions act as a reminder that an event is about to occur, and appears on the Home Page 14 days before the transaction is due. "));
169 this->tips_.Add(_("Tip: These transactions can be set up to activate – allowing the user to adjust any values on the due date."));
170
171 Create(parent, winid, pos, size, style, name);
172 }
173
Create(wxWindow * parent,wxWindowID winid,const wxPoint & pos,const wxSize & size,long style,const wxString & name)174 bool mmBillsDepositsPanel::Create(wxWindow *parent
175 , wxWindowID winid, const wxPoint& pos
176 , const wxSize& size, long style, const wxString& name)
177 {
178 SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS);
179 wxPanel::Create(parent, winid, pos, size, style, name);
180
181 this->windowsFreezeThaw();
182
183 CreateControls();
184 GetSizer()->Fit(this);
185 GetSizer()->SetSizeHints(this);
186
187 /* Set up the transaction filter. The transFilter dialog will be destroyed
188 when the checking panel is destroyed. */
189 transFilterActive_ = false;
190 transFilterDlg_ = new mmFilterTransactionsDialog(this);
191
192 initVirtualListControl();
193
194 this->windowsFreezeThaw();
195
196 return TRUE;
197 }
198
~mmBillsDepositsPanel()199 mmBillsDepositsPanel::~mmBillsDepositsPanel()
200 {
201 if (m_imageList)
202 delete m_imageList;
203 if (transFilterDlg_)
204 delete transFilterDlg_;
205 }
206
CreateControls()207 void mmBillsDepositsPanel::CreateControls()
208 {
209 wxBoxSizer* itemBoxSizer9 = new wxBoxSizer(wxVERTICAL);
210 this->SetSizer(itemBoxSizer9);
211
212 /* ---------------------- */
213 wxPanel* headerPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition
214 , wxDefaultSize, wxNO_BORDER | wxTAB_TRAVERSAL);
215 itemBoxSizer9->Add(headerPanel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
216
217 wxBoxSizer* itemBoxSizerVHeader = new wxBoxSizer(wxVERTICAL);
218 headerPanel->SetSizer(itemBoxSizerVHeader);
219
220 wxStaticText* itemStaticText9 = new wxStaticText(headerPanel, wxID_ANY
221 , _("Recurring Transactions"));
222 itemStaticText9->SetFont(this->GetFont().Larger().Bold());
223 itemBoxSizerVHeader->Add(itemStaticText9, 0, wxALL, 1);
224
225 wxBoxSizer* itemBoxSizerHHeader2 = new wxBoxSizer(wxHORIZONTAL);
226 itemBoxSizerVHeader->Add(itemBoxSizerHHeader2);
227
228 wxBitmap itemStaticBitmap(rightarrow_xpm);
229 bitmapTransFilter_ = new wxStaticBitmap(headerPanel, wxID_ANY, itemStaticBitmap);
230 itemBoxSizerHHeader2->Add(bitmapTransFilter_, 0, wxALL, 1);
231 bitmapTransFilter_->Connect(wxID_ANY, wxEVT_LEFT_DOWN
232 , wxMouseEventHandler(mmBillsDepositsPanel::OnFilterTransactions), nullptr, this);
233 bitmapTransFilter_->Connect(wxID_ANY, wxEVT_RIGHT_DOWN
234 , wxMouseEventHandler(mmBillsDepositsPanel::OnFilterTransactions), nullptr, this);
235
236 itemBoxSizerHHeader2->AddSpacer(5);
237 wxStaticText* statTextTransFilter_ = new wxStaticText(headerPanel, wxID_ANY
238 , _("Transaction Filter"));
239 itemBoxSizerHHeader2->Add(statTextTransFilter_, 0, wxALIGN_CENTER_VERTICAL, 0);
240
241 /* ---------------------- */
242 wxSplitterWindow* itemSplitterWindowBillsDeposit = new wxSplitterWindow(this
243 , wxID_ANY, wxDefaultPosition, wxSize(200, 200)
244 , wxSP_3DBORDER | wxSP_3DSASH | wxNO_BORDER);
245
246 wxSize imageSize(16, 16);
247 m_imageList = new wxImageList(imageSize.GetWidth(), imageSize.GetHeight());
248 m_imageList->Add(wxBitmap(wxImage(error_xpm).Scale(16, 16)));
249 m_imageList->Add(wxBitmap(wxImage(rt_exec_auto_xpm).Scale(16, 16)));
250 m_imageList->Add(wxBitmap(wxImage(rt_exec_user_xpm).Scale(16, 16)));
251 m_imageList->Add(wxBitmap(wxImage(uparrow_xpm).Scale(16, 16)));
252 m_imageList->Add(wxBitmap(wxImage(downarrow_xpm).Scale(16, 16)));
253
254 listCtrlAccount_ = new billsDepositsListCtrl(this, itemSplitterWindowBillsDeposit);
255
256 listCtrlAccount_->SetImageList(m_imageList, wxIMAGE_LIST_SMALL);
257
258 int i = 0;
259 for (const auto& entry : listCtrlAccount_->m_columns)
260 {
261 const wxString& heading = std::get<0>(entry);
262 int width = Model_Setting::instance().GetIntSetting(wxString::Format(listCtrlAccount_->m_col_width, i), std::get<1>(entry));
263 int format = std::get<2>(entry);
264 listCtrlAccount_->InsertColumn(i++, heading, format, width);
265 }
266
267 wxPanel* bdPanel = new wxPanel(itemSplitterWindowBillsDeposit, wxID_ANY
268 , wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxTAB_TRAVERSAL);
269
270 itemSplitterWindowBillsDeposit->SplitHorizontally(listCtrlAccount_, bdPanel);
271 itemSplitterWindowBillsDeposit->SetMinimumPaneSize(100);
272 itemSplitterWindowBillsDeposit->SetSashGravity(1.0);
273 itemBoxSizer9->Add(itemSplitterWindowBillsDeposit, 1, wxGROW | wxALL, 1);
274
275 wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxVERTICAL);
276 bdPanel->SetSizer(itemBoxSizer4);
277
278 wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
279 itemBoxSizer4->Add(itemBoxSizer5, g_flags);
280
281 wxButton* itemButtonNew = new wxButton(bdPanel, wxID_NEW, _("&New "));
282 itemButtonNew->SetToolTip(_("New Bills & Deposit Series"));
283 itemBoxSizer5->Add(itemButtonNew, g_flags);
284
285 wxButton* itemButton81 = new wxButton(bdPanel, wxID_EDIT, _("&Edit "));
286 itemButton81->SetToolTip(_("Edit Bills & Deposit Series"));
287 itemBoxSizer5->Add(itemButton81, g_flags);
288 itemButton81->Enable(false);
289
290 wxButton* itemButton7 = new wxButton(bdPanel, wxID_DELETE, _("&Delete "));
291 itemButton7->SetToolTip(_("Delete Bills & Deposit Series"));
292 itemBoxSizer5->Add(itemButton7, g_flags);
293 itemButton7->Enable(false);
294
295 wxButton* itemButton8 = new wxButton(bdPanel, wxID_PASTE, _("En&ter"));
296 itemButton8->SetToolTip(_("Enter Next Bills & Deposit Occurrence"));
297 itemBoxSizer5->Add(itemButton8, g_flags);
298 itemButton8->Enable(false);
299
300 wxButton* buttonSkipTrans = new wxButton(bdPanel, wxID_IGNORE, _("&Skip"));
301 buttonSkipTrans->SetToolTip(_("Skip Next Bills & Deposit Occurrence"));
302 itemBoxSizer5->Add(buttonSkipTrans, g_flags);
303 buttonSkipTrans->Enable(false);
304
305 wxBitmapButton* btnAttachment_ = new wxBitmapButton(bdPanel, wxID_FILE
306 , wxBitmap(attachment_xpm), wxDefaultPosition
307 , wxSize(30, itemButton8->GetSize().GetY()));
308 btnAttachment_->SetToolTip(_("Open attachments"));
309 itemBoxSizer5->Add(btnAttachment_, g_flags);
310 btnAttachment_->Enable(false);
311
312 //Infobar-mini
313 m_infoTextMini = new wxStaticText(bdPanel, wxID_STATIC, "");
314 itemBoxSizer5->Add(m_infoTextMini, 1, wxGROW | wxTOP, 12);
315
316 //Infobar
317 m_infoText = new wxStaticText(bdPanel, wxID_ANY, ""
318 , wxPoint(-1, -1), wxSize(200, -1), wxNO_BORDER | wxTE_MULTILINE | wxTE_WORDWRAP | wxST_NO_AUTORESIZE);
319 itemBoxSizer4->Add(m_infoText, 1, wxGROW | wxLEFT | wxRIGHT, 14);
320
321 mmBillsDepositsPanel::updateBottomPanelData(-1);
322 }
323
initVirtualListControl(int id)324 int mmBillsDepositsPanel::initVirtualListControl(int id)
325 {
326 listCtrlAccount_->DeleteAllItems();
327
328 wxListItem item;
329 item.SetMask(wxLIST_MASK_IMAGE);
330 item.SetImage(listCtrlAccount_->m_asc ? 4 : 3);
331 listCtrlAccount_->SetColumn(listCtrlAccount_->m_selected_col, item);
332
333 bills_.clear();
334 const auto split = Model_Budgetsplittransaction::instance().get_all();
335 for (const Model_Billsdeposits::Data& data
336 : Model_Billsdeposits::instance().all(Model_Billsdeposits::COL_NEXTOCCURRENCEDATE))
337 {
338 if (transFilterActive_ && !transFilterDlg_->checkAll(data, split))
339 continue;
340
341 Model_Billsdeposits::Full_Data r(data);
342
343 if (Model_Attachment::NrAttachments(Model_Attachment::reftype_desc(Model_Attachment::BILLSDEPOSIT), r.BDID))
344 r.NOTES = r.NOTES.Prepend(mmAttachmentManage::GetAttachmentNoteSign());
345 bills_.push_back(r);
346 }
347
348 sortTable();
349
350 int cnt = 0, selected_item = -1;
351 for (const auto& entry: bills_)
352 {
353 if (id == entry.BDID)
354 {
355 selected_item = cnt;
356 break;
357 }
358 ++cnt;
359 }
360
361 listCtrlAccount_->SetItemCount(static_cast<long>(bills_.size()));
362 return selected_item;
363 }
364
OnNewBDSeries(wxCommandEvent & event)365 void mmBillsDepositsPanel::OnNewBDSeries(wxCommandEvent& event)
366 {
367 listCtrlAccount_->OnNewBDSeries(event);
368 }
369
OnEditBDSeries(wxCommandEvent & event)370 void mmBillsDepositsPanel::OnEditBDSeries(wxCommandEvent& event)
371 {
372 listCtrlAccount_->OnEditBDSeries(event);
373 }
374
OnDeleteBDSeries(wxCommandEvent & event)375 void mmBillsDepositsPanel::OnDeleteBDSeries(wxCommandEvent& event)
376 {
377 listCtrlAccount_->OnDeleteBDSeries(event);
378 }
379
OnEnterBDTransaction(wxCommandEvent & event)380 void mmBillsDepositsPanel::OnEnterBDTransaction(wxCommandEvent& event)
381 {
382 listCtrlAccount_->OnEnterBDTransaction(event);
383 }
384
OnSkipBDTransaction(wxCommandEvent & event)385 void mmBillsDepositsPanel::OnSkipBDTransaction(wxCommandEvent& event)
386 {
387 listCtrlAccount_->OnSkipBDTransaction(event);
388 listCtrlAccount_->SetFocus();
389 }
390
OnOpenAttachment(wxCommandEvent & event)391 void mmBillsDepositsPanel::OnOpenAttachment(wxCommandEvent& event)
392 {
393 listCtrlAccount_->OnOpenAttachment(event);
394 listCtrlAccount_->SetFocus();
395 }
396
397 /*******************************************************/
OnItemRightClick(wxMouseEvent & event)398 void billsDepositsListCtrl::OnItemRightClick(wxMouseEvent& event)
399 {
400 if (m_selected_row > -1)
401 SetItemState(m_selected_row, 0, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
402 int Flags = wxLIST_HITTEST_ONITEM;
403 m_selected_row = HitTest(wxPoint(event.m_x, event.m_y), Flags);
404
405 if (m_selected_row >= 0)
406 {
407 SetItemState(m_selected_row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
408 SetItemState(m_selected_row, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
409 }
410 m_bdp->updateBottomPanelData(m_selected_row);
411 bool item_active = (m_selected_row >= 0);
412 wxMenu menu;
413 menu.Append(MENU_POPUP_BD_ENTER_OCCUR, _("Enter next Occurrence..."));
414 menu.AppendSeparator();
415 menu.Append(MENU_POPUP_BD_SKIP_OCCUR, _("Skip next Occurrence"));
416 menu.AppendSeparator();
417 menu.Append(MENU_TREEPOPUP_NEW, _("&New Bills && Deposit Series..."));
418 menu.Append(MENU_TREEPOPUP_EDIT, _("&Edit Bills && Deposit Series..."));
419 menu.Append(MENU_TREEPOPUP_DELETE, _("&Delete Bills && Deposit Series..."));
420 menu.AppendSeparator();
421 menu.Append(MENU_TREEPOPUP_ORGANIZE_ATTACHMENTS, _("&Organize Attachments"));
422
423 menu.Enable(MENU_POPUP_BD_ENTER_OCCUR, item_active);
424 menu.Enable(MENU_POPUP_BD_SKIP_OCCUR, item_active);
425 menu.Enable(MENU_TREEPOPUP_EDIT, item_active);
426 menu.Enable(MENU_TREEPOPUP_DELETE, item_active);
427 menu.Enable(MENU_TREEPOPUP_ORGANIZE_ATTACHMENTS, item_active);
428
429 PopupMenu(&menu, event.GetPosition());
430 this->SetFocus();
431 }
432
getItem(long item,long column)433 wxString mmBillsDepositsPanel::getItem(long item, long column)
434 {
435 const Model_Billsdeposits::Full_Data& bill = this->bills_.at(item);
436 switch (column)
437 {
438 case COL_ID:
439 return wxString::Format("%i", bill.BDID).Trim();
440 case COL_PAYMENT_DATE:
441 return mmGetDateForDisplay(Model_Billsdeposits::NEXTOCCURRENCEDATE(bill));
442 case COL_DUE_DATE:
443 return mmGetDateForDisplay(Model_Billsdeposits::TRANSDATE(bill));
444 case COL_ACCOUNT:
445 return bill.ACCOUNTNAME;
446 case COL_PAYEE:
447 return bill.PAYEENAME;
448 case COL_STATUS:
449 return bill.STATUS;
450 case COL_CATEGORY:
451 return bill.CATEGNAME;
452 case COL_TYPE:
453 return wxGetTranslation(bill.TRANSCODE);
454 case COL_AMOUNT:
455 return Model_Account::toCurrency(bill.TRANSAMOUNT, Model_Account::instance().get(bill.ACCOUNTID));
456 case COL_FREQUENCY:
457 return GetFrequency(&bill);
458 case COL_REPEATS:
459 if (bill.NUMOCCURRENCES == -1)
460 return L"\x221E";
461 else
462 return wxString::Format("%i", bill.NUMOCCURRENCES).Trim();
463 case COL_AUTO:
464 {
465 int repeats = bill.REPEATS;
466 wxString repeatSTR = _("Manual");
467 if (repeats >= BD_REPEATS_MULTIPLEX_BASE)
468 {
469 repeats -= BD_REPEATS_MULTIPLEX_BASE;
470 repeatSTR = _("Suggested");
471 if (repeats >= BD_REPEATS_MULTIPLEX_BASE)
472 {
473 repeats -= BD_REPEATS_MULTIPLEX_BASE;
474 repeatSTR = _("Automated");
475 }
476 }
477 return repeatSTR;
478 }
479 case COL_DAYS:
480 return GetRemainingDays(&bill);
481 case COL_NUMBER:
482 return bill.TRANSACTIONNUMBER;
483 case COL_NOTES:
484 return bill.NOTES;
485 default:
486 return wxEmptyString;
487 }
488 }
489
GetFrequency(const Model_Billsdeposits::Data * item)490 wxString mmBillsDepositsPanel::GetFrequency(const Model_Billsdeposits::Data* item)
491 {
492 int repeats = item->REPEATS;
493 // DeMultiplex the Auto Executable fields.
494 if (repeats >= BD_REPEATS_MULTIPLEX_BASE) // Auto Execute User Acknowlegement required
495 repeats -= BD_REPEATS_MULTIPLEX_BASE;
496 if (repeats >= BD_REPEATS_MULTIPLEX_BASE) // Auto Execute Silent mode
497 repeats -= BD_REPEATS_MULTIPLEX_BASE;
498
499 wxString text = wxGetTranslation(BILLSDEPOSITS_REPEATS[repeats]);
500 if (repeats > 10 && repeats < 15)
501 text = wxString::Format(text, wxString::Format("%d", item->NUMOCCURRENCES));
502 return text;
503 }
504
GetRemainingDays(const Model_Billsdeposits::Data * item)505 wxString mmBillsDepositsPanel::GetRemainingDays(const Model_Billsdeposits::Data* item)
506 {
507 int repeats = item->REPEATS;
508 // DeMultiplex the Auto Executable fields.
509 if (repeats >= BD_REPEATS_MULTIPLEX_BASE) // Auto Execute User Acknowlegement required
510 repeats -= BD_REPEATS_MULTIPLEX_BASE;
511 if (repeats >= BD_REPEATS_MULTIPLEX_BASE) // Auto Execute Silent mode
512 repeats -= BD_REPEATS_MULTIPLEX_BASE;
513
514 int daysRemaining = Model_Billsdeposits::daysPayment(item);
515 int daysOverdue = Model_Billsdeposits::daysOverdue(item);
516 wxString text = wxString::Format(_("%d days remaining"), daysRemaining);
517
518 if (daysRemaining == 0)
519 {
520 if (((repeats > 10) && (repeats < 15)) && (item->NUMOCCURRENCES < 0))
521 text = _("Inactive");
522 }
523
524 if (daysRemaining < 0)
525 {
526 text = wxString::Format(_("%d days delay!"), abs(daysRemaining));
527 if (((repeats > 10) && (repeats < 15)) && (item->NUMOCCURRENCES < 0))
528 text = _("Inactive");
529 }
530
531 if (daysOverdue < 0)
532 {
533 text = wxString::Format(_("%d days overdue!"), abs(daysOverdue));
534 if (((repeats > 10) && (repeats < 15)) && (item->NUMOCCURRENCES < 0))
535 text = _("Inactive");
536 }
537
538 return text;
539 }
540
OnGetItemText(long item,long column) const541 wxString billsDepositsListCtrl::OnGetItemText(long item, long column) const
542 {
543 return m_bdp->getItem(item, column);
544 }
545
OnListItemSelected(wxListEvent & event)546 void billsDepositsListCtrl::OnListItemSelected(wxListEvent& event)
547 {
548 m_selected_row = event.GetIndex();
549 m_bdp->updateBottomPanelData(m_selected_row);
550 }
551
OnListLeftClick(wxMouseEvent & event)552 void billsDepositsListCtrl::OnListLeftClick(wxMouseEvent& event)
553 {
554 int Flags = wxLIST_HITTEST_ONITEM;
555 long index = HitTest(wxPoint(event.m_x, event.m_y), Flags);
556 if (index == -1)
557 {
558 m_selected_row = -1;
559 m_bdp->updateBottomPanelData(m_selected_row);
560 }
561 event.Skip();
562 }
563
OnGetItemImage(long item) const564 int billsDepositsListCtrl::OnGetItemImage(long item) const
565 {
566 bool bd_repeat_user = false;
567 bool bd_repeat_auto = false;
568 int repeats = m_bdp->bills_[item].REPEATS;
569 // DeMultiplex the Auto Executable fields.
570 if (repeats >= BD_REPEATS_MULTIPLEX_BASE) // Auto Execute User Acknowlegement required
571 {
572 repeats -= BD_REPEATS_MULTIPLEX_BASE;
573 bd_repeat_user = true;
574 }
575 if (repeats >= BD_REPEATS_MULTIPLEX_BASE) // Auto Execute Silent mode
576 {
577 repeats -= BD_REPEATS_MULTIPLEX_BASE;
578 bd_repeat_auto = true;
579 }
580
581 int daysRemaining = Model_Billsdeposits::daysPayment(&m_bdp->bills_[item]);
582 wxString daysRemainingStr = wxString::Format(_("%d days remaining"), daysRemaining);
583
584 if (daysRemaining == 0)
585 {
586 if (((repeats > 10) && (repeats < 15)) && (m_bdp->bills_[item].NUMOCCURRENCES < 0))
587 daysRemainingStr = _("Inactive");
588 }
589
590 if (daysRemaining < 0)
591 {
592 daysRemainingStr = wxString::Format(_("%d days overdue!"), abs(daysRemaining));
593 if (((repeats > 10) && (repeats < 15)) && (m_bdp->bills_[item].NUMOCCURRENCES < 0))
594 daysRemainingStr = _("Inactive");
595 }
596
597 /* Returns the icon to be shown for each entry */
598 if (daysRemainingStr == _("Inactive")) return -1;
599 if (daysRemaining < 0) return 0;
600 if (bd_repeat_auto) return 1;
601 if (bd_repeat_user) return 2;
602
603 return -1;
604 }
605
OnListKeyDown(wxListEvent & event)606 void billsDepositsListCtrl::OnListKeyDown(wxListEvent& event)
607 {
608 switch ( event.GetKeyCode() )
609 {
610 case WXK_DELETE:
611 {
612 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED,
613 MENU_TREEPOPUP_DELETE);
614 OnDeleteBDSeries(evt);
615 }
616 break;
617
618 default:
619 event.Skip();
620 }
621 }
622
OnNewBDSeries(wxCommandEvent &)623 void billsDepositsListCtrl::OnNewBDSeries(wxCommandEvent& /*event*/)
624 {
625 mmBDDialog dlg(this, 0, false, false);
626 if ( dlg.ShowModal() == wxID_OK )
627 refreshVisualList(m_bdp->initVirtualListControl(dlg.GetTransID()));
628 }
629
OnEditBDSeries(wxCommandEvent &)630 void billsDepositsListCtrl::OnEditBDSeries(wxCommandEvent& /*event*/)
631 {
632 if (m_selected_row == -1) return;
633
634 mmBDDialog dlg(this, m_bdp->bills_[m_selected_row].BDID, true, false);
635 if ( dlg.ShowModal() == wxID_OK )
636 refreshVisualList(m_bdp->initVirtualListControl(dlg.GetTransID()));
637 }
638
OnDeleteBDSeries(wxCommandEvent &)639 void billsDepositsListCtrl::OnDeleteBDSeries(wxCommandEvent& /*event*/)
640 {
641 if (m_selected_row < 0) return;
642 if (m_bdp->bills_.size() == 0) return;
643
644 wxMessageDialog msgDlg(this, _("Do you really want to delete the series?")
645 , _("Confirm Series Deletion")
646 , wxYES_NO | wxNO_DEFAULT | wxICON_ERROR);
647 if (msgDlg.ShowModal() == wxID_YES)
648 {
649 int BdId = m_bdp->bills_[m_selected_row].BDID;
650 Model_Billsdeposits::instance().remove(BdId);
651 mmAttachmentManage::DeleteAllAttachments(Model_Attachment::reftype_desc(Model_Attachment::BILLSDEPOSIT), BdId);
652 m_bdp->initVirtualListControl();
653 refreshVisualList(m_selected_row);
654 }
655 }
656
OnEnterBDTransaction(wxCommandEvent &)657 void billsDepositsListCtrl::OnEnterBDTransaction(wxCommandEvent& /*event*/)
658 {
659 if (m_selected_row == -1) return;
660
661 int id = m_bdp->bills_[m_selected_row].BDID;
662 mmBDDialog dlg(this, id, false, true);
663 if ( dlg.ShowModal() == wxID_OK )
664 refreshVisualList(m_bdp->initVirtualListControl(id));
665 }
666
OnSkipBDTransaction(wxCommandEvent &)667 void billsDepositsListCtrl::OnSkipBDTransaction(wxCommandEvent& /*event*/)
668 {
669 if (m_selected_row == -1) return;
670
671 int id = m_bdp->bills_[m_selected_row].BDID;
672 Model_Billsdeposits::instance().completeBDInSeries(id);
673 refreshVisualList(m_bdp->initVirtualListControl(id));
674 }
675
OnOrganizeAttachments(wxCommandEvent &)676 void billsDepositsListCtrl::OnOrganizeAttachments(wxCommandEvent& /*event*/)
677 {
678 if (m_selected_row == -1) return;
679
680 int RefId = m_bdp->bills_[m_selected_row].BDID;
681 const wxString& RefType = Model_Attachment::reftype_desc(Model_Attachment::BILLSDEPOSIT);
682
683 mmAttachmentDialog dlg(this, RefType, RefId);
684 dlg.ShowModal();
685
686 refreshVisualList(m_bdp->initVirtualListControl(RefId));
687 }
688
OnOpenAttachment(wxCommandEvent & event)689 void billsDepositsListCtrl::OnOpenAttachment(wxCommandEvent& event)
690 {
691 if (m_selected_row == -1) return;
692 int RefId = m_bdp->bills_[m_selected_row].BDID;
693 const wxString& RefType = Model_Attachment::reftype_desc(Model_Attachment::BILLSDEPOSIT);
694
695 mmAttachmentManage::OpenAttachmentFromPanelIcon(this, RefType, RefId);
696 refreshVisualList(m_bdp->initVirtualListControl(RefId));
697 }
698
OnListItemActivated(wxListEvent &)699 void billsDepositsListCtrl::OnListItemActivated(wxListEvent& /*event*/)
700 {
701 if (m_selected_row == -1) return;
702
703 mmBDDialog dlg(this, m_bdp->bills_[m_selected_row].BDID, true, false);
704 if ( dlg.ShowModal() == wxID_OK )
705 refreshVisualList(m_bdp->initVirtualListControl(dlg.GetTransID()));
706 }
707
updateBottomPanelData(int selIndex)708 void mmBillsDepositsPanel::updateBottomPanelData(int selIndex)
709 {
710 enableEditDeleteButtons(selIndex >= 0);
711 if (selIndex != -1)
712 {
713 m_infoTextMini->SetLabelText(Model_Category::full_name(bills_[selIndex].CATEGID, bills_[selIndex].SUBCATEGID));
714 m_infoText->SetLabelText(bills_[selIndex].NOTES);
715 }
716 }
717
enableEditDeleteButtons(bool en)718 void mmBillsDepositsPanel::enableEditDeleteButtons(bool en)
719 {
720 wxButton* bE = (wxButton*) FindWindow(wxID_EDIT);
721 wxButton* bD = (wxButton*) FindWindow(wxID_DELETE);
722 wxButton* bN = (wxButton*) FindWindow(wxID_PASTE);
723 wxButton* bS = (wxButton*) FindWindow(wxID_IGNORE);
724 wxButton* bA = (wxButton*)FindWindow(wxID_FILE);
725 if (bE) bE->Enable(en);
726 if (bD) bD->Enable(en);
727 if (bN) bN->Enable(en);
728 if (bS) bS->Enable(en);
729 if (bA) bA->Enable(en);
730
731 m_infoText->SetLabelText(this->tips());
732 m_infoTextMini->ClearBackground();
733 }
734
sortTable()735 void mmBillsDepositsPanel::sortTable()
736 {
737 std::sort(bills_.begin(), bills_.end());
738 switch (listCtrlAccount_->m_selected_col)
739 {
740 case COL_ID:
741 std::stable_sort(bills_.begin(), bills_.end(), SorterByBDID());
742 break;
743 case COL_PAYMENT_DATE:
744 std::stable_sort(bills_.begin(), bills_.end(), SorterByNEXTOCCURRENCEDATE());
745 break;
746 case COL_DUE_DATE:
747 std::stable_sort(bills_.begin(), bills_.end(), SorterByTRANSDATE());
748 break;
749 case COL_ACCOUNT:
750 std::stable_sort(bills_.begin(), bills_.end(), SorterByACCOUNTNAME());
751 break;
752 case COL_PAYEE:
753 std::stable_sort(bills_.begin(), bills_.end(), SorterByPAYEENAME());
754 break;
755 case COL_STATUS:
756 std::stable_sort(bills_.begin(), bills_.end(), SorterBySTATUS());
757 break;
758 case COL_CATEGORY:
759 std::stable_sort(bills_.begin(), bills_.end(), SorterByCATEGNAME());
760 break;
761 case COL_TYPE:
762 std::stable_sort(bills_.begin(), bills_.end(), SorterByTRANSCODE());
763 break;
764 case COL_AMOUNT:
765 std::stable_sort(bills_.begin(), bills_.end(), SorterByTRANSAMOUNT());
766 break;
767 case COL_FREQUENCY:
768 std::stable_sort(bills_.begin(), bills_.end()
769 , [&](const Model_Billsdeposits::Full_Data& x, const Model_Billsdeposits::Full_Data& y)
770 {
771 wxString x_text = this->GetFrequency(&x);
772 wxString y_text = this->GetFrequency(&y);
773 return x_text < y_text;
774 });
775 break;
776 case COL_REPEATS:
777 std::stable_sort(bills_.begin(), bills_.end(), SorterByREPEATS());
778 break;
779 case COL_DAYS:
780 std::stable_sort(bills_.begin(), bills_.end()
781 , [&](const Model_Billsdeposits::Data& x, const Model_Billsdeposits::Data& y)
782 {
783 bool x_useText = false;
784 wxString x_text = this->GetRemainingDays(&x);
785 long x_num = 0;
786 if (isdigit(x_text[0]))
787 {
788 x_num = wxAtoi(x_text);
789 wxString removed;
790 if (x_text.EndsWith(wxString("!"), &removed))
791 x_num = -x_num;
792 }
793 else
794 x_useText = true;
795
796 bool y_useText = false;
797 wxString y_text = this->GetRemainingDays(&y);
798 long y_num = 0;
799 if (isdigit(y_text[0]))
800 {
801 y_num = wxAtoi(y_text);
802 wxString removed;
803 if (y_text.EndsWith(wxString("!"), &removed))
804 y_num = -y_num;
805 }
806 else
807 y_useText = true;
808 return ((!x_useText && !y_useText) ? x_num < y_num : x_text < y_text);
809 });
810 break;
811 case COL_NOTES:
812 std::stable_sort(bills_.begin(), bills_.end(), SorterByNOTES());
813 break;
814 default:
815 break;
816 }
817 if (!listCtrlAccount_->m_asc) std::reverse(bills_.begin(), bills_.end());
818 }
819
tips()820 wxString mmBillsDepositsPanel::tips()
821 {
822 return this->tips_[rand() % this->tips_.GetCount()];
823 }
824
refreshVisualList(int selected_index)825 void billsDepositsListCtrl::refreshVisualList(int selected_index)
826 {
827
828 if (selected_index >= (long)m_bdp->bills_.size() || selected_index < 0)
829 selected_index = - 1;
830 if (!m_bdp->bills_.empty()) {
831 RefreshItems(0, m_bdp->bills_.size() - 1);
832 }
833 else
834 selected_index = -1;
835
836 if (selected_index >= 0 && !m_bdp->bills_.empty())
837 {
838 SetItemState(selected_index, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
839 SetItemState(selected_index, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
840 EnsureVisible(selected_index);
841 }
842 m_selected_row = selected_index;
843 m_bdp->updateBottomPanelData(selected_index);
844 }
845
RefreshList()846 void billsDepositsListCtrl::RefreshList()
847 {
848 if (m_bdp->bills_.size() == 0) return;
849 int id = -1;
850 if (m_selected_row != -1)
851 {
852 id = m_bdp->bills_[m_selected_row].BDID;
853 }
854 refreshVisualList(m_bdp->initVirtualListControl(id));
855 }
856
RefreshList()857 void mmBillsDepositsPanel::RefreshList()
858 {
859 listCtrlAccount_->RefreshList();
860 }
861
OnFilterTransactions(wxMouseEvent & event)862 void mmBillsDepositsPanel::OnFilterTransactions(wxMouseEvent& event)
863 {
864
865 int e = event.GetEventType();
866
867 wxBitmap bitmapFilterIcon(rightarrow_xpm);
868
869 if (e == wxEVT_LEFT_DOWN)
870 {
871
872 if (transFilterDlg_->ShowModal() == wxID_OK && transFilterDlg_->somethingSelected())
873 {
874 transFilterActive_ = true;
875 wxBitmap activeBitmapFilterIcon(tipicon_xpm);
876 bitmapFilterIcon = activeBitmapFilterIcon;
877 }
878 else
879 {
880 transFilterActive_ = false;
881 }
882
883 } else {
884 if (transFilterActive_ == false) return;
885 transFilterActive_ = false;
886 }
887
888 wxImage pic = bitmapFilterIcon.ConvertToImage();
889 bitmapTransFilter_->SetBitmap(pic);
890
891 initVirtualListControl();
892 }
893
BuildPage() const894 wxString mmBillsDepositsPanel::BuildPage() const
895 {
896 return listCtrlAccount_->BuildPage(_("Recurring Transactions"));
897 }