Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OTPayment.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * OTPayment.cpp
4  *
5  */
6 
7 /************************************************************
8  -----BEGIN PGP SIGNED MESSAGE-----
9  Hash: SHA1
10 
11  * OPEN TRANSACTIONS
12  *
13  * Financial Cryptography and Digital Cash
14  * Library, Protocol, API, Server, CLI, GUI
15  *
16  * -- Anonymous Numbered Accounts.
17  * -- Untraceable Digital Cash.
18  * -- Triple-Signed Receipts.
19  * -- Cheques, Vouchers, Transfers, Inboxes.
20  * -- Basket Currencies, Markets, Payment Plans.
21  * -- Signed, XML, Ricardian-style Contracts.
22  * -- Scripted smart contracts.
23  *
24  * Copyright (C) 2010-2013 by "Fellow Traveler" (A pseudonym)
25  *
26  * EMAIL:
28  *
29  * BITCOIN: 1NtTPVVjDsUfDWybS4BwvHpG2pdS9RnYyQ
30  *
31  * KEY FINGERPRINT (PGP Key in license file):
32  * 9DD5 90EB 9292 4B48 0484 7910 0308 00ED F951 BB8E
33  *
34  * OFFICIAL PROJECT WIKI(s):
35  * https://github.com/FellowTraveler/Moneychanger
36  * https://github.com/FellowTraveler/Open-Transactions/wiki
37  *
38  * WEBSITE:
39  * http://www.OpenTransactions.org/
40  *
41  * Components and licensing:
42  * -- Moneychanger..A Java client GUI.....LICENSE:.....GPLv3
43  * -- otlib.........A class library.......LICENSE:...LAGPLv3
44  * -- otapi.........A client API..........LICENSE:...LAGPLv3
45  * -- opentxs/ot....Command-line client...LICENSE:...LAGPLv3
46  * -- otserver......Server Application....LICENSE:....AGPLv3
47  * Github.com/FellowTraveler/Open-Transactions/wiki/Components
48  *
49  * All of the above OT components were designed and written by
50  * Fellow Traveler, with the exception of Moneychanger, which
51  * was contracted out to Vicky C ([email protected]).
52  * The open-source community has since actively contributed.
53  *
54  * -----------------------------------------------------
55  *
56  * LICENSE:
57  * This program is free software: you can redistribute it
58  * and/or modify it under the terms of the GNU Affero
59  * General Public License as published by the Free Software
60  * Foundation, either version 3 of the License, or (at your
61  * option) any later version.
62  *
63  * ADDITIONAL PERMISSION under the GNU Affero GPL version 3
64  * section 7: (This paragraph applies only to the LAGPLv3
65  * components listed above.) If you modify this Program, or
66  * any covered work, by linking or combining it with other
67  * code, such other code is not for that reason alone subject
68  * to any of the requirements of the GNU Affero GPL version 3.
69  * (==> This means if you are only using the OT API, then you
70  * don't have to open-source your code--only your changes to
71  * Open-Transactions itself must be open source. Similar to
72  * LGPLv3, except it applies to software-as-a-service, not
73  * just to distributing binaries.)
74  *
75  * Extra WAIVER for OpenSSL, Lucre, and all other libraries
76  * used by Open Transactions: This program is released under
77  * the AGPL with the additional exemption that compiling,
78  * linking, and/or using OpenSSL is allowed. The same is true
79  * for any other open source libraries included in this
80  * project: complete waiver from the AGPL is hereby granted to
81  * compile, link, and/or use them with Open-Transactions,
82  * according to their own terms, as long as the rest of the
83  * Open-Transactions terms remain respected, with regard to
84  * the Open-Transactions code itself.
85  *
86  * Lucre License:
87  * This code is also "dual-license", meaning that Ben Lau-
88  * rie's license must also be included and respected, since
89  * the code for Lucre is also included with Open Transactions.
90  * See Open-Transactions/src/otlib/lucre/LUCRE_LICENSE.txt
91  * The Laurie requirements are light, but if there is any
92  * problem with his license, simply remove the Lucre code.
93  * Although there are no other blind token algorithms in Open
94  * Transactions (yet. credlib is coming), the other functions
95  * will continue to operate.
96  * See Lucre on Github: https://github.com/benlaurie/lucre
97  * -----------------------------------------------------
98  * You should have received a copy of the GNU Affero General
99  * Public License along with this program. If not, see:
100  * http://www.gnu.org/licenses/
101  *
102  * If you would like to use this software outside of the free
103  * software license, please contact FellowTraveler.
104  * (Unfortunately many will run anonymously and untraceably,
105  * so who could really stop them?)
106  *
107  * DISCLAIMER:
108  * This program is distributed in the hope that it will be
109  * useful, but WITHOUT ANY WARRANTY; without even the implied
110  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
111  * PURPOSE. See the GNU Affero General Public License for
112  * more details.
113 
114  -----BEGIN PGP SIGNATURE-----
115  Version: GnuPG v1.4.9 (Darwin)
116 
117  iQIcBAEBAgAGBQJRSsfJAAoJEAMIAO35UbuOQT8P/RJbka8etf7wbxdHQNAY+2cC
118  vDf8J3X8VI+pwMqv6wgTVy17venMZJa4I4ikXD/MRyWV1XbTG0mBXk/7AZk7Rexk
119  KTvL/U1kWiez6+8XXLye+k2JNM6v7eej8xMrqEcO0ZArh/DsLoIn1y8p8qjBI7+m
120  aE7lhstDiD0z8mwRRLKFLN2IH5rAFaZZUvj5ERJaoYUKdn4c+RcQVei2YOl4T0FU
121  LWND3YLoH8naqJXkaOKEN4UfJINCwxhe5Ke9wyfLWLUO7NamRkWD2T7CJ0xocnD1
122  sjAzlVGNgaFDRflfIF4QhBx1Ddl6wwhJfw+d08bjqblSq8aXDkmFA7HeunSFKkdn
123  oIEOEgyj+veuOMRJC5pnBJ9vV+7qRdDKQWaCKotynt4sWJDGQ9kWGWm74SsNaduN
124  TPMyr9kNmGsfR69Q2Zq/FLcLX/j8ESxU+HYUB4vaARw2xEOu2xwDDv6jt0j3Vqsg
125  x7rWv4S/Eh18FDNDkVRChiNoOIilLYLL6c38uMf1pnItBuxP3uhgY6COm59kVaRh
126  nyGTYCDYD2TK+fI9o89F1297uDCwEJ62U0Q7iTDp5QuXCoxkPfv8/kX6lS6T3y9G
127  M9mqIoLbIQ1EDntFv7/t6fUTS2+46uCrdZWbQ5RjYXdrzjij02nDmJAm2BngnZvd
128  kamH0Y/n11lCvo1oQxM+
129  =uSzz
130  -----END PGP SIGNATURE-----
131  **************************************************************/
132 
133 #include "../core/stdafx.hpp"
134 
135 #include "OTPayment.hpp"
136 #include "InstantiateContract.hpp"
137 
138 #include "../cash/Purse.hpp"
139 
140 #include "../core/recurring/OTPaymentPlan.hpp"
141 #include "../core/script/OTSmartContract.hpp"
142 #include "../core/OTCheque.hpp"
143 #include "../core/OTLog.hpp"
144 
145 #include <irrxml/irrXML.hpp>
146 
147 #include <memory>
148 
149 namespace opentxs
150 {
151 
152 char const* const __TypeStrings[] = {
153 
154  // OTCheque is derived from OTTrackable, which is derived from OTInstrument,
155  // which is
156  // derived from OTScriptable, which is derived from OTContract.
157  "CHEQUE", // A cheque drawn on a user's account.
158  "VOUCHER", // A cheque drawn on a server account (cashier's cheque aka
159  // banker's cheque)
160  "INVOICE", // A cheque with a negative amount. (Depositing this causes a
161  // payment out, instead of a deposit in.)
162  "PAYMENT PLAN", // An OTCronItem-derived OTPaymentPlan, related to a
163  // recurring payment plan.
164  "SMARTCONTRACT", // An OTCronItem-derived OTSmartContract, related to a
165  // smart contract.
166  "PURSE", // An OTContract-derived OTPurse containing a list of cash
167  // OTTokens.
168  "ERROR_STATE"};
169 
170 // static
172 {
173  int32_t nType = static_cast<int32_t>(theType);
174  return __TypeStrings[nType];
175 }
176 
178 {
179 #define OT_NUM_ELEM(blah) (sizeof(blah) / sizeof(*(blah)))
180  for (uint32_t i = 0; i < (OT_NUM_ELEM(__TypeStrings) - 1); i++) {
181  if (strType.Compare(__TypeStrings[i]))
182  return static_cast<OTPayment::paymentType>(i);
183  }
184 #undef OT_NUM_ELEM
185  return OTPayment::ERROR_STATE;
186 }
187 
188 // Since the temp values are not available until at least ONE instantiating has
189 // occured,
190 // this function forces that very scenario (cleanly) so you don't have to
191 // instantiate-and-
192 // then-delete a payment instrument. Instead, just call this, and then the temp
193 // values will
194 // be available thereafter.
195 //
196 bool OTPayment::SetTempValues() // this version for OTTrackable (all types
197  // EXCEPT purses.)
198 {
199  if (OTPayment::PURSE == m_Type) {
200  // Perform instantiation of a purse, then use it to set the temp values,
201  // then cleans it up again before returning success/fail.
202  //
203  Purse* pPurse = InstantiatePurse();
204 
205  if (nullptr == pPurse) {
206  otErr << "OTPayment::SetTempValues: Error: Failed instantiating "
207  "OTPayment (purported purse) contents:\n\n" << m_strPayment
208  << "\n\n";
209  return false;
210  }
211  std::unique_ptr<Purse> thePurseAngel(pPurse);
212 
213  return SetTempValuesFromPurse(*pPurse);
214  }
215  else {
216  OTTrackable* pTrackable = Instantiate();
217 
218  if (nullptr == pTrackable) {
219  otErr << "OTPayment::SetTempValues: Error: Failed instantiating "
220  "OTPayment contents:\n\n" << m_strPayment << "\n\n";
221  return false;
222  }
223  // BELOW THIS POINT, MUST DELETE pTrackable!
224  std::unique_ptr<OTTrackable> theTrackableAngel(pTrackable);
225 
226  OTCheque* pCheque = nullptr;
227  OTPaymentPlan* pPaymentPlan = nullptr;
228  OTSmartContract* pSmartContract = nullptr;
229 
230  switch (m_Type) {
231  case CHEQUE:
232  case VOUCHER:
233  case INVOICE:
234  pCheque = dynamic_cast<OTCheque*>(pTrackable);
235  if (nullptr == pCheque)
236  otErr << "OTPayment::SetTempValues: Failure: "
237  "dynamic_cast<OTCheque *>(pTrackable). Contents:\n\n"
238  << m_strPayment << "\n\n";
239  // Let's grab all the temp values from the cheque!!
240  //
241  else // success
242  return SetTempValuesFromCheque(*pCheque);
243  break;
244 
245  case PAYMENT_PLAN:
246  pPaymentPlan = dynamic_cast<OTPaymentPlan*>(pTrackable);
247  if (nullptr == pPaymentPlan)
248  otErr << "OTPayment::SetTempValues: Failure: "
249  "dynamic_cast<OTPaymentPlan *>(pTrackable). "
250  "Contents:\n\n" << m_strPayment << "\n\n";
251  // Let's grab all the temp values from the payment plan!!
252  //
253  else // success
254  return SetTempValuesFromPaymentPlan(*pPaymentPlan);
255  break;
256 
257  case SMART_CONTRACT:
258  pSmartContract = dynamic_cast<OTSmartContract*>(pTrackable);
259  if (nullptr == pSmartContract)
260  otErr << "OTPayment::SetTempValues: Failure: "
261  "dynamic_cast<OTSmartContract *>(pTrackable). "
262  "Contents:\n\n" << m_strPayment << "\n\n";
263  // Let's grab all the temp values from the smart contract!!
264  //
265  else // success
266  return SetTempValuesFromSmartContract(*pSmartContract);
267  break;
268 
269  default:
270  otErr << "OTPayment::SetTempValues: Failure: Wrong m_Type. "
271  "Contents:\n\n" << m_strPayment << "\n\n";
272  return false;
273  }
274  }
275 
276  return false; // Should never actually reach this point.
277 }
278 
280 {
281  switch (m_Type) {
282  case OTPayment::CHEQUE:
283  case OTPayment::VOUCHER:
284  case OTPayment::INVOICE:
285 
286  m_bAreTempValuesSet = true;
287 
288  m_lAmount = theInput.GetAmount();
290 
291  if (theInput.GetMemo().Exists())
292  m_strMemo.Set(theInput.GetMemo());
293  else
294  m_strMemo.Release();
295 
296  m_AssetTypeID = theInput.GetAssetID();
297  m_ServerID = theInput.GetServerID();
298 
299  m_SenderUserID = theInput.GetSenderUserID();
300  m_SenderAcctID = theInput.GetSenderAcctID();
301 
302  if (theInput.HasRecipient()) {
303  m_bHasRecipient = true;
305  }
306  else {
307  m_bHasRecipient = false;
309  }
310 
311  if (theInput.HasRemitter()) {
312  m_bHasRemitter = true;
313  m_RemitterUserID = theInput.GetRemitterUserID();
314  m_RemitterAcctID = theInput.GetRemitterAcctID();
315  }
316  else {
317  m_bHasRemitter = false;
320  }
321 
322  // NOTE: the "Recipient Acct" is NOT KNOWN when cheque is written, but
323  // only
324  // once the cheque gets deposited. Therefore if type is CHEQUE, then
325  // Recipient
326  // Acct ID is not set, and attempts to read it will result in failure.
327  //
329 
330  m_VALID_FROM = theInput.GetValidFrom();
331  m_VALID_TO = theInput.GetValidTo();
332 
333  return true;
334 
335  default:
336  otErr << "OTPayment::SetTempValuesFromCheque: Error: Wrong type. "
337  "(Returning false.)\n";
338  break;
339  }
340 
341  return false;
342 }
343 
345 {
347  m_bAreTempValuesSet = true;
348  m_bHasRecipient = true;
349  m_bHasRemitter = false;
350 
351  m_lAmount = theInput.GetInitialPaymentAmount(); // There're also regular
352  // payments of
353  // GetPaymentPlanAmount(). Can't
354  // fit 'em all.
356 
357  // const OTString& OTPaymentPlan::GetConsideration() const
358  // { return m_strConsideration; }
359  if (theInput.GetConsideration().Exists())
360  m_strMemo.Set(theInput.GetConsideration());
361  else
362  m_strMemo.Release();
363 
364  m_AssetTypeID = theInput.GetAssetID();
365  m_ServerID = theInput.GetServerID();
366 
367  m_SenderUserID = theInput.GetSenderUserID();
368  m_SenderAcctID = theInput.GetSenderAcctID();
369 
372 
375 
376  m_VALID_FROM = theInput.GetValidFrom();
377  m_VALID_TO = theInput.GetValidTo();
378 
379  return true;
380  }
381  else
382  otErr << "OTPayment::SetTempValuesFromPaymentPlan: Error: Wrong type. "
383  "(Returning false.)\n";
384 
385  return false;
386 }
387 
389 {
391  m_bAreTempValuesSet = true;
392  m_bHasRecipient = false;
393  m_bHasRemitter = false;
394 
395  m_lAmount = 0; // not used here.
397 
398  // Note: Maybe later, store the Smart Contract's temporary name, or ID,
399  // in the memo field.
400  // Or something.
401  //
402  m_strMemo.Release(); // not used here.
403 
404  m_ServerID = theInput.GetServerID();
405  m_AssetTypeID.Release(); // not used here.
406 
407  m_SenderUserID = theInput.GetSenderUserID();
409 
410  m_RecipientUserID.Release(); // not used here.
411  m_RecipientAcctID.Release(); // not used here.
412 
415 
416  m_VALID_FROM = theInput.GetValidFrom();
417  m_VALID_TO = theInput.GetValidTo();
418 
419  return true;
420  }
421  else
422  otErr << __FUNCTION__ << ": Error: Wrong type. (Returning false.)\n";
423 
424  return false;
425 }
426 
428 {
429  if (OTPayment::PURSE == m_Type) {
430  m_bAreTempValuesSet = true;
431  m_bHasRecipient = theInput.IsNymIDIncluded();
432  m_bHasRemitter = false;
433 
434  m_lAmount = theInput.GetTotalValue();
435  m_lTransactionNum = 0; // (A purse has no transaction number.)
436 
437  m_strMemo.Release(); // So far there's no purse memo (could add it,
438  // though.)
439 
440  m_AssetTypeID = theInput.GetAssetID();
441  m_ServerID = theInput.GetServerID();
442 
445 
446  if (!m_bHasRecipient || !theInput.GetNymID(m_RecipientUserID)) {
447  m_bHasRecipient = false;
449  }
450 
452 
455 
456  m_VALID_FROM = theInput.GetLatestValidFrom();
457  m_VALID_TO = theInput.GetEarliestValidTo();
458 
459  return true;
460  }
461  else
462  otErr << "OTPayment::SetTempValuesFromPurse: Error: Wrong type. "
463  "(Returning false.)\n";
464 
465  return false;
466 }
467 
468 bool OTPayment::GetMemo(OTString& strOutput) const
469 {
470  strOutput.Release();
471 
472  if (!m_bAreTempValuesSet) return false;
473 
474  bool bSuccess = false;
475 
476  switch (m_Type) {
477  case OTPayment::CHEQUE:
478  case OTPayment::VOUCHER:
479  case OTPayment::INVOICE:
481  if (m_strMemo.Exists()) {
482  strOutput = m_strMemo;
483  bSuccess = true;
484  }
485  else
486  bSuccess = false;
487  break;
488 
490  case OTPayment::PURSE:
491  bSuccess = false;
492  break;
493 
494  default:
495  otErr << "OTPayment::GetMemo: Bad payment type!\n";
496  break;
497  }
498 
499  return bSuccess;
500 }
501 
502 bool OTPayment::GetAmount(int64_t& lOutput) const
503 {
504  lOutput = 0;
505 
506  if (!m_bAreTempValuesSet) return false;
507 
508  bool bSuccess = false;
509 
510  switch (m_Type) {
511  case OTPayment::CHEQUE:
512  case OTPayment::VOUCHER:
513  case OTPayment::INVOICE:
515  case OTPayment::PURSE:
516  lOutput = m_lAmount;
517  bSuccess = true;
518  break;
519 
521  lOutput = 0;
522  bSuccess = false;
523  break;
524 
525  default:
526  otErr << "OTPayment::GetAmount: Bad payment type!\n";
527  break;
528  }
529 
530  return bSuccess;
531 }
532 
534 {
535  // SMART CONTRACTS and PAYMENT PLANS get a little special
536  // treatment here at the top.
537  //
538  if ((false == m_bAreTempValuesSet) || // Why is this here? Because if temp
539  // values haven't been set yet,
541  m_Type) || // then m_Type isn't set either. We only want smartcontracts
542  // and UPDATE: m_Type IS set!!
543  (OTPayment::PAYMENT_PLAN == m_Type)) // payment plans here, but without
544  // m_Type we can't know the
545  // type...This comment is wrong!!
546  {
547  OTTrackable* pTrackable = Instantiate();
548  if (nullptr == pTrackable) {
549  otErr << __FUNCTION__
550  << ": Failed instantiating OTPayment containing:\n"
551  << m_strPayment << "\n";
552  return false;
553  } // Below THIS POINT, MUST DELETE pTrackable!
554  std::unique_ptr<OTTrackable> theTrackableAngel(pTrackable);
555 
556  OTPaymentPlan* pPlan = nullptr;
557  OTSmartContract* pSmartContract = nullptr;
558 
559  pPlan = dynamic_cast<OTPaymentPlan*>(pTrackable);
560  pSmartContract = dynamic_cast<OTSmartContract*>(pTrackable);
561 
562  if (nullptr != pPlan) {
563  pPlan->GetAllTransactionNumbers(numlistOutput);
564  return true;
565  }
566  else if (nullptr != pSmartContract) {
567  pSmartContract->GetAllTransactionNumbers(numlistOutput);
568  return true;
569  }
570  }
571 
572  if (!m_bAreTempValuesSet) // (This function normally fails, if temp values
573  // aren't set,
574  return false; // for all payment types except the recurring ones
575  // above.)
576 
577  // Next: ALL OTHER payment types...
578  //
579  bool bSuccess = false;
580 
581  switch (m_Type) {
582  case OTPayment::CHEQUE:
583  case OTPayment::VOUCHER:
584  case OTPayment::INVOICE:
585  if (m_lTransactionNum > 0) numlistOutput.Add(m_lTransactionNum);
586  bSuccess = true;
587  break;
588 
589  case OTPayment::PURSE:
590  bSuccess = false;
591  break;
592 
593  default:
594  case OTPayment::PAYMENT_PLAN: // Should never happen. (Handled already
595  // above.)
596  case OTPayment::SMART_CONTRACT: // Should never happen. (Handled already
597  // above.)
598  otErr << "OTPayment::" << __FUNCTION__ << ": Bad payment type!\n";
599  break;
600  }
601 
602  return bSuccess;
603 }
604 
605 // This works with a cheque who has a transaction number.
606 // It also works with a payment plan or smart contract, for opening AND closing
607 // numbers.
608 bool OTPayment::HasTransactionNum(const int64_t& lInput) const
609 {
610  // SMART CONTRACTS and PAYMENT PLANS get a little special
611  // treatment here at the top.
612  //
613  if ((false == m_bAreTempValuesSet) || // Why is this here? Because if temp
614  // values haven't been set yet,
616  m_Type) || // then m_Type isn't set either. We only want smartcontracts
617  // and UPDATE: m_Type IS set!!
618  (OTPayment::PAYMENT_PLAN == m_Type)) // payment plans here, but without
619  // m_Type we can't know the
620  // type...This comment is wrong!!
621  {
622  OTTrackable* pTrackable = Instantiate();
623  if (nullptr == pTrackable) {
624  otErr << __FUNCTION__
625  << ": Failed instantiating OTPayment containing:\n"
626  << m_strPayment << "\n";
627  return false;
628  } // BELOW THIS POINT, MUST DELETE pTrackable!
629  std::unique_ptr<OTTrackable> theTrackableAngel(pTrackable);
630 
631  OTPaymentPlan* pPlan = nullptr;
632  OTSmartContract* pSmartContract = nullptr;
633 
634  pPlan = dynamic_cast<OTPaymentPlan*>(pTrackable);
635  pSmartContract = dynamic_cast<OTSmartContract*>(pTrackable);
636 
637  if (nullptr != pPlan) {
638  if (pPlan->HasTransactionNum(lInput)) return true;
639  return false;
640  }
641  else if (nullptr != pSmartContract) {
642  if (pSmartContract->HasTransactionNum(lInput)) return true;
643  return false;
644  }
645  }
646 
647  if (!m_bAreTempValuesSet) // (This function normally fails, if temp values
648  // aren't set,
649  return false; // for all payment types except the recurring ones
650  // above.)
651 
652  // Next: ALL OTHER payment types...
653  //
654  bool bSuccess = false;
655 
656  switch (m_Type) {
657  case OTPayment::CHEQUE:
658  case OTPayment::VOUCHER:
659  case OTPayment::INVOICE:
660  if (lInput == m_lTransactionNum) bSuccess = true;
661  break;
662 
663  case OTPayment::PURSE:
664  bSuccess = false;
665  break;
666 
667  default:
668  case OTPayment::PAYMENT_PLAN: // Should never happen. (Handled already
669  // above.)
670  case OTPayment::SMART_CONTRACT: // Should never happen. (Handled already
671  // above.)
672  otErr << "OTPayment::" << __FUNCTION__ << ": Bad payment type!\n";
673  break;
674  }
675 
676  return bSuccess;
677 }
678 
679 bool OTPayment::GetClosingNum(int64_t& lOutput,
680  const OTIdentifier& theAcctID) const
681 {
682  lOutput = 0;
683 
684  // SMART CONTRACTS and PAYMENT PLANS get a little special
685  // treatment here at the top.
686  //
687  if ((false ==
688  m_bAreTempValuesSet) || // m_Type isn't even set if this is false.
691  OTTrackable* pTrackable = Instantiate();
692  if (nullptr == pTrackable) {
693  otErr << __FUNCTION__
694  << ": Failed instantiating OTPayment containing:\n"
695  << m_strPayment << "\n";
696  return false;
697  } // BELOW THIS POINT, MUST DELETE pTrackable!
698  std::unique_ptr<OTTrackable> theTrackableAngel(pTrackable);
699 
700  OTSmartContract* pSmartContract = nullptr;
701  pSmartContract = dynamic_cast<OTSmartContract*>(pTrackable);
702 
703  OTPaymentPlan* pPlan = nullptr;
704  pPlan = dynamic_cast<OTPaymentPlan*>(pTrackable);
705 
706  if (nullptr != pSmartContract) {
707  lOutput = pSmartContract->GetClosingNumber(theAcctID);
708  if (lOutput > 0) return true;
709  return false;
710  }
711  else if (nullptr != pPlan) {
712  lOutput = pPlan->GetClosingNumber(theAcctID);
713  if (lOutput > 0) return true;
714  return false;
715  }
716  }
717 
718  if (!m_bAreTempValuesSet) return false;
719 
720  // Next: ALL OTHER payment types...
721  //
722  bool bSuccess = false;
723 
724  switch (m_Type) {
725 
726  case OTPayment::CHEQUE:
727  case OTPayment::VOUCHER:
728  case OTPayment::INVOICE:
729  case OTPayment::PURSE:
730  lOutput = 0; // Redundant, but just making sure.
731  bSuccess = false;
732  break;
733 
734  default:
737  otErr << __FUNCTION__ << ": Bad payment type!\n";
738  break;
739  }
740 
741  return bSuccess;
742 }
743 
744 bool OTPayment::GetOpeningNum(int64_t& lOutput,
745  const OTIdentifier& theNymID) const
746 {
747  lOutput = 0;
748 
749  // SMART CONTRACTS and PAYMENT PLANS get a little special
750  // treatment here at the top.
751  //
752  if ((false ==
753  m_bAreTempValuesSet) || // m_Type isn't even set if this is false.
756  OTTrackable* pTrackable = Instantiate();
757  if (nullptr == pTrackable) {
758  otErr << __FUNCTION__
759  << ": Failed instantiating OTPayment containing:\n"
760  << m_strPayment << "\n";
761  return false;
762  } // BELOW THIS POINT, MUST DELETE pTrackable!
763  std::unique_ptr<OTTrackable> theTrackableAngel(pTrackable);
764 
765  OTSmartContract* pSmartContract = nullptr;
766  pSmartContract = dynamic_cast<OTSmartContract*>(pTrackable);
767 
768  OTPaymentPlan* pPlan = nullptr;
769  pPlan = dynamic_cast<OTPaymentPlan*>(pTrackable);
770 
771  if (nullptr != pSmartContract) {
772  lOutput = pSmartContract->GetOpeningNumber(theNymID);
773  if (lOutput > 0) return true;
774  return false;
775  }
776  else if (nullptr != pPlan) {
777  lOutput = pPlan->GetOpeningNumber(theNymID);
778  if (lOutput > 0) return true;
779  return false;
780  }
781  }
782 
783  if (!m_bAreTempValuesSet) return false;
784 
785  //
786  // Next: ALL OTHER payment types...
787  //
788  bool bSuccess = false;
789 
790  switch (m_Type) {
791 
792  case OTPayment::CHEQUE:
793  case OTPayment::INVOICE:
794  if (theNymID == m_SenderUserID) {
795  lOutput = m_lTransactionNum; // The "opening" number for a cheque is
796  // the ONLY number it has.
797  bSuccess = true;
798  }
799  else {
800  lOutput = 0;
801  bSuccess = false;
802  }
803  break;
804 
805  case OTPayment::VOUCHER:
806  if (theNymID == m_RemitterUserID) {
807  lOutput = m_lTransactionNum; // The "opening" number for a cheque is
808  // the ONLY number it has.
809  bSuccess = true;
810  }
811  else {
812  lOutput = 0;
813  bSuccess = false;
814  }
815  break;
816 
817  case OTPayment::PURSE:
818  lOutput = 0; // Redundant, but just making sure.
819  bSuccess = false;
820  break;
821 
822  default:
825  otErr << __FUNCTION__ << ": Bad payment type!\n";
826  break;
827  }
828 
829  return bSuccess;
830 }
831 
832 bool OTPayment::GetTransactionNum(int64_t& lOutput) const
833 {
834  lOutput = 0;
835 
836  if (!m_bAreTempValuesSet) return false;
837 
838  bool bSuccess = false;
839 
840  switch (m_Type) {
841  case OTPayment::CHEQUE:
842  case OTPayment::VOUCHER:
843  case OTPayment::INVOICE:
844  case OTPayment::PAYMENT_PLAN: // For payment plans, this is the opening
845  // transaction FOR THE NYM who activated the
846  // contract (probably the customer.)
847  case OTPayment::SMART_CONTRACT: // For smart contracts, this is the opening
848  // transaction number FOR THE NYM who
849  // activated the contract.
850  lOutput = m_lTransactionNum;
851  bSuccess = true;
852  break;
853 
854  case OTPayment::PURSE:
855  lOutput = 0;
856  bSuccess = false;
857  break;
858 
859  default:
860  otErr << "OTPayment::GetTransactionNum: Bad payment type!\n";
861  break;
862  }
863 
864  return bSuccess;
865 }
866 
867 bool OTPayment::GetValidFrom(time64_t& tOutput) const
868 {
869  tOutput = OT_TIME_ZERO;
870 
871  if (!m_bAreTempValuesSet) return false;
872 
873  bool bSuccess = false;
874 
875  switch (m_Type) {
876  case OTPayment::PURSE:
877  case OTPayment::CHEQUE:
878  case OTPayment::VOUCHER:
879  case OTPayment::INVOICE:
882  tOutput = m_VALID_FROM;
883  bSuccess = true;
884  break;
885 
886  default:
887  otErr << "OTPayment::GetValidFrom: Bad payment type!\n";
888  break;
889  }
890 
891  return bSuccess;
892 }
893 
894 bool OTPayment::GetValidTo(time64_t& tOutput) const
895 {
896  tOutput = OT_TIME_ZERO;
897 
898  if (!m_bAreTempValuesSet) return false;
899 
900  bool bSuccess = false;
901 
902  switch (m_Type) {
903  case OTPayment::PURSE:
904  case OTPayment::CHEQUE:
905  case OTPayment::VOUCHER:
906  case OTPayment::INVOICE:
909  tOutput = m_VALID_TO;
910  bSuccess = true;
911  break;
912 
913  default:
914  otErr << "OTPayment::GetValidTo: Bad payment type!\n";
915  break;
916  }
917 
918  return bSuccess;
919 }
920 
921 // Verify whether the CURRENT date is AFTER the the VALID TO date.
922 // Notice, this will return false, if the instrument is NOT YET VALID.
923 // You have to use VerifyCurrentDate() to make sure you're within the
924 // valid date range to use this instrument. But sometimes you only want
925 // to know if it's expired, regardless of whether it's valid yet. So this
926 // function answers that for you.
927 //
928 bool OTPayment::IsExpired(bool& bExpired)
929 {
930  if (!m_bAreTempValuesSet) return false;
931 
932  const time64_t CURRENT_TIME = OTTimeGetCurrentTime();
933 
934  // If the current time is AFTER the valid-TO date,
935  // AND the valid_to is a nonzero number (0 means "doesn't expire")
936  // THEN return true (it's expired.)
937  //
938  if ((CURRENT_TIME >= m_VALID_TO) && (m_VALID_TO > OT_TIME_ZERO))
939  bExpired = true;
940  else
941  bExpired = false;
942 
943  return true;
944 }
945 
946 // Verify whether the CURRENT date is WITHIN the VALID FROM / TO dates.
947 //
948 bool OTPayment::VerifyCurrentDate(bool& bVerified)
949 {
950  if (!m_bAreTempValuesSet) return false;
951 
952  const time64_t CURRENT_TIME = OTTimeGetCurrentTime();
953 
954  if ((CURRENT_TIME >= m_VALID_FROM) &&
955  ((CURRENT_TIME <= m_VALID_TO) || (OT_TIME_ZERO == m_VALID_TO)))
956  bVerified = true;
957  else
958  bVerified = false;
959 
960  return true;
961 }
962 
964 {
965  theOutput.Release();
966 
967  if (!m_bAreTempValuesSet) return false;
968 
969  bool bSuccess = false;
970 
971  switch (m_Type) {
972  case OTPayment::CHEQUE:
973  case OTPayment::VOUCHER:
974  case OTPayment::INVOICE:
976  case OTPayment::PURSE:
977  theOutput = m_AssetTypeID;
978  bSuccess = true;
979  break;
980 
982  bSuccess = false;
983  break;
984 
985  default:
986  otErr << "OTPayment::GetAssetTypeID: Bad payment type!\n";
987  break;
988  }
989 
990  return bSuccess;
991 }
992 
993 bool OTPayment::GetServerID(OTIdentifier& theOutput) const
994 {
995  theOutput.Release();
996 
997  if (!m_bAreTempValuesSet) return false;
998 
999  bool bSuccess = false;
1000 
1001  switch (m_Type) {
1002  case OTPayment::CHEQUE:
1003  case OTPayment::VOUCHER:
1004  case OTPayment::INVOICE:
1007  case OTPayment::PURSE:
1008  theOutput = m_ServerID;
1009  bSuccess = true;
1010  break;
1011 
1012  default:
1013  otErr << "OTPayment::GetServerID: Bad payment type!\n";
1014  break;
1015  }
1016 
1017  return bSuccess;
1018 }
1019 
1020 // With a voucher (cashier's cheque) the "bank" is the "sender",
1021 // whereas the actual Nym who purchased it is the "remitter."
1022 //
1024 {
1025  theOutput.Release();
1026 
1027  if (!m_bAreTempValuesSet) return false;
1028 
1029  bool bSuccess = false;
1030 
1031  switch (m_Type) {
1032  case OTPayment::VOUCHER:
1033  theOutput = m_RemitterUserID;
1034  bSuccess = true;
1035  break;
1036 
1037  default:
1038  otErr << "OTPayment::GetRemitterUserID: Bad payment type! Expected a "
1039  "voucher cheque.\n";
1040  break;
1041  }
1042 
1043  return bSuccess;
1044 }
1045 
1046 // With a voucher (cashier's cheque) the "bank"s account is the "sender" acct,
1047 // whereas the actual account originally used to purchase it is the "remitter"
1048 // acct.
1049 //
1051 {
1052  theOutput.Release();
1053 
1054  if (!m_bAreTempValuesSet) return false;
1055 
1056  bool bSuccess = false;
1057 
1058  switch (m_Type) {
1059  case OTPayment::VOUCHER:
1060  theOutput = m_RemitterAcctID;
1061  bSuccess = true;
1062  break;
1063 
1064  default:
1065  otErr << "OTPayment::GetRemitterAcctID: Bad payment type! Expected a "
1066  "voucher cheque.\n";
1067  break;
1068  }
1069 
1070  return bSuccess;
1071 }
1072 
1074 {
1075  if (IsVoucher()) return GetRemitterUserID(theOutput);
1076 
1077  return GetSenderUserID(theOutput);
1078 }
1079 
1081 {
1082  if (IsVoucher()) return GetRemitterAcctID(theOutput);
1083 
1084  return GetSenderAcctID(theOutput);
1085 }
1086 
1088 {
1089  theOutput.Release();
1090 
1091  if (!m_bAreTempValuesSet) return false;
1092 
1093  bool bSuccess = false;
1094 
1095  switch (m_Type) {
1096  case OTPayment::CHEQUE:
1097  case OTPayment::VOUCHER:
1098  case OTPayment::INVOICE:
1101  theOutput = m_SenderUserID;
1102  bSuccess = true;
1103  break;
1104 
1105  case OTPayment::PURSE:
1106  bSuccess = false;
1107  break;
1108 
1109  default:
1110  otErr << "OTPayment::GetSenderUserID: Bad payment type!\n";
1111  break;
1112  }
1113 
1114  return bSuccess;
1115 }
1116 
1118 {
1119  theOutput.Release();
1120 
1121  if (!m_bAreTempValuesSet) return false;
1122 
1123  bool bSuccess = false;
1124 
1125  switch (m_Type) {
1126  case OTPayment::CHEQUE:
1127  case OTPayment::VOUCHER:
1128  case OTPayment::INVOICE:
1130  theOutput = m_SenderAcctID;
1131  bSuccess = true;
1132  break;
1133 
1135  case OTPayment::PURSE:
1136  bSuccess = false;
1137  break;
1138 
1139  default:
1140  otErr << "OTPayment::GetSenderAcctID: Bad payment type!\n";
1141  break;
1142  }
1143 
1144  return bSuccess;
1145 }
1146 
1148 {
1149  theOutput.Release();
1150 
1151  if (!m_bAreTempValuesSet) return false;
1152 
1153  bool bSuccess = false;
1154 
1155  switch (m_Type) {
1156  case OTPayment::CHEQUE:
1157  case OTPayment::VOUCHER:
1158  case OTPayment::INVOICE:
1160  case OTPayment::PURSE:
1161  if (m_bHasRecipient) {
1162  theOutput = m_RecipientUserID;
1163  bSuccess = true;
1164  }
1165  else
1166  bSuccess = false;
1167 
1168  break;
1169 
1171  bSuccess = false;
1172  break;
1173 
1174  default:
1175  otErr << "OTPayment::GetRecipientUserID: Bad payment type!\n";
1176  break;
1177  }
1178 
1179  return bSuccess;
1180 }
1181 
1183 {
1184  // NOTE:
1185  // A cheque HAS NO "Recipient Asset Acct ID", since the recipient's account
1186  // (where he deposits
1187  // the cheque) is not known UNTIL the time of the deposit. It's certain not
1188  // known at the time
1189  // that the cheque is written...
1190 
1191  theOutput.Release();
1192 
1193  if (!m_bAreTempValuesSet) return false;
1194 
1195  bool bSuccess = false;
1196 
1197  switch (m_Type) {
1199  if (m_bHasRecipient) {
1200  theOutput = m_RecipientAcctID;
1201  bSuccess = true;
1202  }
1203  else
1204  bSuccess = false;
1205 
1206  break;
1207 
1208  case OTPayment::CHEQUE:
1209  case OTPayment::VOUCHER:
1210  case OTPayment::INVOICE:
1212  case OTPayment::PURSE: // A purse might have a recipient USER, but never a
1213  // recipient ACCOUNT.
1214  bSuccess = false;
1215  break;
1216 
1217  default:
1218  otErr << "OTPayment::GetRecipientAcctID: Bad payment type!\n";
1219  break;
1220  }
1221 
1222  return bSuccess;
1223 }
1224 
1226  : ot_super()
1227  , m_Type(OTPayment::ERROR_STATE)
1228  , m_bAreTempValuesSet(false)
1229  , m_bHasRecipient(false)
1230  , m_bHasRemitter(false)
1231  , m_lAmount(0)
1232  , m_lTransactionNum(0)
1233  , m_VALID_FROM(OT_TIME_ZERO)
1234  , m_VALID_TO(OT_TIME_ZERO)
1235 {
1236  InitPayment();
1237 }
1238 
1239 OTPayment::OTPayment(const OTString& strPayment)
1240  : ot_super()
1241  , m_Type(OTPayment::ERROR_STATE)
1242  , m_bAreTempValuesSet(false)
1243  , m_bHasRecipient(false)
1244  , m_bHasRemitter(false)
1245  , m_lAmount(0)
1246  , m_lTransactionNum(0)
1247  , m_VALID_FROM(OT_TIME_ZERO)
1248  , m_VALID_TO(OT_TIME_ZERO)
1249 {
1250  InitPayment();
1251 
1252  SetPayment(strPayment);
1253 }
1254 
1255 // CALLER is responsible to delete.
1256 //
1258 {
1259  OTContract* pContract = nullptr;
1260  OTTrackable* pTrackable = nullptr;
1261  OTCheque* pCheque = nullptr;
1262  OTPaymentPlan* pPaymentPlan = nullptr;
1263  OTSmartContract* pSmartContract = nullptr;
1264 
1265  switch (m_Type) {
1266  case CHEQUE:
1267  case VOUCHER:
1268  case INVOICE:
1269  pContract = ::InstantiateContract(m_strPayment);
1270 
1271  if (nullptr != pContract) {
1272  pCheque = dynamic_cast<OTCheque*>(pContract);
1273 
1274  if (nullptr == pCheque) {
1275  otErr << "OTPayment::Instantiate: Tried to instantiate cheque, "
1276  "but factory returned non-cheque:\n\n" << m_strPayment
1277  << "\n\n";
1278  delete pContract;
1279  pContract = nullptr;
1280  }
1281  else
1282  pTrackable = pCheque;
1283  }
1284  else
1285  otErr << "OTPayment::Instantiate: Tried to instantiate cheque, but "
1286  "factory returned nullptr:\n\n" << m_strPayment << "\n\n";
1287  break;
1288 
1289  case PAYMENT_PLAN:
1290  pContract = ::InstantiateContract(m_strPayment);
1291 
1292  if (nullptr != pContract) {
1293  pPaymentPlan = dynamic_cast<OTPaymentPlan*>(pContract);
1294 
1295  if (nullptr == pPaymentPlan) {
1296  otErr << "OTPayment::Instantiate: Tried to instantiate payment "
1297  "plan, but factory returned non-payment-plan:\n\n"
1298  << m_strPayment << "\n\n";
1299  delete pContract;
1300  pContract = nullptr;
1301  }
1302  else
1303  pTrackable = pPaymentPlan;
1304  }
1305  else
1306  otErr << "OTPayment::Instantiate: Tried to instantiate payment "
1307  "plan, but factory returned nullptr:\n\n" << m_strPayment
1308  << "\n\n";
1309  break;
1310 
1311  case SMART_CONTRACT:
1312  pContract = ::InstantiateContract(m_strPayment);
1313 
1314  if (nullptr != pContract) {
1315  pSmartContract = dynamic_cast<OTSmartContract*>(pContract);
1316 
1317  if (nullptr == pSmartContract) {
1318  otErr << __FUNCTION__
1319  << ": Tried to instantiate smart contract, but factory "
1320  "returned non-smart-contract:\n\n" << m_strPayment
1321  << "\n\n";
1322  delete pContract;
1323  pContract = nullptr;
1324  }
1325  else
1326  pTrackable = pSmartContract;
1327  }
1328  else
1329  otErr << "OTPayment::Instantiate: Tried to instantiate smart "
1330  "contract, but factory returned nullptr:\n\n"
1331  << m_strPayment << "\n\n";
1332  break;
1333  case PURSE:
1334  otErr << "OTPayment::Instantiate: ERROR: Tried to instantiate purse, "
1335  "but should have called OTPayment::InstantiatePurse.\n";
1336  return nullptr;
1337  default:
1338  otErr << "OTPayment::Instantiate: ERROR: Tried to instantiate payment "
1339  "object, but had a bad type. Contents:\n\n" << m_strPayment
1340  << "\n\n";
1341  return nullptr;
1342  }
1343 
1344  return pTrackable;
1345 }
1346 
1348 {
1349  if (SetPayment(strPayment)) return Instantiate();
1350 
1351  return nullptr;
1352 }
1353 
1354 // You need the server ID to instantiate a purse, unlike all the
1355 // other payment types. UPDATE: Not anymore.
1356 //
1357 // CALLER is responsible to delete!
1358 //
1360 {
1361  if (OTPayment::PURSE == GetType()) {
1363  }
1364  else
1365  otErr << "OTPayment::InstantiatePurse: Failure: This payment object "
1366  "does NOT contain a purse. "
1367  "Contents:\n\n" << m_strPayment << "\n\n";
1368 
1369  return nullptr;
1370 }
1371 
1372 /*
1373 OTPurse * OTPayment::InstantiatePurse(const OTIdentifier& SERVER_ID) const
1374 {
1375  if (OTPayment::PURSE == GetType())
1376  {
1377  return OTPurse::PurseFactory(m_strPayment, SERVER_ID);
1378  }
1379  else
1380  otErr << "OTPayment::InstantiatePurse: Failure: This payment object does
1381 NOT contain a purse. "
1382  "Contents:\n\n%s\n\n", m_strPayment.Get());
1383 
1384  return nullptr;
1385 }
1386 
1387 OTPurse * OTPayment::InstantiatePurse(const OTIdentifier& SERVER_ID, const
1388 OTIdentifier& ASSET_ID) const
1389 {
1390  if (OTPayment::PURSE == GetType())
1391  {
1392  return OTPurse::PurseFactory(m_strPayment, SERVER_ID, ASSET_ID);
1393  }
1394  else
1395  otErr << "OTPayment::InstantiatePurse: Failure: This payment object does
1396 NOT contain a purse. "
1397  "Contents:\n\n%s\n\n", m_strPayment.Get());
1398 
1399  return nullptr;
1400 }
1401 */
1402 
1404 {
1405  if (!SetPayment(strPayment))
1406  otErr << "OTPayment::InstantiatePurse: WARNING: Failed setting the "
1407  "payment string based on "
1408  "what was passed in:\n\n" << strPayment << "\n\n";
1409  else if (OTPayment::PURSE != m_Type)
1410  otErr << "OTPayment::InstantiatePurse: WARNING: No purse was found in "
1411  "the "
1412  "payment string:\n\n" << strPayment << "\n\n";
1413  else
1414  return InstantiatePurse();
1415 
1416  return nullptr;
1417 }
1418 
1419 /*
1420 OTPurse * OTPayment::InstantiatePurse(const OTIdentifier& SERVER_ID, const
1421 OTString& strPayment)
1422 {
1423  if (!SetPayment(strPayment))
1424  otErr << "OTPayment::InstantiatePurse: WARNING: Failed setting the
1425 payment string based on "
1426  "what was passed in:\n\n%s\n\n", strPayment.Get());
1427  else if (OTPayment::PURSE != m_Type)
1428  otErr << "OTPayment::InstantiatePurse: WARNING: No purse was found in
1429 the "
1430  "payment string:\n\n%s\n\n", strPayment.Get());
1431  else
1432  return InstantiatePurse(SERVER_ID);
1433 
1434  return nullptr;
1435 }
1436 
1437 
1438 OTPurse * OTPayment::InstantiatePurse(const OTIdentifier& SERVER_ID, const
1439 OTIdentifier& ASSET_ID, const OTString& strPayment)
1440 {
1441  if (!SetPayment(strPayment))
1442  otErr << "OTPayment::InstantiatePurse: WARNING: Failed setting the
1443 payment string based on "
1444  "what was passed in:\n\n%s\n\n", strPayment.Get());
1445  else if (OTPayment::PURSE != m_Type)
1446  otErr << "OTPayment::InstantiatePurse: WARNING: No purse was found in
1447 the "
1448  "payment string:\n\n%s\n\n", strPayment.Get());
1449  else
1450  return InstantiatePurse(SERVER_ID, ASSET_ID);
1451 
1452  return nullptr;
1453 }
1454 */
1455 
1456 bool OTPayment::SetPayment(const OTString& strPayment)
1457 {
1458  if (!strPayment.Exists()) return false;
1459 
1460  OTString strContract(strPayment);
1461 
1462  if (!strContract.DecodeIfArmored(false)) // bEscapedIsAllowed=true
1463  // by default.
1464  {
1465  otErr << __FUNCTION__ << ": Input string apparently was encoded and "
1466  "then failed decoding. Contents: \n"
1467  << strPayment << "\n";
1468  return false;
1469  }
1470 
1472 
1473  // todo: should be "starts with" and perhaps with a trim first
1474  //
1475  if (strContract.Contains("-----BEGIN SIGNED CHEQUE-----"))
1477  else if (strContract.Contains("-----BEGIN SIGNED VOUCHER-----"))
1479  else if (strContract.Contains("-----BEGIN SIGNED INVOICE-----"))
1481 
1482  else if (strContract.Contains("-----BEGIN SIGNED PAYMENT PLAN-----"))
1484  else if (strContract.Contains("-----BEGIN SIGNED SMARTCONTRACT-----"))
1486 
1487  else if (strContract.Contains("-----BEGIN SIGNED PURSE-----"))
1489  else {
1491 
1492  otErr << __FUNCTION__
1493  << ": Failure: Unable to determine payment type, from input:\n\n"
1494  << strContract << "\n\n";
1495  }
1496 
1497  if (OTPayment::ERROR_STATE == m_Type) return false;
1498 
1499  m_strPayment.Set(strContract);
1500 
1501  return true;
1502 }
1503 
1505 {
1507  m_lAmount = 0;
1508  m_lTransactionNum = 0;
1511  m_bAreTempValuesSet = false;
1512  m_bHasRecipient = false;
1513  m_bHasRemitter = false;
1514  m_strContractType.Set("PAYMENT");
1515 }
1516 
1518 {
1519  Release_Payment();
1520 }
1521 
1523 {
1525  m_lAmount = 0;
1526  m_lTransactionNum = 0;
1529 
1531 
1532  m_bAreTempValuesSet = false;
1533  m_bHasRecipient = false;
1534  m_bHasRemitter = false;
1535 
1536  m_strMemo.Release();
1537 
1539  m_ServerID.Release();
1540 
1545 
1548 }
1549 
1551 {
1552  Release_Payment();
1553 
1554  // Finally, we call the method we overrode:
1555  //
1557 }
1558 
1559 void OTPayment::UpdateContents() // Before transmission or serialization, this
1560  // is where the Purse saves its contents
1561 {
1562  // I release this because I'm about to repopulate it.
1564 
1565  m_xmlUnsigned.Concatenate("<?xml version=\"%s\"?>\n\n", "1.0");
1566 
1567  m_xmlUnsigned.Concatenate("<payment version=\"%s\"\n"
1568  " type=\"%s\">\n\n",
1570 
1571  if (m_strPayment.Exists()) {
1572  const OTASCIIArmor ascContents(m_strPayment);
1573 
1574  if (ascContents.Exists())
1575  m_xmlUnsigned.Concatenate("<contents>\n%s</contents>\n\n",
1576  ascContents.Get());
1577  }
1578 
1579  m_xmlUnsigned.Concatenate("</payment>\n");
1580 }
1581 
1583 {
1584  const OTString strNodeName(xml->getNodeName());
1585 
1586  if (strNodeName.Compare("payment")) {
1587  m_strVersion = xml->getAttributeValue("version");
1588 
1589  const OTString strPaymentType = xml->getAttributeValue("type");
1590 
1591  if (strPaymentType.Exists())
1592  m_Type = OTPayment::GetTypeFromString(strPaymentType);
1593  else
1595 
1596  otLog4 << "Loaded payment... Type: " << GetTypeString()
1597  << "\n----------\n";
1598 
1599  return (OTPayment::ERROR_STATE == m_Type) ? (-1) : 1;
1600  }
1601  else if (strNodeName.Compare("contents")) {
1602  OTString strContents;
1603 
1604  if (!OTContract::LoadEncodedTextField(xml, strContents) ||
1605  !strContents.Exists() || !SetPayment(strContents)) {
1606  otErr << "OTPayment::ProcessXMLNode: ERROR: \"contents\" field "
1607  "without a value, OR error setting that "
1608  "value onto this object. Raw:\n\n" << strContents
1609  << "\n\n";
1610 
1611  return (-1); // error condition
1612  }
1613  // else success -- the value is now set on this object.
1614  // todo security: Make sure the type of the payment that's ACTUALLY
1615  // there
1616  // matches the type expected (based on the m_Type that we already read,
1617  // above.)
1618 
1619  return 1;
1620  }
1621 
1622  return 0;
1623 }
1624 
1625 bool OTPayment::SaveContractWallet(std::ofstream&) const
1626 {
1627  return true;
1628 }
1629 
1630 } // namespace opentxs
EXPORT bool GetAmount(int64_t &lOutput) const
Definition: OTPayment.cpp:502
virtual void GetAllTransactionNumbers(OTNumList &numlistOutput) const
OTLOG_IMPORT OTLogStream otLog4
EXPORT void InitPayment()
Definition: OTPayment.cpp:1504
EXPORT bool GetClosingNum(int64_t &lOutput, const OTIdentifier &theAcctID) const
Definition: OTPayment.cpp:679
EXPORT bool GetServerID(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:993
#define OT_NUM_ELEM(blah)
paymentType m_Type
Definition: OTPayment.hpp:226
EXPORT bool GetRemitterAcctID(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:1050
EXPORT bool IsNymIDIncluded() const
Definition: Purse.hpp:268
EXPORT bool HasTransactionNum(const int64_t &lInput) const
Definition: OTPayment.cpp:608
EXPORT bool GetValidFrom(time64_t &tOutput) const
Definition: OTPayment.cpp:867
const OTIdentifier & GetSenderUserID() const
EXPORT Purse * InstantiatePurse() const
Definition: OTPayment.cpp:1359
time64_t GetValidTo() const
OTIdentifier m_RecipientUserID
Definition: OTPayment.hpp:258
int64_t GetTransactionNum() const
const int64_t & GetAmount() const
Definition: OTCheque.hpp:172
time64_t m_VALID_FROM
Definition: OTPayment.hpp:272
EXPORT bool SetTempValuesFromPaymentPlan(const OTPaymentPlan &theInput)
Definition: OTPayment.cpp:344
const OTIdentifier & GetAssetID() const
EXPORT bool GetAllTransactionNumbers(OTNumList &numlistOutput) const
Definition: OTPayment.cpp:533
const int64_t & GetInitialPaymentAmount() const
EXPORT bool GetTransactionNum(int64_t &lOutput) const
Definition: OTPayment.cpp:832
OTIdentifier m_RecipientAcctID
Definition: OTPayment.hpp:261
EXPORT bool SetPayment(const OTString &strPayment)
Definition: OTPayment.cpp:1456
EXPORT OTTrackable * Instantiate() const
Definition: OTPayment.cpp:1257
virtual void UpdateContents()
Definition: OTPayment.cpp:1559
OTIdentifier m_RemitterAcctID
Definition: OTPayment.hpp:267
const OTIdentifier & GetAssetID() const
Definition: Purse.hpp:335
static EXPORT Purse * PurseFactory(OTString strInput)
Definition: Purse.cpp:671
const OTIdentifier & GetRemitterAcctID() const
Definition: OTCheque.hpp:188
EXPORT bool GetAssetTypeID(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:963
EXPORT bool VerifyCurrentDate(bool &bVerified)
Definition: OTPayment.cpp:948
bool HasRecipient() const
Definition: OTCheque.hpp:180
virtual int64_t GetClosingNumber(const OTIdentifier &theAcctID) const
EXPORT void Concatenate(const char *arg,...)
Definition: OTString.cpp:1334
int64_t time64_t
Definition: Common.hpp:209
EXPORT bool GetOpeningNum(int64_t &lOutput, const OTIdentifier &theNymID) const
Definition: OTPayment.cpp:744
const OTString & GetMemo() const
Definition: OTCheque.hpp:168
EXPORT bool DecodeIfArmored(bool escapedIsAllowed=true)
Definition: OTString.cpp:1212
EXPORT bool Exists() const
Definition: OTString.cpp:1035
virtual EXPORT ~OTPayment()
Definition: OTPayment.cpp:1517
int64_t m_lTransactionNum
Definition: OTPayment.hpp:244
static EXPORT const char * _GetTypeString(paymentType theType)
Definition: OTPayment.cpp:171
EXPORT bool GetRecipientAcctID(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:1182
const OTIdentifier & GetServerID() const
time64_t GetValidFrom() const
EXPORT void Release_Payment()
Definition: OTPayment.cpp:1522
EXPORT bool Compare(const char *compare) const
Definition: OTString.cpp:1102
OTIdentifier m_AssetTypeID
Definition: OTPayment.hpp:249
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
Definition: OTString.cpp:1055
time64_t OTTimeGetCurrentTime()
Definition: Common.hpp:211
EXPORT bool GetSenderUserID(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:1087
EXPORT bool GetMemo(OTString &strOutput) const
Definition: OTPayment.cpp:468
char const *const __TypeStrings[]
Definition: OTAccount.cpp:161
OTIdentifier m_RemitterUserID
Definition: OTPayment.hpp:263
static EXPORT bool LoadEncodedTextField(irr::io::IrrXMLReader *&xml, OTASCIIArmor &ascOutput)
EXPORT bool GetSenderUserIDForDisplay(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:1073
int64_t GetTotalValue() const
Definition: Purse.hpp:292
virtual bool HasTransactionNum(const int64_t &lInput) const
OTIdentifier m_SenderAcctID
Definition: OTPayment.hpp:255
OTString m_strContractType
Definition: OTContract.hpp:178
OTString m_strPayment
Definition: OTPayment.hpp:224
bool HasRemitter() const
Definition: OTCheque.hpp:192
const OTString & GetConsideration() const
const OTIdentifier & GetRemitterUserID() const
Definition: OTCheque.hpp:184
EXPORT time64_t GetLatestValidFrom() const
Definition: Purse.cpp:1370
EXPORT bool GetSenderAcctID(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:1117
OTStringXML m_xmlUnsigned
Definition: OTContract.hpp:174
virtual bool HasTransactionNum(const int64_t &lInput) const
EXPORT bool SetTempValues()
Definition: OTPayment.cpp:196
EXPORT const char * GetTypeString() const
Definition: OTPayment.hpp:387
EXPORT const char * Get() const
Definition: OTString.cpp:1045
OTIdentifier m_ServerID
Definition: OTPayment.hpp:251
EXPORT bool GetSenderAcctIDForDisplay(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:1080
OTLOG_IMPORT OTLogStream otErr
virtual EXPORT int64_t GetOpeningNumber(const OTIdentifier &theNymID) const
EXPORT time64_t GetEarliestValidTo() const
Definition: Purse.cpp:1375
EXPORT bool GetValidTo(time64_t &tOutput) const
Definition: OTPayment.cpp:894
virtual EXPORT void Release()
Definition: OTPayment.cpp:1550
EXPORT bool SetTempValuesFromSmartContract(const OTSmartContract &theInput)
Definition: OTPayment.cpp:388
virtual EXPORT void Release()
Definition: OTContract.cpp:277
static EXPORT paymentType GetTypeFromString(const OTString &strType)
Definition: OTPayment.cpp:177
EXPORT bool IsExpired(bool &bExpired)
Definition: OTPayment.cpp:928
virtual int64_t GetOpeningNumber(const OTIdentifier &theNymID) const
const OTIdentifier & GetRecipientUserID() const
const OTIdentifier & GetSenderAcctID() const
EXPORT bool IsVoucher() const
Definition: OTPayment.hpp:281
EXPORT bool Contains(const char *compare) const
Definition: OTString.cpp:1137
virtual void GetAllTransactionNumbers(OTNumList &numlistOutput) const
const OTIdentifier & GetRecipientAcctID() const
virtual EXPORT int32_t ProcessXMLNode(irr::io::IrrXMLReader *&xml)
Definition: OTPayment.cpp:1582
#define OT_TIME_ZERO
Definition: Common.hpp:180
virtual EXPORT void Release()
Definition: OTData.cpp:257
EXPORT bool GetNymID(OTIdentifier &theOutput) const
Definition: Purse.cpp:154
EXPORT paymentType GetType() const
Definition: OTPayment.hpp:306
const OTIdentifier & GetRecipientUserID() const
Definition: OTCheque.hpp:176
virtual EXPORT bool SaveContractWallet(std::ofstream &ofs) const
Definition: OTPayment.cpp:1625
EXPORT bool GetRecipientUserID(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:1147
EXPORT bool GetRemitterUserID(OTIdentifier &theOutput) const
Definition: OTPayment.cpp:1023
virtual EXPORT void Release()
Definition: OTString.cpp:765
EXPORT bool SetTempValuesFromPurse(const Purse &theInput)
Definition: OTPayment.cpp:427
virtual int64_t GetClosingNumber(const OTIdentifier &theAcctID) const
OTIdentifier m_SenderUserID
Definition: OTPayment.hpp:253
EXPORT bool SetTempValuesFromCheque(const OTCheque &theInput)
Definition: OTPayment.cpp:279
const OTIdentifier & GetServerID() const
Definition: Purse.hpp:331