home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / software / pelne / optionp / mts4.cab / Account.VC_MoveMoney.cpp < prev    next >
C/C++ Source or Header  |  1997-11-14  |  5KB  |  218 lines

  1. // Filename: MoveMoney.cpp
  2. //
  3. // Description: Implementation of CMoveMoney
  4. //
  5. // This file is provided as part of the Microsoft Transaction Server
  6. // Software Development Kit
  7. //
  8. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT 
  9. // WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 
  10. // INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
  11. // OF MERCHANTABILITY AND/OR FITNESS FOR A  PARTICULAR 
  12. // PURPOSE.
  13. //
  14. // Copyright (C) 1997 Microsoft Corporation, All rights reserved
  15.  
  16. #include "stdafx.h"
  17. #include "Account.h"
  18. #include "MoveMoney.h"
  19. #include "Account.h"
  20. #include "GetReceipt.h"
  21.  
  22. #include <mtx.h>
  23. #include <comdef.h>
  24.  
  25. /////////////////////////////////////////////////////////////////////////////
  26. //
  27.  
  28. STDMETHODIMP CMoveMoney::InterfaceSupportsErrorInfo(REFIID riid)
  29. {
  30.     static const IID* arr[] = 
  31.     {
  32.         &IID_IMoveMoney,
  33.     };
  34.     
  35.     for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
  36.     {
  37.         if (InlineIsEqualGUID(*arr[i],riid))
  38.             return S_OK;
  39.     }
  40.     return S_FALSE;
  41. }
  42.  
  43. //    Perform: modifies the specified account by the specified amount
  44. //
  45. //    pvResult: a BSTR giving information.  NOTE: this is set to NULL when an error occurs
  46. //
  47. //    returns:  S_OK or E_FAIL
  48.  
  49. STDMETHODIMP CMoveMoney::Perform (IN long lPrimeAccount, IN long lSecondAccount, IN long lAmount, 
  50.                                   IN long lTranType, OUT BSTR* pbstrResult) {
  51.     USES_CONVERSION;
  52.     
  53.     HRESULT hr = S_OK;
  54.  
  55.     IObjectContext* pObjectContext = NULL;
  56.  
  57.     IAccount* pObjAccount = NULL;
  58.     IGetReceipt* pObjGetReceipt = NULL;
  59.  
  60.     long lErrFlag = 0;
  61.     TCHAR* pErrMsg = NULL;
  62.  
  63.     BSTR bstrResult2 = NULL;
  64.     BSTR bstrCall1 = NULL;
  65.     BSTR bstrCall2 = NULL;
  66.  
  67.     *pbstrResult = NULL;
  68.  
  69.     try {
  70.  
  71.         // Get the object context
  72.         THROW_ERR ( GetObjectContext (&pObjectContext), "GetObjectContext" );
  73.  
  74.         // Check security for large transfers
  75.         if (lAmount > 500 || lAmount < -500) {
  76.  
  77.             BOOL bInRole;
  78.             BSTR bstrRole = ::SysAllocString (L"Managers");
  79.             hr = pObjectContext->IsCallerInRole (bstrRole, &bInRole);
  80.             ::SysFreeString(bstrRole);
  81.             
  82.             if (!SUCCEEDED ( hr )) {
  83.  
  84.                 THROW_STR ( _T("IsCallerInRole() call failed!  Please add the 'Managers' Roll to the package."));
  85.             }
  86.             
  87.             if (!bInRole) {
  88.                 THROW_STR ( _T("Need 'Managers' role for amounts over $500") );
  89.             }
  90.         }
  91.         
  92.         // Create the account object using our context
  93.         THROW_ERR ( pObjectContext->CreateInstance(CLSID_CAccount, IID_IAccount, (void**)&pObjAccount),
  94.             "CreateInstance(CLSID_CAccount)" );
  95.  
  96.         // Call the post function based on the transaction type
  97.         switch ( lTranType )
  98.         {
  99.         case (1):    // debit
  100.             RETHROW_ERR ( pObjAccount->Post (lPrimeAccount, 0 - lAmount, &bstrResult2) );
  101.             break;
  102.  
  103.         case (2):    // credit
  104.             RETHROW_ERR ( pObjAccount->Post (lPrimeAccount, lAmount, &bstrResult2) );
  105.             break;
  106.  
  107.         case (3):    // transfer
  108.             // Do the credit
  109.             RETHROW_ERR ( pObjAccount->Post (lSecondAccount, lAmount, &bstrCall1) );
  110.             
  111.             // Then do the debit
  112.             RETHROW_ERR ( pObjAccount->Post (lPrimeAccount, 0 - lAmount, &bstrCall2) );
  113.  
  114.             // Prepare return string
  115.             TCHAR szBuf [512];
  116.             _tcscpy (szBuf, W2T( bstrCall1 ));
  117.             _tcscat (szBuf, _T("; "));
  118.             _tcscat (szBuf, W2T( bstrCall2 ));
  119.             bstrResult2 = TCHAR2BSTR (szBuf);
  120.             break;
  121.  
  122.         default:
  123.             THROW_STR ( _T("Invalid Transaction Type") );
  124.         }
  125.  
  126.         // Get Receipt Number for the transaction
  127.         THROW_ERR ( pObjectContext->CreateInstance (CLSID_CGetReceipt, IID_IGetReceipt, (void**)&pObjGetReceipt),
  128.             "CreateInstance(CLSID_CGetReceipt)" );
  129.         long lngReceiptNo;
  130.         RETHROW_ERR ( pObjGetReceipt->GetNextReceipt(&lngReceiptNo) );
  131.  
  132.         // Tag receipt information onto return string
  133.  
  134.         TCHAR szBuffer [512];
  135.         wsprintf (szBuffer, _T("; Receipt No:  %li"), lngReceiptNo);
  136.         BSTR bstrTemp = TCHAR2BSTR (szBuffer);
  137.  
  138.         TCHAR szBuffer2 [512];
  139.         _tcscpy (szBuffer2, W2T ( bstrResult2 ));
  140.         _tcscat (szBuffer2, W2T ( bstrTemp ));
  141.         ::SysFreeString (bstrTemp);
  142.  
  143.         *pbstrResult = TCHAR2BSTR (szBuffer2);
  144.  
  145.          // We are finished and happy
  146.         pObjectContext->SetComplete();
  147.         hr = S_OK;
  148.  
  149.     } catch (HRESULT hr) {
  150.     
  151.         //
  152.         //    store error info locally
  153.         //
  154.  
  155.         IErrorInfo * pErrorInfo = NULL;
  156.         GetErrorInfo(NULL, &pErrorInfo);
  157.         
  158.         // Fill in error information
  159.         switch (lErrFlag) {
  160.         
  161.         // Unknown error occurred in this object
  162.         case (0):
  163.             TCHAR szErr [512];
  164.             wsprintf (szErr, _T("Error 0x%x from CMoveMoney calling %s."), hr, pErrMsg);
  165.             pErrMsg = szErr;
  166.             // Fall through
  167.         
  168.         // An application error occurred in this object
  169.         case (1):
  170.             //
  171.             //    we are going to put our own error in TLS, so if there is one there, clear it
  172.             //
  173.             if (pErrorInfo)
  174.                 pErrorInfo -> Release();
  175.     
  176.             AtlReportError( CLSID_CMoveMoney, pErrMsg, IID_IMoveMoney, hr);
  177.             break;
  178.         
  179.         case (2):// An error occurred in a called object
  180.             //
  181.             //    put the error back in TLS
  182.             //
  183.             SetErrorInfo(NULL, pErrorInfo);
  184.             break;
  185.         
  186.         // Will never reach here
  187.         default:
  188.             break;
  189.         }
  190.  
  191.         
  192.         // Indicate our unhappiness
  193.         if (pObjectContext)
  194.             pObjectContext->SetAbort();
  195.     }
  196.  
  197.  
  198.     // Release resources
  199.     if (pObjAccount)
  200.         pObjAccount->Release();
  201.     
  202.     if (pObjectContext)
  203.         pObjectContext->Release();
  204.  
  205.     if (pObjGetReceipt)
  206.         pObjGetReceipt->Release();
  207.  
  208.     if (bstrResult2)
  209.         ::SysFreeString (bstrResult2);
  210.  
  211.     if (bstrCall1)
  212.         ::SysFreeString (bstrCall1);
  213.  
  214.     if (bstrCall2)
  215.         ::SysFreeString (bstrCall2);
  216.  
  217.     return hr;
  218. }