1 /*******************************************************
2   This program is free software; you can redistribute it and/or modify
3  it under the terms of the GNU General Public License as published by
4  the Free Software Foundation; either version 2 of the License, or
5  (at your option) any later version.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  ********************************************************/
16 
17 #include "assetdialog.h"
18 #include "attachmentdialog.h"
19 #include "constants.h"
20 #include "mmSimpleDialogs.h"
21 #include "mmtextctrl.h"
22 #include "paths.h"
23 #include "util.h"
24 #include "validators.h"
25 
26 #include "model/Model_Attachment.h"
27 
28 #include "../resources/attachment.xpm"
29 
30 #include <wx/valnum.h>
31 
32 wxIMPLEMENT_DYNAMIC_CLASS(mmAssetDialog, wxDialog);
33 
wxBEGIN_EVENT_TABLE(mmAssetDialog,wxDialog)34 wxBEGIN_EVENT_TABLE( mmAssetDialog, wxDialog )
35     EVT_BUTTON(wxID_OK, mmAssetDialog::OnOk)
36     EVT_BUTTON(wxID_CANCEL, mmAssetDialog::OnCancel)
37 	EVT_BUTTON(wxID_FILE, mmAssetDialog::OnAttachments)
38     EVT_CHOICE(IDC_COMBO_TYPE, mmAssetDialog::OnChangeAppreciationType)
39     EVT_CHILD_FOCUS(mmAssetDialog::changeFocus)
40     EVT_CLOSE(mmAssetDialog::OnQuit)
41 wxEND_EVENT_TABLE()
42 
43 mmAssetDialog::mmAssetDialog(wxWindow* parent, Model_Asset::Data* asset)
44     : m_asset(asset)
45     , m_assetName()
46     , m_dpc()
47     , m_notes()
48     , m_value()
49     , m_valueChangeRate()
50     , m_assetType()
51     , m_valueChange()
52     , m_valueChangeRateLabel()
53 {
54     long style = wxCAPTION | wxSYSTEM_MENU | wxCLOSE_BOX;
55     Create(parent, wxID_ANY, _("New/Edit Asset"), wxDefaultPosition, wxSize(400, 300), style);
56 }
57 
Create(wxWindow * parent,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)58 bool mmAssetDialog::Create(wxWindow* parent
59     , wxWindowID id
60     , const wxString& caption
61     , const wxPoint& pos
62     , const wxSize& size
63     , long style)
64 {
65     SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS);
66 
67     if (!wxDialog::Create(parent, id, caption, pos, size, style))
68         return false;
69 
70     CreateControls();
71     dataToControls();
72     GetSizer()->Fit(this);
73     this->SetInitialSize();
74     GetSizer()->SetSizeHints(this);
75     SetIcon(mmex::getProgramIcon());
76     Centre();
77     return true;
78 }
79 
dataToControls()80 void mmAssetDialog::dataToControls()
81 {
82     if (!this->m_asset) return;
83 
84     m_assetName->SetValue(m_asset->ASSETNAME);
85     m_notes->SetValue(m_asset->NOTES);
86     m_dpc->SetValue(Model_Asset::STARTDATE(m_asset));
87     m_value->SetValue(m_asset->VALUE);
88 
89     m_valueChangeRate->SetValue(m_asset->VALUECHANGERATE, 3);
90 
91     m_valueChange->SetSelection(Model_Asset::rate(m_asset));
92     enableDisableRate(Model_Asset::rate(m_asset) != Model_Asset::RATE_NONE);
93     m_assetType->SetSelection(Model_Asset::type(m_asset));
94 }
95 
CreateControls()96 void mmAssetDialog::CreateControls()
97 {
98     wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
99     this->SetSizer(itemBoxSizer2);
100 
101     wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL);
102     itemBoxSizer2->Add(itemBoxSizer3, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
103 
104     wxStaticBox* itemStaticBoxSizer4Static = new wxStaticBox(this, wxID_ANY, _("Asset Details"));
105     wxStaticBoxSizer* itemStaticBoxSizer4 = new wxStaticBoxSizer(itemStaticBoxSizer4Static
106         , wxVERTICAL);
107     itemBoxSizer3->Add(itemStaticBoxSizer4, g_flags);
108 
109     wxPanel* itemPanel5 = new wxPanel( this, wxID_STATIC, wxDefaultPosition
110         , wxDefaultSize, wxTAB_TRAVERSAL );
111     itemStaticBoxSizer4->Add(itemPanel5, g_flags);
112 
113     wxFlexGridSizer* itemFlexGridSizer6 = new wxFlexGridSizer(0, 2, 0, 0);
114     itemPanel5->SetSizer(itemFlexGridSizer6);
115 
116     wxStaticText* n = new wxStaticText(itemPanel5, wxID_STATIC, _("Name"));
117     itemFlexGridSizer6->Add(n, g_flags);
118     n->SetFont(this->GetFont().Bold());
119 
120     m_assetName = new mmTextCtrl(itemPanel5, wxID_ANY, wxGetEmptyString());
121     m_assetName->SetToolTip(_("Enter the name of the asset"));
122     itemFlexGridSizer6->Add(m_assetName, g_flagsExpand);
123 
124     itemFlexGridSizer6->Add(new wxStaticText(itemPanel5, wxID_STATIC, _("Date")), g_flags);
125 
126     m_dpc = new wxDatePickerCtrl( itemPanel5, wxID_ANY, wxDefaultDateTime,
127               wxDefaultPosition, wxSize(150, -1), wxDP_DROPDOWN|wxDP_SHOWCENTURY);
128     itemFlexGridSizer6->Add(m_dpc, g_flags);
129     m_dpc->SetToolTip(_("Specify the date of purchase of asset"));
130 
131     itemFlexGridSizer6->Add(new wxStaticText(itemPanel5, wxID_STATIC, _("Asset Type")), g_flags);
132 
133     m_assetType = new wxChoice(itemPanel5, wxID_STATIC, wxDefaultPosition, wxSize(150, -1));
134     for (const auto& a : Model_Asset::all_type())
135         m_assetType->Append(wxGetTranslation(a), new wxStringClientData(a));
136 
137     m_assetType->SetToolTip(_("Select type of asset"));
138     m_assetType->SetSelection(Model_Asset::TYPE_PROPERTY);
139     itemFlexGridSizer6->Add(m_assetType, 0,
140         wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
141 
142     wxStaticText* v = new wxStaticText(itemPanel5, wxID_STATIC, _("Value"));
143     itemFlexGridSizer6->Add(v, g_flags);
144     v->SetFont(this->GetFont().Bold());
145 
146     m_value = new mmTextCtrl(itemPanel5, IDC_VALUE, wxGetEmptyString()
147         , wxDefaultPosition, wxSize(150,-1), wxALIGN_RIGHT|wxTE_PROCESS_ENTER
148         , mmCalcValidator() );
149     m_value->SetToolTip(_("Enter the current value of the asset"));
150     itemFlexGridSizer6->Add(m_value, g_flags);
151     m_value->Connect(IDC_VALUE, wxEVT_COMMAND_TEXT_ENTER
152         , wxCommandEventHandler(mmAssetDialog::onTextEntered), nullptr, this);
153 
154     itemFlexGridSizer6->Add(new wxStaticText(itemPanel5, wxID_STATIC, _("Change in Value")), g_flags);
155 
156     m_valueChange = new wxChoice(itemPanel5, IDC_COMBO_TYPE, wxDefaultPosition, wxSize(150, -1));
157     for(const auto& a : Model_Asset::all_rate())
158         m_valueChange->Append(wxGetTranslation(a));
159 
160     m_valueChange->SetToolTip(_("Specify if the value of the asset changes over time"));
161     m_valueChange->SetSelection(Model_Asset::RATE_NONE);
162     itemFlexGridSizer6->Add(m_valueChange, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
163 
164     m_valueChangeRateLabel = new wxStaticText( itemPanel5, wxID_STATIC, _("% Rate"));
165     itemFlexGridSizer6->Add(m_valueChangeRateLabel, g_flags);
166 
167     m_valueChangeRate = new mmTextCtrl(itemPanel5, IDC_RATE, wxGetEmptyString()
168         , wxDefaultPosition, wxSize(150,-1), wxALIGN_RIGHT|wxTE_PROCESS_ENTER
169         , mmCalcValidator());
170     m_valueChangeRate->SetToolTip(_("Enter the rate at which the asset changes its value in % per year"));
171     itemFlexGridSizer6->Add(m_valueChangeRate, g_flags);
172     m_valueChangeRate->Connect(IDC_RATE, wxEVT_COMMAND_TEXT_ENTER
173         , wxCommandEventHandler(mmAssetDialog::onTextEntered), nullptr, this);
174     enableDisableRate(false);
175 
176     itemFlexGridSizer6->Add(new wxStaticText( itemPanel5, wxID_STATIC, _("Notes")), g_flags);
177 
178 	bAttachments_ = new wxBitmapButton(itemPanel5, wxID_FILE
179 		, wxBitmap(attachment_xpm), wxDefaultPosition
180 		, wxSize(m_valueChange->GetSize().GetY(), m_valueChange->GetSize().GetY()));
181 	itemFlexGridSizer6->Add(bAttachments_, wxSizerFlags(g_flags).Align(wxALIGN_RIGHT));
182 	bAttachments_->SetToolTip(_("Organize attachments of this asset"));
183 
184     m_notes = new mmTextCtrl(this, IDC_NOTES, wxGetEmptyString(), wxDefaultPosition, wxSize(220, 170), wxTE_MULTILINE);
185     m_notes->SetToolTip(_("Enter notes associated with this asset"));
186     itemStaticBoxSizer4->Add(m_notes, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 10);
187 
188     wxPanel* itemPanel27 = new wxPanel(this, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
189     itemBoxSizer3->Add(itemPanel27, wxSizerFlags(g_flags).Center());
190 
191     wxBoxSizer* itemBoxSizer28 = new wxBoxSizer(wxHORIZONTAL);
192     itemPanel27->SetSizer(itemBoxSizer28);
193 
194     wxButton* itemButton29 = new wxButton(itemPanel27, wxID_OK, _("&OK "));
195     itemBoxSizer28->Add(itemButton29, g_flags);
196 
197     wxButton* itemButton30 = new wxButton(itemPanel27, wxID_CANCEL, wxGetTranslation(g_CancelLabel));
198     itemBoxSizer28->Add(itemButton30, g_flags);
199     itemButton30->SetFocus();
200 }
201 
OnChangeAppreciationType(wxCommandEvent &)202 void mmAssetDialog::OnChangeAppreciationType(wxCommandEvent& /*event*/)
203 {
204     int selection = m_valueChange->GetSelection();
205     // Disable for "None", Enable for "Appreciates" or "Depreciates"
206     enableDisableRate(selection != Model_Asset::RATE_NONE);
207 }
208 
enableDisableRate(bool en)209 void mmAssetDialog::enableDisableRate(bool en)
210 {
211     if (en)
212     {
213         m_valueChangeRate->SetEditable(true);
214         m_valueChangeRate->Enable(true);
215         m_valueChangeRateLabel->Enable(true);
216     }
217     else
218     {
219         //m_valueChangeRate->SetValue("0");
220         m_valueChangeRate->SetEditable(false);
221         m_valueChangeRate->Enable(false);
222         m_valueChangeRateLabel->Enable(false);
223     }
224 }
225 
OnOk(wxCommandEvent &)226 void mmAssetDialog::OnOk(wxCommandEvent& /*event*/)
227 {
228     const wxString name = m_assetName->GetValue().Trim();
229     if (name.empty()){
230         mmErrorDialogs::InvalidName(m_assetName);
231         return;
232     }
233 
234     double value = 0, valueChangeRate = 0;
235     if (!m_value->checkValue(value))
236     {
237         return;
238     }
239 
240     int valueChangeType = m_valueChange->GetSelection();
241     if (valueChangeType != Model_Asset::RATE_NONE && !m_valueChangeRate->checkValue(valueChangeRate))
242     {
243         return;
244     }
245 
246     wxString asset_type = "";
247     wxStringClientData* type_obj = (wxStringClientData *)m_assetType->GetClientObject(m_assetType->GetSelection());
248     if (type_obj) asset_type = type_obj->GetData();
249 
250     if (!this->m_asset) this->m_asset = Model_Asset::instance().create();
251 
252     m_asset->STARTDATE        = m_dpc->GetValue().FormatISODate();
253     m_asset->NOTES            = m_notes->GetValue().Trim();
254     m_asset->ASSETNAME        = name;
255     m_asset->VALUE            = value;
256     m_asset->VALUECHANGE      = Model_Asset::all_rate()[valueChangeType];
257     m_asset->VALUECHANGERATE  = valueChangeRate;
258     m_asset->ASSETTYPE        = asset_type;
259 
260 	int OldAssetId = m_asset->ASSETID;
261     int NewAssetId = Model_Asset::instance().save(m_asset);
262 
263 	if (OldAssetId < 0)
264 	{
265 		const wxString& RefType = Model_Attachment::reftype_desc(Model_Attachment::ASSET);
266 		mmAttachmentManage::RelocateAllAttachments(RefType, 0, NewAssetId);
267 	}
268 
269     EndModal(wxID_OK);
270 }
271 
OnCancel(wxCommandEvent &)272 void mmAssetDialog::OnCancel(wxCommandEvent& /*event*/)
273 {
274     if (assetRichText)
275         return;
276     else
277     {
278         const wxString& RefType = Model_Attachment::reftype_desc(Model_Attachment::ASSET);
279         if (!this->m_asset)
280             mmAttachmentManage::DeleteAllAttachments(RefType, 0);
281         EndModal(wxID_CANCEL);
282     }
283 }
284 
OnQuit(wxCloseEvent &)285 void mmAssetDialog::OnQuit(wxCloseEvent& /*event*/)
286 {
287     const wxString& RefType = Model_Attachment::reftype_desc(Model_Attachment::ASSET);
288     if (!this->m_asset)
289         mmAttachmentManage::DeleteAllAttachments(RefType, 0);
290     EndModal(wxID_CANCEL);
291 }
292 
OnAttachments(wxCommandEvent &)293 void mmAssetDialog::OnAttachments(wxCommandEvent& /*event*/)
294 {
295 	const wxString& RefType = Model_Attachment::reftype_desc(Model_Attachment::ASSET);
296 	int RefId;
297 
298 	if (!this->m_asset)
299 		RefId = 0;
300 	else
301 		RefId= m_asset->ASSETID;
302 
303 	mmAttachmentDialog dlg(this, RefType, RefId);
304 	dlg.ShowModal();
305 }
306 
changeFocus(wxChildFocusEvent & event)307 void mmAssetDialog::changeFocus(wxChildFocusEvent& event)
308 {
309     wxWindow *w = event.GetWindow();
310     if (w) assetRichText = (w->GetId() == IDC_NOTES ? true : false);
311 }
312 
onTextEntered(wxCommandEvent & event)313 void mmAssetDialog::onTextEntered(wxCommandEvent& event)
314 {
315     Model_Currency::Data *currency = Model_Currency::GetBaseCurrency();
316     if (event.GetId() == m_value->GetId())
317     {
318         m_value->Calculate(currency);
319     }
320     else if (event.GetId() == m_valueChangeRate->GetId())
321     {
322         m_valueChangeRate->Calculate(currency, 3);
323     }
324 
325     event.Skip();
326 }
327