コード例 #1
0
ファイル: MTRecord.cpp プロジェクト: kazcw/Moneychanger
// ---------------------------------------
void  MTRecord::SetContents      (const std::string & str_contents)
{
    m_str_contents = str_contents;

    if (!m_str_contents.empty() && (MTRecord::Instrument == this->GetRecordType()))
    {
        OTString  strPayment(m_str_contents);
        OTPayment thePayment(strPayment);

        if (thePayment.IsValid() && thePayment.SetTempValues())
        {
            switch (thePayment.GetType())
            {
                case OTPayment::PURSE:          m_bIsCash           = true;  break;
                case OTPayment::CHEQUE:         m_bIsCheque         = true;  break;
                case OTPayment::VOUCHER:        m_bIsVoucher        = true;  break;
                case OTPayment::INVOICE:        m_bIsInvoice        = true;  break;
                case OTPayment::PAYMENT_PLAN:   m_bIsPaymentPlan    = true;  break;
                case OTPayment::SMART_CONTRACT: m_bIsSmartContract  = true;  break;

                default:
                    break;
            }
        }
    }
}
コード例 #2
0
ファイル: MTRecord.cpp プロジェクト: kazcw/Moneychanger
// ---------------------------------------
// For outgoing, pending (not-yet-accepted) instruments.
//
bool MTRecord::CancelOutgoing(const std::string str_via_acct) // This can be blank if it's a cheque.
{
    if (!this->CanCancelOutgoing())
        return false;

    switch (this->GetRecordType())
    {
        case MTRecord::Instrument:
        {
            if (m_str_nym_id.empty())
            {
                OTLog::vError("%s: Error: missing nym id (%s)\n",
                              __FUNCTION__, m_str_nym_id.c_str());
                return false;
            }

            const OTIdentifier theNymID(m_str_nym_id);
            // ------------------------------
            std::string str_using_acct;

            if (this->IsCheque())
            {
                str_using_acct = m_str_account_id;
            }
            else
            {
                str_using_acct = str_via_acct;
            }
            // ---------------------------------------
            if (str_using_acct.empty())
            {
                OTLog::vError("%s: Error: Missing account ID (FAILURE)\n", __FUNCTION__);
                return false;
            }
            // ------------------------------
            if (0 == m_lTransactionNum)
            {
                if (IsCash())
                {
                    // Maybe it's cash...
                    std::string strOutpayment(OTAPI_Wrap::GetNym_OutpaymentsContentsByIndex(m_str_nym_id, GetBoxIndex()));

                    if (strOutpayment.empty())
                    {
                        long lIndex = static_cast<long>(GetBoxIndex());
                        OTLog::vError("%s: Error: Blank outpayment at index %ld\n", __FUNCTION__, lIndex);
                        return false;
                    }
                    // ------------------------
                    OTString  strPayment(strOutpayment);
                    OTPayment thePayment(strPayment);

                    if (!thePayment.IsValid() || !thePayment.SetTempValues())
                    {
                        long lIndex = static_cast<long>(GetBoxIndex());
                        OTLog::vError("%s: Error: Invalid outpayment at index %ld\n", __FUNCTION__, lIndex);
                        return false;
                    }
                    // ------------------------
                    long lTransNum = 0;
                    thePayment.GetOpeningNum(lTransNum, theNymID);
                    // ------------------------
                    if (0 == lTransNum) // Found it.
                    {
                        long lIndex = static_cast<long>(GetBoxIndex());
                        OTString strIndices;
                        strIndices.Format("%ld", lIndex);
                        const std::string str_indices(strIndices.Get());
                        // ---------------------------------
                        OT_ME madeEasy;

                        return madeEasy.cancel_outgoing_payments(m_str_nym_id, str_using_acct, str_indices);
                    }
                    else
                    {
                        OTLog::vError("%s: Error: Transaction number is non-zero (%ld), for cash outgoing payment for nym id (%s)\n",
                                      __FUNCTION__, lTransNum, m_str_nym_id.c_str());
                        return false;
                    }
                } // IsCash()
                else
                {
                    OTLog::vError("%s: Error: Transaction number is 0, for non-cash outgoing payment for nym id (%s)\n",
                                  __FUNCTION__, m_str_nym_id.c_str());
                    return false;
                }
            }
            // ---------------------------------------
            // Find the payment in the Nym's outpayments box that correlates to this MTRecord.
            //
            int32_t nCount = OTAPI_Wrap::GetNym_OutpaymentsCount(m_str_nym_id);

            for (int32_t nIndex = 0; nIndex < nCount; ++nIndex)
            {
                std::string strOutpayment(OTAPI_Wrap::GetNym_OutpaymentsContentsByIndex(m_str_nym_id, nIndex));

                if (strOutpayment.empty())
                {
                    long lIndex = nIndex;
                    OTLog::vError("%s: Error: Blank outpayment at index %ld\n", __FUNCTION__, lIndex);
                    return false;
                }
                // ------------------------
                OTString  strPayment(strOutpayment);
                OTPayment thePayment(strPayment);

                if (!thePayment.IsValid() || !thePayment.SetTempValues())
                {
                    long lIndex = nIndex;
                    OTLog::vError("%s: Error: Invalid outpayment at index %ld\n", __FUNCTION__, lIndex);
                    return false;
                }
                // ------------------------
                long lTransNum = 0;
                thePayment.GetOpeningNum(lTransNum, theNymID);
                // ------------------------
                if (lTransNum == m_lTransactionNum) // Found it.
                {
                    long lIndex = nIndex;
                    OTString strIndices;
                    strIndices.Format("%ld", lIndex);
                    const std::string str_indices(strIndices.Get());
                    // ---------------------------------
                    OT_ME madeEasy;

                    return madeEasy.cancel_outgoing_payments(m_str_nym_id, str_using_acct, str_indices);
                }
            } // for
            // ---------------------------------------------------
        }
            break;
        // -----------------------------
        default:
            OTLog::vError("%s: Unexpected type: %s\n",
                          __FUNCTION__, this->GetInstrumentType().c_str());
            return false;
    }

    return true;
}
コード例 #3
0
// PayDividendVisitor::Trigger() is used in
// OTUnitDefinition::VisitAccountRecords()
// cppcheck-suppress unusedFunction
bool PayDividendVisitor::Trigger(Account& theSharesAccount) // theSharesAccount
                                                            // is, say, a Pepsi
                                                            // shares
