<?php
namespace Bidcoz\Bundle\FrontendBundle\Controller;
use Bidcoz\Bundle\CoreBundle\Controller\CoreController;
use Bidcoz\Bundle\CoreBundle\Entity\Address;
use Bidcoz\Bundle\CoreBundle\Entity\Auction\Auction;
use Bidcoz\Bundle\CoreBundle\Entity\Campaign;
use Bidcoz\Bundle\CoreBundle\Entity\Donation\CashDonation;
use Bidcoz\Bundle\CoreBundle\Entity\Donation\DonationLevel;
use Bidcoz\Bundle\CoreBundle\Entity\Organization;
use Bidcoz\Bundle\CoreBundle\Entity\PaymentGateway\Account\Account;
use Bidcoz\Bundle\CoreBundle\Entity\Proxy\CashDonationProxy;
use Bidcoz\Bundle\CoreBundle\Entity\Proxy\ItemDonationProxy;
use Bidcoz\Bundle\CoreBundle\Entity\User;
use Bidcoz\Bundle\FrontendBundle\Form\Type\AddressType;
use Bidcoz\Bundle\FrontendBundle\Form\Type\Donation\CashDonationLevelType;
use Bidcoz\Bundle\FrontendBundle\Form\Type\Donation\CashType;
use Bidcoz\Bundle\FrontendBundle\Form\Type\Donation\ItemType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/{orgSlug}/{campaignSlug}/donate")
* @IsGranted("VIEW", subject="organization")
* @IsGranted("FRONT_END", subject="campaign")
*/
class DonationController extends CoreController
{
/**
* @Route("", name="campaign_donate")
*/
public function donateAction(Organization $organization, Campaign $campaign)
{
return $this->render('@BidcozFrontend/Campaign/Donate/index.html.twig', [
'organization' => $organization,
'campaign' => $campaign,
]);
}
/**
* @Route("/money", name="campaign_donate_cash")
*/
public function donateMoneyAction(Request $request, Organization $organization, Campaign $campaign)
{
$form = $this->getCashDonationForm();
if ('POST' === $request->getMethod()) {
if (!$user = $this->getUser()) {
$this->addFlash('info', 'Please login or create an account before making a donation.');
throw $this->createAccessDeniedException('Unable to access this page!');
}
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$this->getDonationManager()->createSimpleCashDonation($campaign, $user, $data['amount']);
$this->getEntityManager()->flush();
$this->addFlash('success', 'Thank you for your donation');
return $this->redirectToRoute('account_campaign_purchases', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
}
}
return $this->render('@BidcozFrontend/Campaign/Donate/donate_cash.html.twig', [
'organization' => $organization,
'campaign' => $campaign,
'form' => $form->createView(),
]);
}
/**
* @Route("/money/level/{donation_level_id}", name="campaign_donate_cash_level", methods={"GET"})
* @ParamConverter("donationLevel", class="Bidcoz\Bundle\CoreBundle\Entity\Donation\DonationLevel", options={"id" = "donation_level_id"})
*/
public function viewDonationLevelAction(Request $request, Organization $organization, Campaign $campaign, DonationLevel $donationLevel)
{
if (!$user = $this->getUser()) {
$this->addFlash('info', 'Please login or create an account before making a donation.');
throw $this->createAccessDeniedException('Unable to access this page!');
}
$stripeEnabled = $organization->isStripeAllowed() && $organization->hasPaymentGatewayAccountType(Account::STRIPE);
$proxy = $this->createCashDonationProxy($donationLevel, $campaign);
$proxy->setDonorName($this->getUser()->getName());
$form = $this->getCashDonationLevelForm($proxy, $stripeEnabled);
return $this->render('@BidcozFrontend/Campaign/Donate/donate.html.twig', [
'organization' => $organization,
'campaign' => $campaign,
'donationLevel' => $donationLevel,
'form' => $form->createView(),
'stripeEnabled' => $stripeEnabled,
]);
}
/**
* @Route("/money/level/{donation_level_id}", name="campaign_donate_cash_level_save", methods={"POST"})
* @ParamConverter("donationLevel", class="Bidcoz\Bundle\CoreBundle\Entity\Donation\DonationLevel", options={"id" = "donation_level_id"})
*/
public function makeDonationAction(Request $request, Organization $organization, Campaign $campaign, DonationLevel $donationLevel)
{
if (!$user = $this->getUser()) {
$this->addFlash('info', 'Please login or create an account before purchasing a ticket.');
throw $this->createAccessDeniedException('Unable to access this page!');
}
$stripeEnabled = $organization->isStripeAllowed() && $organization->hasPaymentGatewayAccountType(Account::STRIPE);
$proxy = $this->createCashDonationProxy($donationLevel, $campaign);
$form = $this->getCashDonationLevelForm($proxy, $stripeEnabled);
$form->handleRequest($request);
if (!$organization->isStripeAddressCheck()) {
$address = $user->getAddress();
$addressForm = $this->getAddressForm($address);
$addressForm->handleRequest($request);
if ($addressForm->isSubmitted() && $addressForm->isValid()) {
$user->setAddress($address);
}
}
try {
if ($form->isSubmitted() && $form->isValid()) {
$user = $this->getUser();
$level = $proxy->getDonationLevel();
$amount = $level->getAmount() + $proxy->getAdditionalAmount();
if ($proxy->getStripeToken() && $proxy->getInterval()) {
$intervalAmount = round($amount / $proxy->getIntervalsCnt(), 2);
$realAmount = $intervalAmount * $proxy->getIntervalsCnt(); // real amount after round
$proxy->setAdditionalAmount($realAmount - $level->getAmount()); // update AdditionalAmount according to realAmount
$subscriptionId = $this->getStripeManager()->createSubscriptionAndSubscribeUser(
$campaign,
$user,
$proxy->getInterval(),
$proxy->getStripeToken(),
$intervalAmount
);
} else {
$subscriptionId = null;
}
/** @var CashDonation $donation */
$donation = $this->getDonationManager()->createCashDonation($campaign, $user, $proxy, $subscriptionId);
//stripe payment for one-time donation
if (!$subscriptionId && $proxy->getStripeToken()) {
$transaction = $this->getStripeManager()->createStripeTransactionForPurchases(
$campaign,
$user,
$donation->getPurchases()->toArray(),
$proxy->getStripeToken()
);
}
$this->getEntityManager()->flush();
$this->addFlash('success', 'Donation successful');
// If not recurring payments, send to cart with Appeal item
if (!$subscriptionId) {
$redirect_path = 'account_campaign_purchases';
} else {
$redirect_path = 'account_campaign_purchase_stripe_success';
}
// Send to cart instead of campaign homepage.
// return $this->redirectToRoute('campaign_home', [
return $this->redirectToRoute($redirect_path, [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
}
} catch (\Stripe\Error\Base $e) {
$this->addFlash('danger', $e->getMessage());
$this->getEntityManager()->clear();
}
return $this->render('@BidcozFrontend/Campaign/Donate/donate.html.twig', [
'organization' => $organization,
'campaign' => $campaign,
'donationLevel' => $donationLevel,
'form' => $form->createView(),
'stripeEnabled' => $stripeEnabled,
]);
}
/**
* @Route("/crypto", name="campaign_donate_crypto")
* @IsGranted("DONATION_CRYPTO", subject="organization")
*/
public function donateCryptoAction(Request $request, Organization $organization, Campaign $campaign)
{
$cryptoWallets = $campaign->getCryptoWallets();
return $this->render('@BidcozFrontend/Campaign/Donate/donate_crypto.html.twig', [
'organization' => $organization,
'campaign' => $campaign,
'crypto_wallets' => $cryptoWallets,
]);
}
/**
* @Route("/levels", name="campaign_donate_levels")
*/
public function donationLevelsAction(Request $request, Organization $organization, Campaign $campaign)
{
$donationLevels = $this->getRepository('Donation\DonationLevel')->findCampaignDonationLevels($campaign);
return $this->render('@BidcozFrontend/Campaign/Donate/levels.html.twig', [
'organization' => $organization,
'campaign' => $campaign,
'donationLevels' => $donationLevels,
]);
}
/**
* @Route("/item", name="campaign_donate_item")
*/
public function donateItemAction(Request $request, Organization $organization, Campaign $campaign, Auction $auction)
{
$itemProxy = new ItemDonationProxy($campaign);
$form = $this->getItemDonationForm($itemProxy);
if ('POST' === $request->getMethod()) {
if (!$user = $this->getUser()) {
$this->addFlash('info', 'Please login or create an account before making a donation.');
throw $this->createAccessDeniedException('Unable to access this page!');
}
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDonationManager()->createItemDonation($itemProxy);
$this->addFlash('success', 'Thank you. Your Donation has been received.');
return $this->redirectToRoute('campaign_donate_item', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
}
}
return $this->render('@BidcozFrontend/Campaign/Donate/donate_item.html.twig', [
'organization' => $organization,
'campaign' => $campaign,
'form' => $form->createView(),
]);
}
protected function createItem(Auction $auction, User $user)
{
$item = $this->getItemManager()->createItem($auction);
$item->setActive(false);
$item->setDonor($user);
return $item;
}
protected function getCashDonationForm()
{
return $this->createForm(CashType::class);
}
protected function getCashDonationLevelForm(CashDonationProxy $cashDonationProxy, $withInterval)
{
return $this->createForm(CashDonationLevelType::class, $cashDonationProxy, [
'withInterval' => $withInterval,
'showMessage' => $cashDonationProxy->getDonationLevel()->getShowMessage(),
]);
}
protected function getItemDonationForm(ItemDonationProxy $item)
{
return $this->createForm(ItemType::class, $item);
}
protected function createCashDonationProxy(DonationLevel $donationLevel, Campaign $campaign)
{
$user = $this->getUser();
$questions = $this->getRepository('Donation\DonationQuestion')->findCampaignDonationQuestions($campaign, true);
$answers = array_map(function ($q) use ($user) {
$question = $q->getQuestion();
return $this->getQuestionManager()->createDonationAnswer($question, $user);
}, $questions);
$proxy = new CashDonationProxy($donationLevel, $user);
$proxy->setAnswers($answers);
return $proxy;
}
protected function getAddressForm(Address $address)
{
return $this->createForm(AddressType::class, $address);
}
}