/**
  * Execute a command and return a response. Does not render
  * @param IRequest $Request
  * @return IResponse the execution response
  */
 function execute(IRequest $Request)
 {
     $TransactionEntry = TransactionEntry::get($this->getTransactionID());
     $transactionLog = $TransactionEntry->fetchLog();
     $Invoice = $TransactionEntry->getInvoice();
     $Product = $Invoice->getProduct();
     $Wallet = $Invoice->getWallet();
     $accounts = array();
     $merchantProfit = $Product->calculateProfit($TransactionEntry->getStatus(), $accounts);
     $accounts[$Product->getAccountID()] = $merchantProfit;
     $ProfitTBody = new HTMLSequenceTableBody(new CallbackSequenceMap(function (ISequenceMapper $Map) use($accounts) {
         foreach ($accounts as $accountID => $profit) {
             $Map->mapNext(array('account' => $accountID, 'profit' => $profit));
         }
     }));
     $Form = new HTMLForm(self::FORM_METHOD, $Request->getPath(), self::FORM_NAME, new HTMLMetaTag(HTMLMetaTag::META_TITLE, self::TITLE), new HTMLHeaderScript(__DIR__ . '/assets/transaction.js'), new HTMLHeaderStyleSheet(__DIR__ . '/assets/transaction.css'), new HTMLElement('fieldset', 'fieldset-transaction-info inline', new HTMLElement('legend', 'legend-transaction-info', 'Transaction Information'), new MapRenderer($TransactionEntry)), new HTMLElement('fieldset', 'fieldset-product-profit inline', new HTMLElement('legend', 'legend-product-profit', 'Profit Information'), new HTMLTable($ProfitTBody)), "<br/>", new HTMLElement('fieldset', 'fieldset-product-container inline', new HTMLElement('legend', 'legend-product', 'Order Information'), $Wallet->getFieldSet($Request)->setAttribute('disabled', 'disabled'), $Product->getOrderFieldSet($Request)->setAttribute('disabled', 'disabled'), $Product->getConfigFieldSet($Request)->setAttribute('disabled', 'disabled'), $Product->getFeesFieldSet($Request)->setAttribute('disabled', 'disabled'), "<br/><br/>", new HTMLButton('submit', 'Update', 'submit')), "<br/>", new HTMLElement('fieldset', 'fieldset-transaction-log inline', new HTMLElement('legend', 'legend-transaction-log', 'Transaction Log'), new HTMLTextAreaField(self::PARAM_LOG . '_disabled', $transactionLog, new Attributes('rows', 10, 'cols', 100), new Attributes('disabled', 'disabled')), "<br/>", new HTMLTextAreaField(self::PARAM_LOG, new Attributes('rows', 3, 'cols', 100)), "<br/>", new HTMLButton(self::PARAM_SUBMIT, 'Append', 'append-log')), new HTMLElement('fieldset', 'fieldset-transaction-manage inline', new HTMLElement('legend', 'legend-submit', self::TITLE), new HTMLInputField(self::PARAM_ID, $this->id, 'hidden', new RequiredValidation()), new HTMLElement('label', null, "Status<br/>", $SelectStatus = new HTMLSelectField(self::PARAM_TRANSACTION_STATUS, TransactionEntry::$StatusOptions, new RequiredValidation())), "<br/><br/>", new HTMLButton(self::PARAM_SUBMIT, 'Update', 'submit')), "<br/>");
     $SelectStatus->setInputValue($TransactionEntry->getStatus());
     if (!$Request instanceof IFormRequest) {
         return $Form;
     }
     switch ($Request[self::PARAM_SUBMIT]) {
         case 'submit':
             $status = $Form->validateField($Request, self::PARAM_TRANSACTION_STATUS);
             $TransactionEntry->update($Request, $status);
             ProfitEntry::update($Request, $TransactionEntry->getID());
             return new RedirectResponse(ManageTransaction::getRequestURL($TransactionEntry->getID()), "Transaction updated successfully. Redirecting...", 5);
         case 'append-log':
             $appendLog = $Request[self::PARAM_LOG];
             $TransactionEntry->appendLog($appendLog);
             return new RedirectResponse(ManageTransaction::getRequestURL($TransactionEntry->getID()), "Log appended successfully. Redirecting...", 5);
         default:
             throw new \InvalidArgumentException("Invalid Submit");
     }
 }
 /**
  * Execute a command and return a response. Does not render
  * @param IRequest $Request
  * @throws \Exception
  * @return IResponse the execution response
  */
 function execute(IRequest $Request)
 {
     $SessionRequest = $Request;
     if (!$SessionRequest instanceof ISessionRequest) {
         throw new \Exception("Session required");
     }
     $ProductForms = array();
     /** @var AbstractWallet[] $WalletTypes */
     $WalletTypes = array();
     $walletOptions = array('Choose a Wallet' => null);
     $WalletForms = array();
     $Products = ProductEntry::loadSessionProducts($SessionRequest);
     $productOptions = array('Choose a Product' => null);
     foreach ($Products as $ProductEntry) {
         $Product = $ProductEntry->getProduct();
         $productOptions[$Product->getTotalCost() . ' - ' . $Product->getProductTitle()] = $ProductEntry->getID();
         $Product = $ProductEntry->getProduct();
         $FieldSet = $Product->getOrderFieldSet($Request);
         $key = $ProductEntry->getID();
         $FieldSet->setAttribute('data-' . self::PARAM_PRODUCT_ID, $key);
         $ProductForms[] = $FieldSet;
         foreach ($Product->getWalletTypes() as $WalletType) {
             $key = $WalletType->getTypeName();
             $WalletTypes[$key] = $WalletType;
             $FieldSet = $WalletType->getFieldSet($Request);
             $FieldSet->setAttribute('data-' . self::PARAM_WALLET_ID, $key);
             $FieldSet->setAttribute('disabled', 'disabled');
             $WalletForms[] = $FieldSet;
             $walletOptions['New ' . $WalletType->getDescription()] = $key;
         }
     }
     $SessionWalletEntries = AbstractWallet::loadSessionWallets($SessionRequest);
     foreach ($SessionWalletEntries as $WalletEntry) {
         $Wallet = $WalletEntry->getWallet();
         $key = $WalletEntry->getID();
         $WalletTypes[$key] = $Wallet;
         $FieldSet = $Wallet->getFieldSet($Request);
         $FieldSet->setAttribute('data-' . self::PARAM_WALLET_ID, $key);
         $FieldSet->setAttribute('disabled', 'disabled');
         $WalletForms[] = $FieldSet;
         $walletOptions[$Wallet->getTitle() . ' - ' . $Wallet->getDescription()] = $key;
     }
     //		$walletTypes = Config::$AvailableWalletTypes;
     $Form = new HTMLForm(self::FORM_METHOD, self::FORM_ACTION, self::FORM_NAME, new HTMLMetaTag(HTMLMetaTag::META_TITLE, self::TITLE), new HTMLHeaderScript(__DIR__ . '/assets/transaction.js'), new HTMLHeaderStyleSheet(__DIR__ . '/assets/transaction.css'), new HTMLElement('fieldset', 'fieldset-create-transaction', new HTMLElement('legend', 'legend-wallet', self::TITLE), new HTMLElement('fieldset', 'fieldset-transaction', new HTMLElement('legend', 'legend-transaction', 'Transaction Details'), new HTMLElement('label', null, "Status<br/>", new HTMLSelectField(self::PARAM_TRANSACTION_STATUS, TransactionEntry::$StatusOptions, new RequiredValidation())), "<br/><br/>", new HTMLElement('label', null, "Product<br/>", new HTMLSelectField(self::PARAM_PRODUCT_ID, $productOptions, new RequiredValidation())), "<br/><br/>", $ProductForms), new HTMLElement('fieldset', 'fieldset-choose-wallet', new HTMLElement('legend', 'legend-wallet', 'Choose a Wallet'), new HTMLElement('label', null, new HTMLSelectField(self::PARAM_WALLET_ID, $walletOptions, new RequiredValidation())), "<br/><br/>", $WalletForms), "<br/><br/>Submit:<br/>", new HTMLButton('submit', 'Create Transaction', 'submit')), "<br/>");
     if (!$Request instanceof IFormRequest) {
         return $Form;
     }
     $Form->setFormValues($Request);
     //		$status = (int)$Form->validateField($Request, self::PARAM_TRANSACTION_STATUS);
     //		$email = $Form->validateField($Request, self::PARAM_TRANSACTION_EMAIL);
     $walletType = $Form->validateField($Request, self::PARAM_WALLET_ID);
     $ChosenWallet = $WalletTypes[$walletType];
     $ChosenWallet->validateRequest($Request, $Form);
     $productID = $Form->validateField($Request, self::PARAM_PRODUCT_ID);
     $ProductEntry = ProductEntry::get($productID);
     $Product = $ProductEntry->getProduct();
     $Invoice = $Product->createNewInvoice($Request, $ChosenWallet);
     $responses = array();
     foreach (PaymentSourceEntry::getActiveSources() as $PaymentSourceEntry) {
         $PaymentSource = $PaymentSourceEntry->getPaymentSource();
         if ($PaymentSource->supportsWalletType($ChosenWallet)) {
             $Response = $PaymentSource->executeWalletTransaction($ChosenWallet);
             $responses[] = $Response->getMessage();
             $paymentSourceID = $PaymentSourceEntry->getID();
             $walletID = WalletEntry::createOrUpdate($Request, $ChosenWallet);
             if ($Response->getCode() === TransactionEntry::STATUS_APPROVED) {
                 $status = TransactionEntry::STATUS_APPROVED;
                 $id = TransactionEntry::create($Request, $Invoice, $status, $walletID, $productID, $paymentSourceID);
                 ProfitEntry::update($Request, $id);
                 return new RedirectResponse(ManageTransaction::getRequestURL($id), "Transaction created successfully. Redirecting...", 5);
             } else {
                 $status = TransactionEntry::STATUS_DECLINED;
                 $id = TransactionEntry::create($Request, $Invoice, $status, $walletID, $productID, $paymentSourceID);
                 ProfitEntry::update($Request, $id);
             }
         }
     }
     throw new ValidationException($Form, "Transaction declined: \n\t" . implode("\n\t", $responses));
 }