// account.  Here, we'll send a dollars voucher
// to its owner.
{
    const int64_t lPayoutAmount =
        (theSharesAccount.GetBalance() * GetPayoutPerShare());

    if (lPayoutAmount <= 0) {
        Log::Output(0, "PayDividendVisitor::Trigger: nothing to pay, "
                       "since this account owns no shares. (Returning "
                       "true.)");
        return true; // nothing to pay, since this account owns no shares.
                     // Success!
    }
    OT_ASSERT(nullptr != GetNotaryID());
    const Identifier& theNotaryID = *(GetNotaryID());
    OT_ASSERT(nullptr != GetPayoutInstrumentDefinitionID());
    const Identifier& thePayoutInstrumentDefinitionID =
        *(GetPayoutInstrumentDefinitionID());
    OT_ASSERT(nullptr != GetVoucherAcctID());
    const Identifier& theVoucherAcctID = *(GetVoucherAcctID());
    OT_ASSERT(nullptr != GetServer());
    OTServer& theServer = *(GetServer());
    Nym& theServerNym = const_cast<Nym&>(theServer.GetServerNym());
    const Identifier theServerNymID(theServerNym);
    const Identifier& RECIPIENT_ID = theSharesAccount.GetNymID();
    OT_ASSERT(nullptr != GetNymID());
    const Identifier& theSenderNymID = *(GetNymID());
    OT_ASSERT(nullptr != GetMemo());
    const String& strMemo = *(GetMemo());
    // Note: theSenderNymID is the originator of the Dividend Payout.
    // However, all the actual vouchers will be from "the server Nym" and
    // not from theSenderNymID. So then why is it even here? Because anytime
    // there's an error, the server will send to theSenderNymID instead of
    // RECIPIENT_ID (so the original sender can have his money back, instead of
    // just having it get lost in the ether.)
    bool bReturnValue = false;

    Cheque theVoucher(theNotaryID, thePayoutInstrumentDefinitionID);

    // 10 minutes ==    600 Seconds
    // 1 hour    ==     3600 Seconds
    // 1 day    ==    86400 Seconds
    // 30 days    ==  2592000 Seconds
    // 3 months ==  7776000 Seconds
    // 6 months == 15552000 Seconds

    const time64_t VALID_FROM =
        OTTimeGetCurrentTime(); // This time is set to TODAY NOW
    const time64_t VALID_TO = OTTimeAddTimeInterval(
        VALID_FROM, OTTimeGetSecondsFromTime(
                        OT_TIME_SIX_MONTHS_IN_SECONDS)); // This time occurs in
                                                         // 180 days (6 months).
                                                         // Todo hardcoding.

    int64_t lNewTransactionNumber = 0;

    bool bGotNextTransNum =
        theServer.transactor_.issueNextTransactionNumberToNym(
            theServerNym, lNewTransactionNumber); // We save the transaction
    // number on the server Nym (normally we'd discard it) because
    // when the cheque is deposited, the server nym, as the owner of
    // the voucher account, needs to verify the transaction # on the
    // cheque (to prevent double-spending of cheques.)
    if (bGotNextTransNum) {
        const bool bIssueVoucher = theVoucher.IssueCheque(
            lPayoutAmount,         // The amount of the cheque.
            lNewTransactionNumber, // Requiring a transaction number prevents
                                   // double-spending of cheques.
            VALID_FROM, // The expiration date (valid from/to dates) of the
                        // cheque
            VALID_TO, // Vouchers are automatically starting today and lasting 6
                      // months.
            theVoucherAcctID, // The asset account the cheque is drawn on.
            theServerNymID,   // Nym ID of the sender (in this case the server
                              // nym.)
            strMemo, // Optional memo field. Includes item note and request
                     // memo.
            &RECIPIENT_ID);

        // All account crediting / debiting happens in the caller, in OTServer.
        //    (AND it happens only ONCE, to cover ALL vouchers.)
        // Then in here, the voucher either gets send to the recipient, or if
        // error, sent back home to
        // the issuer Nym. (ALL the funds are removed, then the vouchers are
        // sent one way or the other.)
        // Any returned vouchers, obviously serve to notify the dividend payer
        // of where the errors were
        // (as well as give him the opportunity to get his money back.)
        //
        bool bSent = false;
        if (bIssueVoucher) {
            // All this does is set the voucher's internal contract string to
            // "VOUCHER" instead of "CHEQUE". We also set the server itself as
            // the remitter, which is unusual for vouchers, but necessary in the
            // case of dividends.
            //
            theVoucher.SetAsVoucher(theServerNymID, theVoucherAcctID);
            theVoucher.SignContract(theServerNym);
            theVoucher.SaveContract();

            // Send the voucher to the payments inbox of the recipient.
            //
            const String strVoucher(theVoucher);
            OTPayment thePayment(strVoucher);

            // calls DropMessageToNymbox
            bSent = theServer.SendInstrumentToNym(
                theNotaryID, theServerNymID,          // sender nym
                RECIPIENT_ID,                         // recipient nym
                nullptr, &thePayment, "payDividend"); // todo: hardcoding.
            bReturnValue = bSent;                     // <======= RETURN VALUE.
            if (bSent)
                m_lAmountPaidOut +=
                    lPayoutAmount; // At the end of iterating all accounts, if
                                   // m_lAmountPaidOut is less than
                                   // lTotalPayoutAmount, then we return to rest
                                   // to the sender.
        }
        else {
            const String strPayoutInstrumentDefinitionID(
                thePayoutInstrumentDefinitionID),
                strRecipientNymID(RECIPIENT_ID);
            Log::vError("PayDividendVisitor::Trigger: ERROR failed "
                        "issuing voucher (to send to dividend payout "
                        "recipient.) "
                        "WAS TRYING TO PAY %" PRId64
                        " of instrument definition %s to Nym %s.\n",
                        lPayoutAmount, strPayoutInstrumentDefinitionID.Get(),
                        strRecipientNymID.Get());
        }
        // If we didn't send it, then we need to return the funds to where they
        // came from.
        //
        if (!bSent) {
            Cheque theReturnVoucher(theNotaryID,
                                    thePayoutInstrumentDefinitionID);

            const bool bIssueReturnVoucher = theReturnVoucher.IssueCheque(
                lPayoutAmount,         // The amount of the cheque.
                lNewTransactionNumber, // Requiring a transaction number
                                       // prevents double-spending of cheques.
                VALID_FROM, // The expiration date (valid from/to dates) of the
                            // cheque
                VALID_TO,   // Vouchers are automatically starting today and
                            // lasting 6 months.
                theVoucherAcctID, // The asset account the cheque is drawn on.
                theServerNymID,   // Nym ID of the sender (in this case the
                                  // server nym.)
                strMemo, // Optional memo field. Includes item note and request
                         // memo.
                &theSenderNymID); // We're returning the money to its original
                                  // sender.
            if (bIssueReturnVoucher) {
                // All this does is set the voucher's internal contract string
                // to
                // "VOUCHER" instead of "CHEQUE".
                //
                theReturnVoucher.SetAsVoucher(theServerNymID, theVoucherAcctID);
                theReturnVoucher.SignContract(theServerNym);
                theReturnVoucher.SaveContract();

                // Return the voucher back to the payments inbox of the original
                // sender.
                //
                const String strReturnVoucher(theReturnVoucher);
                OTPayment theReturnPayment(strReturnVoucher);

                // calls DropMessageToNymbox
                bSent = theServer.SendInstrumentToNym(
                    theNotaryID, theServerNymID, // sender nym
                    theSenderNymID, // recipient nym (original sender.)
                    nullptr, &theReturnPayment,
                    "payDividend"); // todo: hardcoding.
                if (bSent)
                    m_lAmountReturned +=
                        lPayoutAmount; // At the end of iterating all accounts,
                                       // if m_lAmountPaidOut+m_lAmountReturned
                                       // is less than lTotalPayoutAmount, then
                                       // we return the rest to the sender.
            }
            else {
                const String strPayoutInstrumentDefinitionID(
                    thePayoutInstrumentDefinitionID),
                    strSenderNymID(theSenderNymID);
                Log::vError("PayDividendVisitor::Trigger: ERROR "
                            "failed issuing voucher (to return back to "
                            "the dividend payout initiator, after a failed "
                            "payment attempt to the originally intended "
                            "recipient.) WAS TRYING TO PAY %" PRId64
                            " of instrument definition "
                            "%s to Nym %s.\n",
                            lPayoutAmount,
                            strPayoutInstrumentDefinitionID.Get(),
                            strSenderNymID.Get());
            }
        }  // if !bSent
    }
    else // !bGotNextTransNum
    {
        const String strPayoutInstrumentDefinitionID(
            thePayoutInstrumentDefinitionID),
            strRecipientNymID(RECIPIENT_ID);
        Log::vError(
            "PayDividendVisitor::Trigger: ERROR!! Failed issuing next "
            "transaction "
            "number while trying to send a voucher (while paying dividends.) "
            "WAS TRYING TO PAY %" PRId64
            " of instrument definition %s to Nym %s.\n",
            lPayoutAmount, strPayoutInstrumentDefinitionID.Get(),
            strRecipientNymID.Get());
    }

    return bReturnValue;
}