bool MTSendDlg::sendChequeLowLevel(int64_t amount, QString toNymId, QString fromAcctId, QString note, bool isInvoice) { QString nsChequeType = isInvoice ? QString("invoice") : QString("cheque"); // ------------------------------------------------------------ if (toNymId.size() == 0) { qDebug() << QString("Cannot send %1 to an empty nym id, aborting.").arg(nsChequeType); return false; } if (fromAcctId.size() == 0) { qDebug() << QString("Cannot send %1 from a non-existent account id, aborting.").arg(nsChequeType); return false; } if (amount <= 0) { qDebug() << QString("Why send 0 (or less) units? Aborting send %1.").arg(nsChequeType); return false; } // Note: in the case of cheques we don't have to see if the amount exceeds the // account balance here, since the money doesn't come out of the account until // the cheque is deposited by the recipient. Technically you could write a bad // cheque. Also, your balance will not change right away either -- not until the // recipient deposits the cheque. // Also of course, in the case of invoices, your account balance is irrelevant // since an invoice can only increase your balance, not decrease it. if (note.isEmpty()) note = tr("From the Qt systray app."); // ------------------------------------------------------------ std::string str_toNymId (toNymId .toStdString()); std::string str_fromAcctId(fromAcctId.toStdString()); // ------------------------------------------------------------ std::string str_fromNymId(OTAPI_Wrap::GetAccountWallet_NymID (str_fromAcctId)); std::string str_serverId (OTAPI_Wrap::GetAccountWallet_ServerID(str_fromAcctId)); // ------------------------------------------------------------ int64_t SignedAmount = amount; int64_t trueAmount = isInvoice ? (SignedAmount*(-1)) : SignedAmount; // ------------------------------------------------------------ qDebug() << QString("Sending %1:\n Server:'%2'\n Nym:'%3'\n Acct:'%4'\n ToNym:'%5'\n Amount:'%6'\n Note:'%7'"). arg(nsChequeType).arg(QString::fromStdString(str_serverId)).arg(QString::fromStdString(str_fromNymId)). arg(fromAcctId).arg(toNymId).arg(SignedAmount).arg(note); // ------------------------------------------------------------ time_t tFrom = OTAPI_Wrap::GetTime(); time_t tTo = tFrom + DEFAULT_CHEQUE_EXPIRATION; // ------------------------------------------------------------ std::string strCheque = OTAPI_Wrap::WriteCheque(str_serverId, trueAmount, tFrom, tTo, str_fromAcctId, str_fromNymId, note.toStdString(), str_toNymId); if (strCheque.empty()) { qDebug() << QString("Failed creating %1.").arg(nsChequeType); return false; } // ------------------------------------------------------------ OT_ME madeEasy; std::string strResponse; { MTOverrideCursor theSpinner; strResponse = madeEasy.send_user_payment(str_serverId, str_fromNymId, str_toNymId, strCheque); } int32_t nReturnVal = madeEasy.VerifyMessageSuccess(strResponse); if (1 != nReturnVal) qDebug() << QString("send %1: failed.").arg(nsChequeType); else { qDebug() << QString("Success in send %1!").arg(nsChequeType); return true; } // NOTE: We do not retrieve the account files here, in the case of success. // That's because none of them have changed yet from this operation -- not // until the recipient deposits the cheque. return false; }
bool MTSendDlg::sendCashierCheque(int64_t amount, QString toNymId, QString fromAcctId, QString note) { QString nsChequeType = QString("voucher"); // ------------------------------------------------------------ if (toNymId.size() == 0) { qDebug() << QString("Cannot send %1 to an empty nym id, aborting.").arg(nsChequeType); return false; } if (fromAcctId.size() == 0) { qDebug() << QString("Cannot send %1 from an unknown account id, aborting.").arg(nsChequeType); return false; } if (amount <= 0) { qDebug() << QString("Why send 0 (or less) units? Aborting send %1.").arg(nsChequeType); return false; } if (amount > MTHome::rawAcctBalance(m_myAcctId)) { qDebug() << QString("Aborting send %1: Amount is larger than account balance.").arg(nsChequeType); return false; } if (note.isEmpty()) note = tr("From the desktop systray app."); // ------------------------------------------------------------ std::string str_toNymId (toNymId .toStdString()); std::string str_fromAcctId(fromAcctId.toStdString()); // ------------------------------------------------------------ std::string str_fromNymId(OTAPI_Wrap::GetAccountWallet_NymID (str_fromAcctId)); std::string str_serverId (OTAPI_Wrap::GetAccountWallet_ServerID(str_fromAcctId)); // ------------------------------------------------------------ int64_t SignedAmount = amount; qDebug() << QString("Sending %1:\n Server:'%2'\n Nym:'%3'\n Acct:'%4'\n ToNym:'%5'\n Amount:'%6'\n Note:'%7'"). arg(nsChequeType).arg(str_serverId.c_str()).arg(str_fromNymId.c_str()).arg(str_fromAcctId.c_str()). arg(toNymId).arg(SignedAmount).arg(note); // ------------------------------------------------------------ OT_ME madeEasy; std::string strAttempt = "withdraw_voucher"; std::string strResponse; { MTOverrideCursor theSpinner; strResponse = madeEasy.withdraw_voucher(str_serverId, str_fromNymId, str_fromAcctId, str_toNymId, note.toStdString(), SignedAmount); } int32_t nInterpretReply = madeEasy.InterpretTransactionMsgReply(str_serverId, str_fromNymId, str_fromAcctId, strAttempt, strResponse); if (1 != nInterpretReply) // Failure { qDebug() << QString("Failure withdrawing voucher."); return false; } // --------------------------------------------------------- //else Success! std::string strLedger = OTAPI_Wrap::Message_GetLedger(strResponse); if (strLedger.empty()) { qDebug() << QString("Failed withdrawing voucher: strLedger is empty."); return false; } // --------------------------------------------------------- std::string strTransReply = OTAPI_Wrap::Ledger_GetTransactionByIndex(str_serverId, str_fromNymId, str_fromAcctId, strLedger, 0); // index 0. if (strTransReply.empty()) { qDebug() << QString("Error in withdraw_voucher: strTransReply is unexpectedly null, " "returned by Ledger_GetTransactionByIndex, argument passed, index 0 and ledger:\n\n%s1\n"). arg(strLedger.c_str()); return false; } // --------------------------------------------------------- std::string strVoucher = OTAPI_Wrap::Transaction_GetVoucher(str_serverId, str_fromNymId, str_fromAcctId, strTransReply); if (strVoucher.empty()) { qDebug() << QString("Error in withdraw_voucher: Voucher is unexpectedly empty, returned by Transaction_GetVoucher " "with strTransReply set to:\n\n%1\n").arg(strTransReply.c_str()); return false; } else { // Save a copy in my own outpayments box. I don't want to lose this voucher since it uses // one of my own transaction numbers. (If I later send the voucher to someone, OT is smart // enough to remove the first copy from outpayments, when adding the second copy.) // // Notice how I can send an instrument to myself. This doesn't actually send anything -- // it just puts a copy into my outpayments box for safe-keeping. // OT_ME sendToSelf; sendToSelf.send_user_payment(str_serverId, str_fromNymId, str_fromNymId, strVoucher); } // --------------------------------------------------------- // Download all the intermediary files (account balance, inbox, outbox, etc) // since they have probably changed from this operation. // OT_ME retrieveAcct; bool bRetrieved = false; { MTOverrideCursor theSpinner; bRetrieved = retrieveAcct.retrieve_account(str_serverId, str_fromNymId, str_fromAcctId, true); //bForceDownload defaults to false. } qDebug() << QString("%1 retrieving intermediary files for account %2. (After withdraw voucher.)"). arg(bRetrieved ? QString("Success") : QString("Failed")).arg(str_fromAcctId.c_str()); // --------------------------------------------------------- // We try to send it, even if the retrieve_account failed. // That way we insure that a copy of the voucher is stored // in the outpayment box. (Even if it fails to send.) // That way the user can later cancel or re-send it. // //OTLog::vOutput(0, "Sending payment to NymID: %s\n", str_toNymId.c_str()); OT_ME sendPayment; std::string strSendResponse; { MTOverrideCursor theSpinner; strSendResponse = sendPayment.send_user_payment(str_serverId, str_fromNymId, str_toNymId, strVoucher); } int32_t nReturnVal = sendPayment.VerifyMessageSuccess(strSendResponse); if (1 != nReturnVal) qDebug() << QString("send %1: Failed.").arg(nsChequeType); else { qDebug() << QString("Success in send %1!").arg(nsChequeType); return true; } return false; }