/**
  * Put the money into the real bank account of the operator|seller.
  *
  * @param OperationInterface $operation
  * @return int
  * @throws Exception
  */
 public function withdraw(OperationInterface $operation)
 {
     try {
         $vendor = $this->getVendor($operation);
         if (!$vendor || $this->hipay->isAvailable($vendor->getEmail())) {
             throw new WalletNotFoundException($vendor);
         }
         if (!$this->hipay->isIdentified($vendor->getEmail())) {
             throw new UnidentifiedWalletException($vendor);
         }
         $bankInfoStatus = trim($this->hipay->bankInfosStatus($vendor));
         if ($bankInfoStatus != BankInfoStatus::VALIDATED) {
             throw new UnconfirmedBankAccountException(new BankInfoStatus($bankInfoStatus), $operation->getMiraklId());
         }
         //Check account balance
         $amount = round($operation->getAmount(), self::SCALE);
         $balance = round($this->hipay->getBalance($vendor), self::SCALE);
         if ($balance < $amount) {
             //Operator operation
             if (!$operation->getMiraklId()) {
                 $amount = $balance;
                 //Vendor operation
             } else {
                 throw new WrongWalletBalance($vendor->getMiraklId(), $amount, $balance);
             }
         }
         $operation->setHiPayId($vendor->getHiPayId());
         //Withdraw
         $withdrawId = $this->hipay->withdraw($vendor, $amount, $this->operationManager->generateWithdrawLabel($operation));
         $operation->setWithdrawId($withdrawId);
         $operation->setStatus(new Status(Status::WITHDRAW_REQUESTED));
         $operation->setUpdatedAt(new DateTime());
         $operation->setWithdrawnAmount($amount);
         $this->operationManager->save($operation);
         return $withdrawId;
     } catch (Exception $e) {
         $operation->setStatus(new Status(Status::WITHDRAW_FAILED));
         $operation->setUpdatedAt(new DateTime());
         $this->operationManager->save($operation);
         throw $e;
     }
 }
 /**
  * @param int             $withdrawalId
  * @param int             $hipayId
  * @param DateTime        $date
  * @param bool            $status
  *
  * @throws Exception
  */
 protected function withdrawalValidation($hipayId, DateTime $date, $withdrawalId, $status)
 {
     $operation = $this->operationManager->findByWithdrawalId($withdrawalId);
     if (!$operation) {
         throw new OperationNotFound($withdrawalId);
     }
     if ($operation->getStatus() != Status::WITHDRAW_REQUESTED) {
         throw new WrongOperationStatus($operation);
     }
     if ($status) {
         $operation->setStatus(new Status(Status::WITHDRAW_SUCCESS));
         $this->logger->info("Withdraw {$operation->getWithdrawId()} successful");
         $eventName = 'withdraw.notification.success';
     } else {
         $operation->setStatus(new Status(Status::WITHDRAW_CANCELED));
         $this->logger->info("Withdraw {$operation->getWithdrawId()} canceled");
         $eventName = 'withdraw.notification.canceled';
     }
     $this->operationManager->save($operation);
     $event = new Withdraw($hipayId, $date, $operation);
     $this->dispatcher->dispatch($eventName, $event);
 }