src/Service/PackageService.php line 1630

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\DTO\MMPZ\PaymentMethod\PaymentGatewayAuthorizationDTO;
  4. use App\DTO\MMPZ\PaymentMethod\Paypal\Order\PaypalOrderDTO;
  5. use App\DTO\MMPZ\PaymentMethod\Paypal\PaypalWebHookDTO;
  6. use App\DTO\MMPZ\PaymentMethod\Paypal\Subscription\PaypalSubscriptionDTO;
  7. use App\DTO\Request\ManualInvoice;
  8. use App\Entity\App\File;
  9. use App\Entity\Package\Invoice;
  10. use App\Entity\Package\Package;
  11. use App\Entity\Package\PackageSongWriter;
  12. use App\Entity\Package\PackageTransaction;
  13. use App\Entity\Package\ReactivationAttempts;
  14. use App\Entity\Profile\PaymentMethod\PaymentGateway;
  15. use App\Entity\Profile\PaymentMethod\PaymentGatewayEvent;
  16. use App\Entity\Profile\Profile;
  17. use App\Entity\Profile\ProfileType;
  18. use App\Entity\User\User;
  19. use App\Enums\Constants;
  20. use App\Enums\PackageSongwriterStatus;
  21. use App\Enums\PackageType;
  22. use App\Enums\PaypalWebHookList;
  23. use App\Enums\StripeApiInvoiceStatus;
  24. use App\Enums\StripeWebHookList;
  25. use App\Enums\TransactionPlatform;
  26. use App\Enums\TransactionPlatformStatus;
  27. use App\Event\Package\PackageCreatedEvent;
  28. use App\Event\Package\PackageDeletedEvent;
  29. use App\Event\Package\PackageTransactionApprovedEvent;
  30. use App\Event\Package\PackageTransactionSubscriptionCanceledEvent;
  31. use App\Event\Package\PackageTransactionSubscriptionInactivatedEvent;
  32. use App\Event\Package\PackageTransactionSubscriptionReactivatedEvent;
  33. use App\Event\Package\PackageUpdatedEvent;
  34. use App\Factory\EntityFactory;
  35. use App\Repository\Package\InvoiceRepository;
  36. use App\Repository\Package\PackageRepository;
  37. use App\Repository\Package\PackageSongwriterRepository;
  38. use App\Repository\Package\PackageTransactionRepository;
  39. use App\Repository\Package\ReactiveAttemptsRepository;
  40. use App\Repository\Profile\PaymentMethod\PaymentGatewayEventRepository;
  41. use App\Repository\Profile\PaymentMethod\PaymentGatewayRepository;
  42. use App\Service\PaymentMethod\PaymentMethodService;
  43. use App\Service\PaymentMethod\ProfileForPaymentMethodService;
  44. use App\Service\PaymentMethod\Stripe\StripeService;
  45. use Doctrine\DBAL\Types\DateTimeType;
  46. use Stripe\Checkout\Session;
  47. use Stripe\Subscription;
  48. use Stripe\Webhook;
  49. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  50. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  51. use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
  52. use Symfony\Component\Serializer\SerializerInterface;
  53. use function Aws\flatmap;
  54. class PackageService
  55. {
  56.     /** @var EntityFactory */
  57.     private $entityFactory;
  58.     /** @var SerializerInterface */
  59.     private $serializer;
  60.     /** @var EventDispatcherInterface */
  61.     private $eventDispatcher;
  62.     /** @var PackageRepository */
  63.     private $packageRepository;
  64.     /** @var PackageTransactionRepository */
  65.     private $packageTransactionRepository;
  66.     /** @var PackageSongwriterRepository */
  67.     private $packageSongwriterRepository;
  68.     /** @var PaymentGatewayRepository */
  69.     private $paymentGatewayRepository;
  70.     /** @var PaymentGatewayEventRepository */
  71.     private $paymentGatewayEventRepository;
  72.     /** @var InvoiceRepository */
  73.     private $invoiceRepository;
  74.     /** @var ReactiveAttemptsRepository */
  75.     private $reactiveAttemptsRepository;
  76.     /** @var PaymentMethodService */
  77.     private $paymentMethodService;
  78.     /** @var ProfileForPaymentMethodService */
  79.     private $profileForPaymentMethodService;
  80.     /** @var StripeService */
  81.     private $stripeService;
  82.     /**
  83.      * @param EntityFactory $entityFactory
  84.      * @param SerializerInterface $serializer
  85.      * @param EventDispatcherInterface $eventDispatcher
  86.      * @param PackageRepository $packageRepository
  87.      * @param PackageTransactionRepository $packageTransactionRepository
  88.      * @param PackageSongwriterRepository $packageSongwriterRepository
  89.      * @param PaymentGatewayEventRepository $paymentGatewayEventRepository
  90.      * @param PaymentGatewayRepository $paymentGatewayRepository
  91.      * @param InvoiceRepository $invoiceRepository
  92.      * @param ReactiveAttemptsRepository $reactiveAttemptsRepository
  93.      * @param PaymentMethodService $paymentMethodService
  94.      * @param ProfileForPaymentMethodService $profileForPaymentMethodService
  95.      * @param StripeService $stripeService
  96.      */
  97.     public function __construct(
  98.         EntityFactory $entityFactory,
  99.         SerializerInterface $serializer,
  100.         EventDispatcherInterface $eventDispatcher,
  101.         PackageRepository $packageRepository,
  102.         PackageTransactionRepository $packageTransactionRepository,
  103.         PackageSongwriterRepository $packageSongwriterRepository,
  104.         PaymentGatewayRepository $paymentGatewayRepository,
  105.         PaymentGatewayEventRepository $paymentGatewayEventRepository,
  106.         InvoiceRepository $invoiceRepository,
  107.         ReactiveAttemptsRepository $reactiveAttemptsRepository,
  108.         PaymentMethodService $paymentMethodService,
  109.         ProfileForPaymentMethodService $profileForPaymentMethodService,
  110.         StripeService $stripeService
  111.     )
  112.     {
  113.         $this->entityFactory $entityFactory;
  114.         $this->serializer $serializer;
  115.         $this->eventDispatcher $eventDispatcher;
  116.         $this->packageRepository $packageRepository;
  117.         $this->packageTransactionRepository $packageTransactionRepository;
  118.         $this->packageSongwriterRepository $packageSongwriterRepository;
  119.         $this->paymentGatewayRepository $paymentGatewayRepository;
  120.         $this->paymentGatewayEventRepository $paymentGatewayEventRepository;
  121.         $this->invoiceRepository $invoiceRepository;
  122.         $this->reactiveAttemptsRepository $reactiveAttemptsRepository;
  123.         $this->paymentMethodService $paymentMethodService;
  124.         $this->profileForPaymentMethodService $profileForPaymentMethodService;
  125.         $this->stripeService $stripeService;
  126.     }
  127.     /**
  128.      * @param ProfileType $profileType
  129.      * @param User $user
  130.      * @return Profile|null
  131.      */
  132.     public function findProfileForProcess(ProfileType $profileType,  User $user)
  133.     {
  134.         /** @var Profile $profile in that case the songWriter Profile or the publisher who buy the package */
  135.         if($_ENV['CWR_ENVIROMENT'] === "local"){
  136.             $profile $this->profileForPaymentMethodService->getTestProfileByProfiletype($profileType);
  137.         }else{
  138.             $profile $this->profileForPaymentMethodService->findLastAccessedProfileForUser($user);
  139.         }
  140.         return $profile;
  141.     }
  142.     /**
  143.      * @param Profile $profile
  144.      * @return array
  145.      */
  146.     public function getAllPackageByProfile(Profile $profile)
  147.     {
  148.         return $this->packageRepository->findBy([
  149.             'profile'   => $profile,
  150.             'type'      => PackageType::PRIMARY,
  151.             'parent'    => null
  152.         ]);
  153.     }
  154.     /**
  155.      * @param Profile $profile
  156.      * @return array
  157.      */
  158.     public function getAllSubscriptionByProfile(Profile $profile)
  159.     {
  160.         return $this->packageRepository->findBy([
  161.             'profile'   => $profile,
  162.             'type'      => PackageType::SUBSCRIPTION,
  163.             'parent'    => null
  164.         ]);
  165.     }
  166.     /**
  167.      * @param Profile $profile
  168.      * @param Profile $parentProfile
  169.      * @param bool $isAdminUser
  170.      * @return array
  171.      */
  172.     public function getAllPackageAndSubscriptionByClient(Profile $profileProfile $parentProfilebool $isAdminUser)
  173.     {
  174.         $packages $this->packageRepository->findBy([
  175.             'profile'       => $parentProfile,
  176.             'profileType'   => $profile->getProfileType(),
  177.             'parent'        => null
  178.         ]);
  179.         $relationProfileSubscriptions $this->getRelationsProfileSubscriptions($profile);
  180.         if(count($relationProfileSubscriptions) === 0){
  181.             /** @var Package $package */
  182.             foreach($packages as $key => $package){
  183.                 if(!$package->isBasic()){
  184.                     unset($packages[$key]);
  185.                 }
  186.             }
  187.         }else{
  188.             /** @var PackageSongWriter $activeRelation */
  189.             $activeRelation null;
  190.             /** @var PackageSongWriter $relation */
  191.             foreach ($relationProfileSubscriptions as $relation) {
  192.                 if($relation->getStatus() === PackageSongwriterStatus::ACTIVE){
  193.                     $activeRelation $relation;
  194.                     break;
  195.                 }
  196.             }
  197.             /** @var Package $package */
  198.             foreach ($packages as $key => $package) {
  199.                 if (!$package->isEnabled() || !$package->isVisible()) {
  200.                     unset($packages[$key]);
  201.                 }
  202.                 if(!$isAdminUser && $package->isVisibleToAdminOnly()){
  203.                     unset($packages[$key]);
  204.                 }
  205.                 if($profile->getProfileType()->getName() === Constants::PROFILE_TYPE_PUBLISHER){
  206.                     $validProfileCounter $this->profileForPaymentMethodService->countNotClosureSubProfiles($profile);
  207.                     
  208.                     if($validProfileCounter $package->getSubprofileLimit() && !is_null($activeRelation)){
  209.                         if(!is_null($activeRelation->getPackage()->getstandardPackageData()) || !is_null($activeRelation->getPackage()->getPlusPackageData())){
  210.                             if(!is_null($activeRelation->getPackage()->getstandardPackageData())){
  211.                                 if($activeRelation->getPackage()->getstandardPackageData()['id'] !== $package->getId()){
  212.                                     $operation $validProfileCounter $package->getSubprofileLimit();
  213.                                     $reason "This subscription allows a maximum of {$package->getSubprofileLimit()} songwriter(s). Currently, 
  214.                                     there are {$validProfileCounter} not closed songwriters under your publisher profile. 
  215.                                     Please close {$operation} in order to downgrade";
  216.                                     $package->setCanBePurchased(false);
  217.                                     $package->setCanNotBePurchasedReason($reason);
  218.                                     $packages[$key] = $package;
  219.                                 }
  220.                             }
  221.                             if(!is_null($activeRelation->getPackage()->getPlusPackageData())){
  222.                                 if($activeRelation->getPackage()->getPlusPackageData()['id'] !== $package->getId()){
  223.                                     $operation $validProfileCounter $package->getSubprofileLimit();
  224.                                     $reason "This subscription allows a maximum of {$package->getSubprofileLimit()} songwriter(s). Currently, 
  225.                                     there are {$validProfileCounter} not closed songwriters under your publisher profile. 
  226.                                     Please close {$operation} in order to downgrade";
  227.                                     $package->setCanBePurchased(false);
  228.                                     $package->setCanNotBePurchasedReason($reason);
  229.                                     $packages[$key] = $package;
  230.                                 }
  231.                             }
  232.                         }else{
  233.                             $operation $validProfileCounter $package->getSubprofileLimit();
  234.                             $reason "This subscription allows a maximum of {$package->getSubprofileLimit()} songwriter(s). Currently, 
  235.                             there are {$validProfileCounter} not closed songwriters under your publisher profile. 
  236.                             Please close {$operation} in order to downgrade";
  237.                             $package->setCanBePurchased(false);
  238.                             $package->setCanNotBePurchasedReason($reason);
  239.                             $packages[$key] = $package;
  240.                         }
  241.                     }
  242.                 }
  243.                 if(!is_null($activeRelation)){
  244.                     if($activeRelation->getPackage()->getId() === $package->getId()){
  245.                         $package->setCanBePurchased(false);
  246.                         $package->setCanNotBePurchasedReason("This is the active subscription");
  247.                         $packages[$key] = $package;
  248.                     }else if(!is_null($activeRelation->getPackage()->getParent())){
  249.                         if($activeRelation->getPackage()->getParent()->getId() === $package->getId()){
  250.                             $package->setCanBePurchased(false);
  251.                             $package->setCanNotBePurchasedReason("This is the active subscription");
  252.                             $packages[$key] = $package;
  253.                         }
  254.                     }
  255.                     $reason "Upgrade from monthly->yearly and yearly->monthly is not possible without cancellations of ongoing subscription.";
  256.                     if($activeRelation->getPackage()->isMonthly() && $package->isAnnual()){
  257.                         $package->setCanBePurchased(false);
  258.                         $package->setCanNotBePurchasedReason($reason);
  259.                     }
  260.                     if($activeRelation->getPackage()->isAnnual() && $package->isMonthly()){
  261.                         $package->setCanBePurchased(false);
  262.                         $package->setCanNotBePurchasedReason($reason);
  263.                     }
  264.                 }
  265.                 if(
  266.                     $profile->getProfileType()->getName() === Constants::PROFILE_TYPE_SONGWRITER &&
  267.                     $profile->getParent()->getProfileType()->getName() === Constants::PROFILE_TYPE_PUBLISHER
  268.                 ){
  269.                     unset($packages[$key]);
  270.                 }
  271.             }
  272.         }
  273.         return $packages;
  274.     }
  275.     /**
  276.      * @param int $id
  277.      * @return Package
  278.      */
  279.     public function getASubscriptionOrPackageById(int $id)
  280.     {
  281.         return $this->packageRepository->findOneBy(['id'   => $id]);
  282.     }
  283.     /**
  284.      * @param array $data
  285.      * @param Profile $profile
  286.      * @param ProfileType $profileType
  287.      * @param Package $parent
  288.      * @param bool $isBasic
  289.      * @return Package
  290.      */
  291.     public function processToCreateAPackage(
  292.         array $data,
  293.         Profile $profile,
  294.         ProfileType $profileType,
  295.         Package $parent null,
  296.         bool $isBasic false
  297.     )
  298.     {
  299.         /** @var Package $entity */
  300.         $entity $this->entityFactory->createFromJson(
  301.             json_encode($data),
  302.             Package::class,
  303.             ['package:create']
  304.         );
  305.         $entity->setProfile($profile);
  306.         $entity->setProfileType($profileType);
  307.         $entity->setIsBasic($isBasic);
  308.         $entity->setParent($parent);
  309.         $this->packageRepository->save($entity);
  310.         /** @var Package $package */
  311.         $package $this->packageRepository->findOneBy(['id' => $entity->getId()]);
  312.         $package $this->paymentMethodService->processToCreateAProductInThePaymentPlatform($package);
  313.         $this->packageRepository->flush($package);
  314.         /** @var Package $package */
  315.         $package $this->packageRepository->findOneBy(['id' => $entity->getId()]);
  316.         if($_ENV['CWR_ENVIROMENT'] !== "local"){
  317.             $this->eventDispatcher->dispatch(new PackageCreatedEvent($package$profile));
  318.         }
  319.         return $package;
  320.     }
  321.     /**
  322.      * @param Package $package
  323.      * @param array $data
  324.      * @param Profile $profile
  325.      * @param ProfileType $profileType
  326.      * @param File $file
  327.      * @param Package|null $parent
  328.      * @param bool $isBasic
  329.      * @return Package
  330.      */
  331.     public function processToUpdateAPackage(
  332.         Package $package,
  333.         array $data,
  334.         Profile $profile,
  335.         ProfileType $profileType,
  336.         File $file,
  337.         Package $parent null,
  338.         bool $isBasic false
  339.     )
  340.     {
  341.         $totalAmountAfter = (float)$package->getPrice() - ((float)$package->getPrice() * (float)$package->getDiscount());
  342.         /** @var Package $entity */
  343.         $entity $this->entityFactory->createFromJson(
  344.             json_encode($data),
  345.             Package::class,
  346.             ['package:edit'],
  347.             [
  348.                 AbstractObjectNormalizer::OBJECT_TO_POPULATE => $package
  349.             ]
  350.         );
  351.         $entity->setProfile($profile);
  352.         $entity->setProfileType($profileType);
  353.         $entity->setFile($file);
  354.         $entity $this->packageRepository->merge($entity);
  355.         /** @var Package $package */
  356.         $package $this->packageRepository->findOneBy(['id' => $entity->getId()]);
  357.         $totalAmountBefore = (float)$package->getPrice() - ((float)$package->getPrice() * (float)$package->getDiscount());
  358.         if($totalAmountAfter != $totalAmountBefore && $package->getType() === PackageType::SUBSCRIPTION){
  359.             $externalPlatformResults $this->paymentMethodService->processToUpdateAPlanPriceProductInThePaymentPlatform($package);
  360.             if(!is_null($externalPlatformResults[TransactionPlatform::PAYPAL])){
  361.                 $package->setPaypalPlanId($externalPlatformResults[TransactionPlatform::PAYPAL]->getId());
  362.             }
  363.             if(!is_null($externalPlatformResults[TransactionPlatform::STRIPE])){
  364.                 $package->setStripePlanId($externalPlatformResults[TransactionPlatform::STRIPE]->id);
  365.             }
  366.             $this->packageRepository->flush($package);
  367.             /** @var Package $package */
  368.             $package $this->packageRepository->findOneBy(['id' => $entity->getId()]);
  369.         }
  370.         $this->eventDispatcher->dispatch(new PackageUpdatedEvent($package));
  371.         return $package;
  372.     }
  373.     /**
  374.      * @param PackageTransaction $packageTransaction
  375.      * @return Package
  376.      */
  377.     public function processToUpdateTheChildPackagePrice(PackageTransaction $packageTransaction)
  378.     {
  379.         $package $packageTransaction->getPackage();
  380.         if(!is_null($package->getParent())){
  381.             $package->setPrice($package->getParent()->getPrice());
  382.             $package->setDiscount($package->getParent()->getDiscount());
  383.             $this->packageRepository->flush($package);
  384.             /** @var Package $package */
  385.             $package $this->packageRepository->findOneBy(['id' => $package->getId()]);
  386.             if(!is_null($package->getStripePlanId()) || !is_null($package->getPaypalPlanId())){
  387.                 $externalPlatformResults $this->paymentMethodService->processToUpdateAPlanPriceProductInThePaymentPlatform($package);
  388.                 if(!is_null($externalPlatformResults[TransactionPlatform::PAYPAL])){
  389.                     $package->setPaypalPlanId($externalPlatformResults[TransactionPlatform::PAYPAL]->getId());
  390.                 }
  391.                 if(!is_null($externalPlatformResults[TransactionPlatform::STRIPE])){
  392.                     $package->setStripePlanId($externalPlatformResults[TransactionPlatform::STRIPE]->id);
  393.                     $this->paymentMethodService->processToUpdateStripePriceSusbcription($packageTransaction);
  394.                 }
  395.                 $this->packageRepository->flush($package);
  396.                 /** @var Package $package */
  397.                 $package $this->packageRepository->findOneBy(['id' => $package->getId()]);
  398.             }
  399.         }
  400.         return $package;
  401.     }
  402.     /**
  403.      * @param Package $package
  404.      * @param array $data
  405.      * @return Package
  406.      */
  407.     public function processToCreateAPlusPackage(Package $package, array $data): Package
  408.     {
  409.         if($package->isHasPlus()){
  410.             /** @var Package $pp */
  411.             $pp $this->packageRepository->findOneBy(['id' => $package->getPackagePlus()->getId()]);
  412.             if(!is_null($pp)){
  413.                 throw new BadRequestHttpException("The subscription already has a plus");
  414.             }
  415.         }
  416.         /** @var Package $newPackagePlus */
  417.         $newPackagePlus $this->entityFactory->createFromJson(
  418.             json_encode($data),
  419.             Package::class,
  420.             ['package:create']
  421.         );
  422.         $newPackagePlus->setName($package->getName()." Plus");
  423.         $newPackagePlus->setDescription($package->getDescription()." Plus");
  424.         $newPackagePlus->setIsBasic($package->isBasic());
  425.         $newPackagePlus->setParent($package->getParent());
  426.         $newPackagePlus->setProfile($package->getProfile());
  427.         $newPackagePlus->setProfileType($package->getProfileType());
  428.         $newPackagePlus->setHasStandard(true);
  429.         $newPackagePlus->setPackageStandard($package);
  430.         $this->packageRepository->save($newPackagePlus);
  431.         /** @var Package $newPackagePlus */
  432.         $newPackagePlus $this->packageRepository->findOneBy(['id' => $newPackagePlus->getId()]);
  433.         $newPackagePlus $this->paymentMethodService->processToCreateAProductInThePaymentPlatform($newPackagePlus);
  434.         $this->packageRepository->flush($newPackagePlus);
  435.         /** @var Package $newPackagePlus */
  436.         $newPackagePlus $this->packageRepository->findOneBy(['id' => $newPackagePlus->getId()]);
  437.         if($_ENV['CWR_ENVIROMENT'] !== "local"){
  438.             $this->eventDispatcher->dispatch(new PackageCreatedEvent($newPackagePlus$newPackagePlus->getProfile()));
  439.         }
  440.         $package->setHasPlus(true);
  441.         $package->setPackagePlus($newPackagePlus);
  442.         $this->packageRepository->flush($package);
  443.         return $newPackagePlus;
  444.     }
  445.     /**
  446.      * @param Package $package
  447.      * @return Package
  448.      */
  449.     public function processToDeleteAPackage(Package $package)
  450.     {
  451.         $package->setEnabled(false);
  452.         if($package->isHasStandard()){//this is when is deleted a package plus
  453.             /** @var Package $packageStandard */
  454.             $packageStandard $this->packageRepository->findOneBy([
  455.                 'id' => $package->getPackageStandard()->getId()
  456.             ]);
  457.             $packageStandard->setPackagePlus(null);
  458.             $packageStandard->setHasPlus(false);
  459.             $package->setHasStandard(false);
  460.             $package->setPackageStandard(null);
  461.         }else if($package->isHasPlus()){//this is when is deleted a package standard
  462.             /** @var Package $packagePlus */
  463.             $packagePlus $this->packageRepository->findOneBy([
  464.                 'id' => $package->getPackagePlus()->getId()
  465.             ]);
  466.             $packagePlus->setPackageStandard(null);
  467.             $packagePlus->setHasStandard(false);
  468.             
  469.             $package->setHasPlus(false);
  470.             $package->setPackagePlus(null);
  471.         }
  472.         $this->packageRepository->flush($package);
  473.         $this->eventDispatcher->dispatch(new PackageDeletedEvent($package));
  474.         /** @var Package $package */
  475.         $package $this->packageRepository->findOneBy(['id' => $package->getId()]);
  476.         return $package;
  477.     }
  478.     /**
  479.      * @param array $data
  480.      * @param Profile $profile
  481.      * @param Package $package
  482.      * @return float
  483.      * @throws \GuzzleHttp\Exception\GuzzleException
  484.      * @throws \Stripe\Exception\ApiErrorException
  485.      */
  486.     public function processToShowPriceToUpgrade(
  487.         array $data,
  488.         Profile $profile,
  489.         Package $package
  490.     )
  491.     {
  492.         /** @var PaymentGateway $paymentGateway */
  493.         $paymentGateway $this->paymentGatewayRepository->findOneBy(['id' => $data['payment_gateway']['id']]);
  494.         $customPriceToUpgrade $package->getPrice() - ($package->getPrice() * $package->getDiscount());
  495.         /** @var PackageSongWriter $packageSongWriter */
  496.         $packageSongWriter $this->processToCheckActiveInactiveSubscription($profile);
  497.         if(!is_null($packageSongWriter)){
  498.             $this->processToCheckOldPackageNewPackage($packageSongWriter->getPackage(), $package);
  499.             $oldPackage = (is_null($packageSongWriter->getPackage()->getParent())) ?
  500.                 $packageSongWriter->getPackage() :
  501.                 $packageSongWriter->getPackage()->getParent();
  502.             if($package->getPrice() <= $oldPackage->getPrice()){
  503.                 if($this->profileForPaymentMethodService->countNotClosureSubProfiles($profile) > $package->getSubprofileLimit()){
  504.                     throw new BadRequestHttpException(
  505.                         "Please, check your sub-profiles, you need to have at most {$package->getSubprofileLimit()} non-closed subprofiles"
  506.                     );
  507.                 }
  508.             }else{
  509.                 $customPriceToUpgrade $this->calculatePriceToUpgrade(
  510.                     $package,
  511.                     $packageSongWriter
  512.                 );
  513.                 if(
  514.                     $package->isHasStandard() &&
  515.                     $package->getPackageStandard()->getId() === $oldPackage->getId()
  516.                 ){
  517.                     $oldPrice = (float)$oldPackage->getPrice() - ((float)$oldPackage->getPrice() * (float)$oldPackage->getDiscount());
  518.                     $customPriceToUpgrade $package->getPrice() - ($package->getPrice() * $package->getDiscount());
  519.                     $customPriceToUpgrade $customPriceToUpgrade $oldPrice;
  520.                 }
  521.             }
  522.         }
  523.         return $customPriceToUpgrade;
  524.     }
  525.     /**
  526.      * @param Profile $profile
  527.      * @return array
  528.      */
  529.     public function getTransactionsByProfile(Profile $profile)
  530.     {
  531.         return $this->packageTransactionRepository->findBy(
  532.             ['profile' => $profile]
  533.         );
  534.     }
  535.     /**
  536.      * @param Profile $profile
  537.      * @return array
  538.      */
  539.     public function getRelationsProfileSubscriptions(Profile $profile)
  540.     {
  541.         return $this->packageSongwriterRepository->findBy(['profile' => $profile]);
  542.     }
  543.     /**
  544.      * @param array $data
  545.      * @param Profile $profile
  546.      * @param Package $package
  547.      * @param string $manual
  548.      * @return PackageTransaction
  549.      * @throws \GuzzleHttp\Exception\GuzzleException
  550.      * @throws \Stripe\Exception\ApiErrorException
  551.      */
  552.     public function processtoCreateTransaction(
  553.         array $data,
  554.         Profile $profile,
  555.         Package $package,
  556.         string $manual ""
  557.     )
  558.     {
  559.         /** @var PaymentGateway $paymentGateway */
  560.         $paymentGateway $this->paymentGatewayRepository->findOneBy(['id' => $data['payment_gateway']['id']]);
  561.         /** @var PackageTransaction $entity */
  562.         $entity $this->entityFactory->createFromJson(
  563.             json_encode($data),
  564.             PackageTransaction::class,
  565.             ['package-transaction:create']
  566.         );
  567.         $entity->setProfile($profile);
  568.         $entity->setPackage($package);
  569.         $entity->setPaymentGateway($paymentGateway);
  570.         /** @var PackageSongWriter $packageSongWriter */
  571.         $packageSongWriter $this->processToCheckActiveInactiveSubscription($profile);
  572.         if(!is_null($packageSongWriter)){
  573.             $this->processToCheckOldPackageNewPackage($packageSongWriter->getPackage(), $package);
  574.             $entity->setTransitionTransaction($packageSongWriter->getPackageTransaction());
  575.             $oldPackage = (is_null($packageSongWriter->getPackage()->getParent())) ?
  576.                 $packageSongWriter->getPackage() :
  577.                 $packageSongWriter->getPackage()->getParent();
  578.             if($package->getPrice() <= $oldPackage->getPrice()){//Process for downgrade
  579.                 if($this->profileForPaymentMethodService->countNotClosureSubProfiles($profile) > $package->getSubprofileLimit()){
  580.                     throw new BadRequestHttpException(
  581.                         "Please, check your sub-profiles, you need to have at most {$package->getSubprofileLimit()} non-closed subprofiles"
  582.                     );
  583.                 }
  584.                 /*if(
  585.                     $package->isHasPlus() &&
  586.                     $package->getPackagePlus()->getId() === $oldPackage->getId()
  587.                 ){
  588.                     $customPriceToDowngrade = (float)$package->getPrice() - ((float)$package->getPrice() * (float)$package->getDiscount());
  589.                     $oldPrice = (float)$oldPackage->getPrice() - ((float)$oldPackage->getPrice() * (float)$oldPackage->getDiscount());
  590.                     $customPriceToDowngrade = $oldPrice - $customPriceToDowngrade;
  591.                     $newPackageData = $this->buildAPackageArray(
  592.                         $customPriceToDowngrade,
  593.                         $package,
  594.                         $oldPackage
  595.                     );
  596.                     $package = $this->processToCreateAPackage(
  597.                         $newPackageData,
  598.                         $package->getProfile(),
  599.                         $package->getProfileType(),
  600.                         $package,
  601.                         false
  602.                     );
  603.                     $entity->setPackage($package);
  604.                 }*/
  605.                 $entity->setTransitionReason(Constants::DOWNGRADE_SUBSCRIPTION);
  606.             }else{//Process for upgrade
  607.                 $arrExtPackTranId explode("-"$packageSongWriter->getPackageTransaction()->getPaymentGatewayExternalId());
  608.                 $manualProcess false;
  609.                 if($arrExtPackTranId[0] === Constants::MANUAL_INVOICE_IDENTIFIER || $arrExtPackTranId[0] === Constants::FREE_INVOICE_IDENTIFIER){
  610.                     $manualProcess = !$manualProcess;
  611.                 }
  612.                 $customPriceToUpgrade $this->calculatePriceToUpgrade(
  613.                     $package,
  614.                     $packageSongWriter
  615.                 );
  616.                 if(
  617.                     $package->isHasStandard() &&
  618.                     $package->getPackageStandard()->getId() === $oldPackage->getId()
  619.                 ){
  620.                     $customPriceToUpgrade = (float)$package->getPrice() - ((float)$package->getPrice() * (float)$package->getDiscount());
  621.                     $oldPrice = (float)$oldPackage->getPrice() - ((float)$oldPackage->getPrice() * (float)$oldPackage->getDiscount());
  622.                     $customPriceToUpgrade $customPriceToUpgrade $oldPrice;
  623.                 }
  624.                 $newPackageData $this->buildAPackageArray(
  625.                     $customPriceToUpgrade,
  626.                     $package,
  627.                     $oldPackage
  628.                 );
  629.                 $package $this->processToCreateAPackage(
  630.                     $newPackageData,
  631.                     $package->getProfile(),
  632.                     $package->getProfileType(),
  633.                     $package,
  634.                     false
  635.                 );
  636.                 $entity->setTransitionReason(Constants::UPGRADE_SUBSCRIPTION);
  637.                 //Here it is set again the new package created to can register the price of the diference Btwn the
  638.                 // new package and the old package
  639.                 $entity->setPackage($package);
  640.             }
  641.         }
  642.         if((float)$package->getPrice() > && $manual === ""){
  643.             if($paymentGateway->getPaymentType()->getName() === TransactionPlatform::PAYPAL){
  644.                 switch ($package->getType()){
  645.                     case PackageType::PRIMARY:
  646.                         /** @var PaypalOrderDTO $paypalOderDTO */
  647.                         $paypalOderDTO $this->paymentMethodService->processToCreatePackageOrder($entity);
  648.                         $entity->setPaymentGatewayExternalId($paypalOderDTO->getId());
  649.                         $entity->setPaymentGatewayCreate($this->serializer->serialize($paypalOderDTO"json", ['groups' => 'paypal:order']));
  650.                         break;
  651.                     case PackageType::SUBSCRIPTION:
  652.                         /** @var PaypalSubscriptionDTO $paypalSubscriptionDTO */
  653.                         $paypalSubscriptionDTO $this->paymentMethodService->processToCreateSubscription($entity);
  654.                         $entity->setPaymentGatewayExternalId($paypalSubscriptionDTO->getId());
  655.                         $entity->setPaymentGatewayCreate($this->serializer->serialize($paypalSubscriptionDTO"json", ['groups' => 'paypal:subscription']));
  656.                         break;
  657.                 }
  658.                 //echo $this->serializer->serialize($entity, "json", ['groups' => 'package-transaction:show']); exit();
  659.             }else if($paymentGateway->getPaymentType()->getName() === TransactionPlatform::STRIPE){
  660.                 switch ($package->getType()){
  661.                     case PackageType::PRIMARY:
  662.                         /** @var Session $stripeCharge */
  663.                         $stripeCharge $this->paymentMethodService->processToCreatePackageOrder($entity);
  664.                         $entity->setPaymentGatewayExternalId($stripeCharge->id);
  665.                         $entity->setPaymentGatewayCreate($stripeCharge->toJSON());
  666.                         break;
  667.                     case PackageType::SUBSCRIPTION:
  668.                         /** @var Session $stripeSubscription */
  669.                         $stripeSubscription $this->paymentMethodService->processToCreateSubscription($entity);
  670.                         $entity->setPaymentGatewayExternalId($stripeSubscription->id);
  671.                         $entity->setPaymentGatewayCreate($stripeSubscription->toJSON());
  672.                         break;
  673.                 }
  674.             }
  675.         }else{
  676.             if($manual === Constants::MANUAL_PROCESS_CREATE_SUBCRIPTION){
  677.                 $entity->setPaymentGatewayExternalId(
  678.                     Constants::MANUAL_INVOICE_IDENTIFIER."-".$package->getId()."-".date("YmdHis")
  679.                 );
  680.             }else{
  681.                 $entity->setPaymentGatewayExternalId(
  682.                     Constants::FREE_INVOICE_IDENTIFIER."-".$package->getId()."-".date("YmdHis")
  683.                 );
  684.             }
  685.         }
  686.         $entity->setCreatedAt(new \DateTime());
  687.         /** @var PackageTransaction $packageTransaction */
  688.         $packageTransaction $this->packageTransactionRepository->save($entity);
  689.         return $packageTransaction;
  690.     }
  691.     /**
  692.      * @param array $data
  693.      * @param Profile $profile
  694.      * @param Package $package
  695.      * @param PackageTransaction $packageTransaction
  696.      * @param string $manual
  697.      * @return PackageTransaction
  698.      * @throws \GuzzleHttp\Exception\GuzzleException
  699.      * @throws \Stripe\Exception\ApiErrorException
  700.      */
  701.     public function processToEditTransaction(
  702.         array $data,
  703.         Profile $profile,
  704.         Package $package,
  705.         PackageTransaction $packageTransaction,
  706.         string $manual ""
  707.     )
  708.     {
  709.         /** @var PaymentGateway $paymentGateway */
  710.         $paymentGateway $this->paymentGatewayRepository->findOneBy(['id' => $data['payment_gateway']['id']]);
  711.         $packageTransaction->setStatus(TransactionPlatformStatus::COMPLETED);
  712.         if((float)$package->getPrice() > && $manual === ""){
  713.             if($paymentGateway->getPaymentType()->getName() === TransactionPlatform::PAYPAL){
  714.                 switch ($package->getType()){
  715.                     case PackageType::PRIMARY:
  716.                         /** @var PaypalOrderDTO $paypalOderDTO */
  717.                         $paypalOderDTO $this->paymentMethodService->processToConfirmPackageOrder($packageTransaction);
  718.                         $packageTransaction->setPaymentGatewayProcess($this->serializer->serialize($paypalOderDTO"json", ['groups' => 'paypal:order']));
  719.                         break;
  720.                     case PackageType::SUBSCRIPTION:
  721.                         /** @var PaypalSubscriptionDTO $paypalSubscriptionDTO */
  722.                         $paypalSubscriptionDTO $this->paymentMethodService->processToConfirmSubscription($packageTransaction);
  723.                         $packageTransaction->setPaymentGatewayProcess($this->serializer->serialize($paypalSubscriptionDTO"json", ['groups' => 'paypal:subscription']));
  724.                         break;
  725.                 }
  726.             }else if($paymentGateway->getPaymentType()->getName() === TransactionPlatform::STRIPE){
  727.                 switch ($package->getType()){
  728.                     case PackageType::PRIMARY:
  729.                         /** @var Session $stripeCharge */
  730.                         $stripeCharge $this->paymentMethodService->processToConfirmPackageOrder($packageTransaction);
  731.                         $packageTransaction->setPaymentGatewayProcess($stripeCharge->toJSON());
  732.                         break;
  733.                     case PackageType::SUBSCRIPTION:
  734.                         /** @var Subscription $stripeSubscription */
  735.                         $stripeSubscription $this->paymentMethodService->processToConfirmSubscription($packageTransaction);
  736.                         $packageTransaction->setPaymentGatewayProcess($stripeSubscription->toJSON());
  737.                         $packageTransaction->setPaymentGatewayExternalId($stripeSubscription->id);
  738.                         $data['payment_gateway_external_id'] = $stripeSubscription->id;
  739.                         break;
  740.                 }
  741.             }
  742.         }else{
  743.             $packageTransaction->setManual(true);
  744.         }
  745.         $packageTransaction->setProcessedAt(new \DateTime());
  746.         $this->packageTransactionRepository->flush($packageTransaction);
  747.         /** @var PackageTransaction $packageTransaction */
  748.         $packageTransaction $this->packageTransactionRepository->findOneBy([
  749.             'paymentGatewayExternalId' => $data['payment_gateway_external_id']
  750.         ]);
  751.         if(!is_null($packageTransaction->getTransitionTransaction())){
  752.             $packageTransactionOld $this->processToCancelASubscription(
  753.                 $packageTransaction->getTransitionReason(),
  754.                 $packageTransaction->getTransitionTransaction()
  755.             );
  756.         }
  757.         return $packageTransaction;
  758.     }
  759.     /**
  760.      * @param PackageTransaction $packageTransaction
  761.      * @param string $manual
  762.      * @return PackageSongWriter
  763.      * @throws \Exception
  764.      */
  765.     public function processtoCreateRelationPackageProfile(
  766.         PackageTransaction $packageTransaction,
  767.         string $manual ""
  768.     )
  769.     {
  770.         $credentials $this->getCredentialFOrPaymentGateway($packageTransaction->getProfile());
  771.         $packageSongwriter = (new PackageSongWriter())
  772.             ->setPackage($packageTransaction->getPackage())
  773.             ->setProfile($packageTransaction->getProfile())
  774.             ->setPackageTransaction($packageTransaction)
  775.             ->setActive(true)
  776.             ->setStatus(PackageSongwriterStatus::ACTIVE)
  777.             ->setTypeSubcription("normal");
  778.         if((float)$packageTransaction->getPackage()->getPrice() > && $manual === ""){
  779.             if($packageTransaction->getPackage()->getType() === PackageType::SUBSCRIPTION){
  780.                 switch ($packageTransaction->getPaymentGateway()->getPaymentType()->getName()){
  781.                     case TransactionPlatform::STRIPE:
  782.                         /** @var Subscription $stripeSubscription */
  783.                         $stripeSubscription $this->paymentMethodService->processToGetSubscriptionTransactionInformation(
  784.                             $packageTransaction
  785.                         );
  786.                         $packageSongwriter->setAvialableOn(\DateTime::createFromFormat('U'$stripeSubscription->current_period_start));
  787.                         $packageSongwriter->setAvialableOff(\DateTime::createFromFormat('U'$stripeSubscription->current_period_end));
  788.                         break;
  789.                     case TransactionPlatform::PAYPAL:
  790.                         /** @var PaypalSubscriptionDTO $paypalSubscription */
  791.                         $paypalSubscription $this->paymentMethodService->processToGetSubscriptionTransactionInformation(
  792.                             $packageTransaction
  793.                         );
  794.                         $startDate = \DateTime::createFromFormat(
  795.                             'Y-m-d\TH:i:s\Z',
  796.                             $paypalSubscription->getUpdateTime()
  797.                         );
  798.                         $packageSongwriter->setAvialableOn($startDate);
  799.                         $endDate = \DateTime::createFromFormat(
  800.                             'Y-m-d\TH:i:s\Z',
  801.                             $paypalSubscription->getBillingInfo()->getNextBillingTime()
  802.                         );
  803.                         $packageSongwriter->setAvialableOff($endDate);
  804.                         break;
  805.                 }
  806.             }else{
  807.             }
  808.         }else{
  809.             if($manual !== Constants::MANUAL_PROCESS_CREATE_SUBCRIPTION){
  810.                 $startDate = new \DateTime();
  811.                 $packageSongwriter->setAvialableOn($startDate);
  812.                 $endDate = new \DateTime();
  813.                 $endDate = ($packageTransaction->getPackage()->isMonthly()) ? $endDate->modify("+1 month") : $endDate->modify('+1 year');
  814.                 $packageSongwriter->setAvialableOff($endDate);
  815.             }else{
  816.                 $packageSongwriter->setAvialableOn($packageTransaction->getProcessedAt());
  817.                 $endDate =$packageTransaction->getProcessedAt();
  818.                 $endDate = ($packageTransaction->getPackage()->isMonthly()) ? $endDate->modify("+1 month") : $endDate->modify('+1 year');
  819.                 $packageSongwriter->setAvialableOff($endDate);
  820.             }
  821.         }
  822.         $packageSongwriter $this->packageSongwriterRepository->save($packageSongwriter);
  823.         /** @var PackageSongWriter $packageSongwriter */
  824.         $packageSongwriter $this->packageSongwriterRepository->findOneBy(['id' => $packageSongwriter->getId()]);
  825.         return $packageSongwriter;
  826.     }
  827.     /**
  828.      * @param \DateTime $dateBegin
  829.      * @param PackageTransaction $packageTransaction
  830.      * @return PackageTransaction
  831.      */
  832.     public function processToCheckDateForManualPaymentInTransaction(
  833.         \DateTime $dateBegin,
  834.         PackageTransaction $packageTransaction
  835.     )
  836.     {
  837.         $currentDate = new \DateTime();
  838.         if($dateBegin->getTimestamp() > $currentDate->getTimestamp()){
  839.             $packageTransaction->setStatus(TransactionPlatformStatus::CREATED);
  840.         }
  841.         $packageTransaction->setCreatedAt($dateBegin);
  842.         $packageTransaction->setProcessedAt($dateBegin);
  843.         $this->packageTransactionRepository->flush($packageTransaction);
  844.         return $packageTransaction;
  845.     }
  846.     /**
  847.      * @param PackageTransaction $packageTransaction
  848.      * @param PackageSongWriter $packageSongWriter
  849.      * @return Invoice
  850.      */
  851.     public function processToCreateInvoice(
  852.         PackageTransaction $packageTransaction,
  853.         PackageSongWriter $packageSongWriter
  854.     )
  855.     {
  856.         $invoice = (new Invoice())
  857.             ->setPackageSongWriter($packageSongWriter)
  858.             ->setNumber($packageTransaction->getId().$packageSongWriter->getId()."-".$this->invoiceCounter($packageSongWriter))
  859.             ->setBillingDate($packageTransaction->getCreatedAt())
  860.             ->setSubTotal($packageTransaction->getPackage()->getPrice())
  861.             ->setDiscount($packageTransaction->getPackage()->getDiscount() * $packageTransaction->getPackage()->getPrice())
  862.             ->setTaxes(0)
  863.             ->setStatus(PackageSongwriterStatus::ACTIVE)
  864.             ->setAvialableOn($packageSongWriter->getAvialableOn())
  865.             ->setAvialableOff($packageSongWriter->getAvialableOff());
  866.         $invoiceItems = [
  867.             $this->serializer->serialize($packageTransaction->getPackage(), "json", ['groups' => 'invoice:json'])
  868.         ];
  869.         $invoice->setItems(json_encode($invoiceItems));
  870.         $totalAmount = (float)$packageTransaction->getPackage()->getPrice() - ((float)$packageTransaction->getPackage()->getDiscount() * (float)$packageTransaction->getPackage()->getPrice());
  871.         $invoice->setTotal($totalAmount);
  872.         $invoice $this->invoiceRepository->save($invoice);
  873.         /** @var Invoice $invoice */
  874.         $invoice $this->invoiceRepository->findOneBy(['id' => $invoice->getId()]);
  875.         return $invoice;
  876.     }
  877.     /**
  878.      * @param PackageSongWriter $packageSongWriter
  879.      * @return int
  880.      */
  881.     public function invoiceCounter(PackageSongWriter $packageSongWriter$to "create")
  882.     {
  883.         $invoices $this->invoiceRepository->findBy(['packageSongWriter' => $packageSongWriter]);
  884.         if($to === "create"){
  885.             return count($invoices) + 1;
  886.         }else{
  887.             return count($invoices);
  888.         }
  889.     }
  890.     /**
  891.      * @param Profile $profile
  892.      * @return PackageSongWriter|null
  893.      */
  894.     public function processToCheckActiveInactiveSubscription(Profile $profile)
  895.     {
  896.         /** @var PackageSongWriter $packageSongwriter */
  897.         foreach ($this->packageSongwriterRepository->findBy(['profile' => $profile]) as $packageSongwriter){
  898.             if(
  899.                 $packageSongwriter->getActive() &&
  900.                 ($packageSongwriter->getStatus() === PackageSongwriterStatus::ACTIVE ||
  901.                     $packageSongwriter->getStatus() === PackageSongwriterStatus::INACTIVE) &&
  902.                 $packageSongwriter->getPackage()->getType() === PackageType::SUBSCRIPTION
  903.             ){
  904.                 return $packageSongwriter;
  905.             }
  906.         }
  907.         return null;
  908.     }
  909.     /*
  910.     * Get only Active subscription 
  911.     * @param Profile $profile
  912.     * @return PackageSongWriter|null
  913.     */ 
  914.     public function processToCheckActiveSubscription(Profile $profile)
  915.     {
  916.         /** @var PackageSongWriter $packageSongwriter */
  917.         foreach ($this->packageSongwriterRepository->findBy(['profile' => $profile]) as $packageSongwriter){
  918.             if(
  919.                 $packageSongwriter->getActive() &&
  920.                 $packageSongwriter->getStatus() === PackageSongwriterStatus::ACTIVE &&
  921.                 $packageSongwriter->getPackage()->getType() === PackageType::SUBSCRIPTION
  922.             ){
  923.                 return $packageSongwriter;
  924.             }
  925.         }
  926.         return null;
  927.     }
  928.     /**
  929.      * @param PackageTransaction $packageTransaction
  930.      * @return object|null
  931.      */
  932.     public function processToCancelAPackageTransactionWithPackage(PackageTransaction $packageTransaction)
  933.     {
  934.         if($packageTransaction->getPackage()->getType() === PackageType::PRIMARY){
  935.             $packageTransaction->setStatus(TransactionPlatformStatus::CANCELED);
  936.             $this->packageTransactionRepository->flush($packageTransaction);
  937.             /** @var PackageSongWriter $packageSongWriter */
  938.             $packageSongWriter $this->packageSongwriterRepository->findOneBy(['packageTransaction' => $packageTransaction]);
  939.             $packageSongWriter->setActive(false);
  940.             $packageSongWriter->setStatus(PackageSongwriterStatus::CANCELLED);
  941.             $this->packageSongwriterRepository->flush($packageSongWriter);
  942.             //Set the invoice status as cancelled
  943.             $this->updateTheInvoiceStatus($packageSongWriterPackageSongwriterStatus::CANCELLED);
  944.         }
  945.         return $this->packageTransactionRepository->findOneBy(['id' => $packageTransaction->getId()]);
  946.     }
  947.     /**
  948.      * @param string $comment
  949.      * @param PackageTransaction $packageTransaction
  950.      * @param string $from
  951.      * @return object|null
  952.      */
  953.     public function processToCancelASubscription(
  954.         string $comment,
  955.         PackageTransaction $packageTransaction,
  956.         string  $from "web"
  957.     )
  958.     {
  959.         if($from === "web" && (float)$packageTransaction->getPackage()->getPrice() > && !$packageTransaction->isManual()){
  960.             if($packageTransaction->getCancelUrl() !== "" && $packageTransaction->getReturnUrl() !== ""){
  961.                 if($packageTransaction->getPaymentGateway()->getPaymentType()->getName() === TransactionPlatform::PAYPAL){
  962.                     /** @var PaypalSubscriptionDTO $paypalSubscriptionDTO */
  963.                     $paypalSubscriptionDTO $this->paymentMethodService->processToCancelSubscription(
  964.                         $packageTransaction,
  965.                         $comment
  966.                     );
  967.                     $packageTransaction->setPaymentGatewayProcess($this->serializer->serialize(
  968.                         $paypalSubscriptionDTO,
  969.                         "json",
  970.                         ['groups' => 'paypal:subscription']
  971.                     ));
  972.                 }else if($packageTransaction->getPaymentGateway()->getPaymentType()->getName() === TransactionPlatform::STRIPE){
  973.                     /** @var Subscription $stripeSubscription */
  974.                     $stripeSubscription $this->paymentMethodService->processToCancelSubscription(
  975.                         $packageTransaction,
  976.                         $comment
  977.                     );
  978.                     $packageTransaction->setPaymentGatewayProcess($stripeSubscription->toJSON());
  979.                 }
  980.             }
  981.         }
  982.         $packageTransaction->setStatus(TransactionPlatformStatus::CANCELED);
  983.         $this->packageTransactionRepository->flush($packageTransaction);
  984.         /** @var PackageSongWriter $packageSongWriter */
  985.         $packageSongWriter $this->packageSongwriterRepository->findOneBy(['packageTransaction' => $packageTransaction]);
  986.         $packageSongWriter->setActive(false);
  987.         $packageSongWriter->setStatus(PackageSongwriterStatus::CANCELLED);
  988.         $this->packageSongwriterRepository->flush($packageSongWriter);
  989.         //Set the invoice status as cancelled
  990.         $this->updateTheInvoiceStatus($packageSongWriterPackageSongwriterStatus::CANCELLED);
  991.         $this->eventDispatcher->dispatch(new PackageTransactionSubscriptionCanceledEvent($packageTransaction$from));
  992.         return $this->packageTransactionRepository->findOneBy(['id' => $packageTransaction->getId()]);
  993.     }
  994.     /**
  995.      * @param string $comment
  996.      * @param string $paymentGatewayStatus
  997.      * @param PackageTransaction $packageTransaction
  998.      * @param string $from
  999.      * @return object|null
  1000.      */
  1001.     public function processToInactiveASubscription(
  1002.         string $comment,
  1003.         string $paymentGatewayStatus,
  1004.         PackageTransaction $packageTransaction,
  1005.         string  $from "web"
  1006.     )
  1007.     {
  1008.         /** @var ReactivationAttempts $lastReactivationAttempt */
  1009.         $lastReactivationAttempt $this->getReactivationAttempts($packageTransaction);
  1010.         $currentDate = new \DateTime();
  1011.         $tryAgain false;
  1012.         if(is_null($lastReactivationAttempt)){
  1013.             $tryAgain true;
  1014.         }else if($currentDate->getTimestamp() >= $lastReactivationAttempt->getNextAttemptDate()->getTimestamp()){
  1015.             $tryAgain true;
  1016.         }
  1017.         if($packageTransaction->getReactivationAttempts()->count() < && $tryAgain){
  1018.             if($from === "web" && (float)$packageTransaction->getPackage()->getPrice() > 0){
  1019.                 if($packageTransaction->getCancelUrl() !== "" && $packageTransaction->getReturnUrl() !== ""){
  1020.                     if($packageTransaction->getPaymentGateway()->getPaymentType()->getName() === TransactionPlatform::PAYPAL){
  1021.                         /** @var PaypalSubscriptionDTO $paypalSubscriptionDTO */
  1022.                         $paypalSubscriptionDTO $this->paymentMethodService->processToSuspendSubscription(
  1023.                             $packageTransaction,
  1024.                             $comment
  1025.                         );
  1026.                         $packageTransaction->setPaymentGatewayProcess($this->serializer->serialize(
  1027.                             $paypalSubscriptionDTO,
  1028.                             "json",
  1029.                             ['groups' => 'paypal:subscription']
  1030.                         ));
  1031.                     }else if($packageTransaction->getPaymentGateway()->getPaymentType()->getName() === TransactionPlatform::STRIPE){
  1032.                         /** @var Subscription $stripeSubscription */
  1033.                         $stripeSubscription $this->paymentMethodService->processToSuspendSubscription(
  1034.                             $packageTransaction,
  1035.                             $comment
  1036.                         );
  1037.                         $packageTransaction->setPaymentGatewayProcess($stripeSubscription->toJSON());
  1038.                     }
  1039.                 }
  1040.             }
  1041.             $packageTransaction->setStatus(TransactionPlatformStatus::INACTIVE);
  1042.             $this->packageTransactionRepository->flush($packageTransaction);
  1043.             /** @var PackageSongWriter $packageSongWriter */
  1044.             $packageSongWriter $this->packageSongwriterRepository->findOneBy(['packageTransaction' => $packageTransaction]);
  1045.             $packageSongWriter->setActive(true);
  1046.             $packageSongWriter->setStatus(PackageSongwriterStatus::INACTIVE);
  1047.             $this->packageSongwriterRepository->flush($packageSongWriter);
  1048.             if($from === "command" || $from === "webhook"){
  1049.                 $reactiveAttempt= (new ReactivationAttempts())
  1050.                     ->setPackageTransaction($packageTransaction)
  1051.                     ->setPaymentGatewayName($packageTransaction->getPaymentGateway()->getPaymentType()->getName())
  1052.                     ->setPaymentGatewayStatus($paymentGatewayStatus)
  1053.                     ->setAttemptDate(new \DateTime());
  1054.                 $nextAttemptDate = new \DateTime();
  1055.                 $nextAttemptDate->modify("+5 day");
  1056.                 $reactiveAttempt->setNextAttemptDate($nextAttemptDate);
  1057.                 $reactiveAttempt->setAttemptMessageSent(true);
  1058.                 $this->reactiveAttemptsRepository->save($reactiveAttempt);
  1059.                 $this->eventDispatcher->dispatch(new PackageTransactionSubscriptionInactivatedEvent($packageTransaction$from));
  1060.             }
  1061.         }
  1062.         return $this->packageTransactionRepository->findOneBy(['id' => $packageTransaction->getId()]);
  1063.     }
  1064.     /**
  1065.      * @param ManualInvoice $manualInvoice
  1066.      * @param PackageTransaction $packageTransaction
  1067.      * @param string $manual
  1068.      * @param string $from
  1069.      * @return object|null
  1070.      * @throws \GuzzleHttp\Exception\GuzzleException
  1071.      */
  1072.     public function processToReactiveASubscription(
  1073.         ManualInvoice $manualInvoice,
  1074.         PackageTransaction $packageTransaction,
  1075.         string $from "command"
  1076.     )
  1077.     {
  1078.         $currentDate = new \DateTime();
  1079.         $packageTransaction->setStatus(TransactionPlatformStatus::COMPLETED);
  1080.         $packageTransaction->setManual(true);
  1081.         $this->packageTransactionRepository->flush($packageTransaction);
  1082.         /** @var PackageSongWriter $packageSongWriter */
  1083.         $packageSongWriter $this->packageSongwriterRepository->findOneBy(['packageTransaction' => $packageTransaction]);
  1084.         $packageSongWriter->setActive(true);
  1085.         $packageSongWriter->setStatus(PackageSongwriterStatus::ACTIVE);
  1086.         $packageSongWriter->setAvialableOn($manualInvoice->getDateBegin());
  1087.         $packageSongWriter->setAvialableOff($manualInvoice->getDateEnd());
  1088.         if($packageSongWriter->getAvialableOn()->getTimestamp() > $currentDate->getTimestamp()){
  1089.             $packageSongWriter->setStatus(PackageSongwriterStatus::PENDING);
  1090.         }
  1091.         $this->packageSongwriterRepository->flush($packageSongWriter);
  1092.         $this->activeTheLastInvoice($packageSongWriter$manualInvoice);
  1093.         if(!$packageTransaction->isResumeMessageSent()){
  1094.             $packageTransaction->setResumeMessageSent(true);
  1095.             /*$this->eventDispatcher->dispatch(new PackageTransactionSubscriptionReactivatedEvent(
  1096.                 $packageTransaction,
  1097.                 $from
  1098.             ));*/
  1099.         }
  1100.         return $this->packageTransactionRepository->findOneBy(['id' => $packageTransaction->getId()]);
  1101.     }
  1102.     /**
  1103.      * @param PackageTransaction $packageTransaction
  1104.      * @param ManualInvoice $manualIncoive
  1105.      * @return void
  1106.      */
  1107.     public function processToAddAnInvoiceManually(
  1108.         PackageTransaction $packageTransaction,
  1109.         ManualInvoice $manualInvoice
  1110.     )
  1111.     {
  1112.         $currentDate = new \DateTime();
  1113.         /** @var PackageSongWriter $packageSongWriter */
  1114.         $packageSongWriter $this->packageSongwriterRepository->findOneBy(['packageTransaction' => $packageTransaction]);
  1115.         $packageSongWriter->setAvialableOn($manualInvoice->getDateBegin());
  1116.         $packageSongWriter->setAvialableOff($manualInvoice->getDateEnd());
  1117.         if($packageSongWriter->getAvialableOn()->getTimestamp() > $currentDate->getTimestamp()){
  1118.             $packageSongWriter->setStatus(PackageSongwriterStatus::PENDING);
  1119.         }
  1120.         $this->packageSongwriterRepository->flush($packageSongWriter);
  1121.         /** @var PackageSongWriter $packageSongWriter */
  1122.         $packageSongWriter $this->packageSongwriterRepository->findOneBy(['id' => $packageSongWriter->getId()]);
  1123.         $invoice = (new Invoice())
  1124.             ->setPackageSongWriter($packageSongWriter)
  1125.             ->setNumber($packageTransaction->getId().$packageSongWriter->getId()."-".$this->invoiceCounter($packageSongWriter))
  1126.             ->setHorusNumber($manualInvoice->getIdentifier())
  1127.             ->setBillingDate($manualInvoice->getDateBegin())
  1128.             ->setSubTotal($packageTransaction->getPackage()->getPrice())
  1129.             ->setDiscount($packageTransaction->getPackage()->getDiscount() * $packageTransaction->getPackage()->getPrice())
  1130.             ->setTaxes(0)
  1131.             ->setStatus($packageSongWriter->getStatus())
  1132.             ->setAvialableOn($manualInvoice->getDateBegin())
  1133.             ->setAvialableOff($manualInvoice->getDateEnd());
  1134.         $invoiceItems = [
  1135.             $this->serializer->serialize($packageTransaction->getPackage(), "json", ['groups' => 'invoice:json'])
  1136.         ];
  1137.         $invoice->setItems(json_encode($invoiceItems));
  1138.         $totalAmount = (float)$packageTransaction->getPackage()->getPrice() - ((float)$packageTransaction->getPackage()->getDiscount() * (float)$packageTransaction->getPackage()->getPrice());
  1139.         $invoice->setTotal($totalAmount);
  1140.         $invoice $this->invoiceRepository->save($invoice);
  1141.     }
  1142.     /**
  1143.      * This function is used in the command to check if the subscription are pending and they need to change to active
  1144.      * @return array
  1145.      */
  1146.     public function processToActivePendingSubscription()
  1147.     {
  1148.         $dataPackageProfiles = [];
  1149.         $currentDate =  new \DateTime();
  1150.         /** @var PackageSongWriter $packageSongWriter */
  1151.         foreach ($this->packageSongwriterRepository->findAll() as $packageSongWriter){
  1152.             if($packageSongWriter->getStatus() === PackageSongwriterStatus::PENDING){
  1153.                 if($packageSongWriter->getAvialableOn()->getTimestamp() <= $currentDate->getTimestamp()){
  1154.                     $packageSongWriter->setStatus(PackageSongwriterStatus::ACTIVE);
  1155.                     $this->packageSongwriterRepository->flush($packageSongWriter);
  1156.                     
  1157.                     /** @var Invoice $invoice */
  1158.                     foreach ($this->invoiceRepository->findBy(['packageSongWriter' => $packageSongWriter]) as $invoice){
  1159.                         $invoice->setStatus(PackageSongwriterStatus::ACTIVE);
  1160.                         $this->invoiceRepository->flush($invoice);
  1161.                     }
  1162.                     $packageTransaction $packageSongWriter->getPackageTransaction();
  1163.                     $packageTransaction->setStatus(TransactionPlatformStatus::COMPLETED);
  1164.                     $this->packageTransactionRepository->flush($packageTransaction);
  1165.                     $dataPackageProfiles[] = $this->packageSongwriterRepository->findOneBy([
  1166.                         'id' => $packageSongWriter->getId()
  1167.                     ]);
  1168.                 }
  1169.             }
  1170.         }
  1171.         return $dataPackageProfiles;
  1172.     }
  1173.     /**
  1174.      * @param PackageSongWriter $packageSongWriter
  1175.      * @param Object $objectQuery this can be an object for a Paypal subscription or an object for a Stripe subscription
  1176.      * @return object|null
  1177.      */
  1178.     public function processToUpdateDatesTransaction(
  1179.         PackageSongWriter $packageSongWriter,
  1180.         Object $objectQuery
  1181.     )
  1182.     {
  1183.         echo $packageSongWriter->getId()."\n";
  1184.         $update false;
  1185.         $packageTransaction $packageSongWriter->getPackageTransaction();
  1186.         /*if($packageTransaction->getPaymentGateway()->getPaymentType()->getName() === TransactionPlatform::PAYPAL){
  1187.             $objectQuery = $objectQuery;
  1188.             $beginDate = \DateTime::createFromFormat('Y-m-d\TH:i:s\Z', $objectQuery->getUpdateTime());
  1189.             $endDate = \DateTime::createFromFormat('Y-m-d\TH:i:s\Z', $objectQuery->getBillingInfo()->getNextBillingTime());
  1190.             if($beginDate->getTimestamp() > $packageSongWriter->getAvialableOn()->getTimestamp()){
  1191.                 if($beginDate->format('Y-m-d') != $packageSongWriter->getAvialableOn()->format('Y-m-d')){
  1192.                     $update = !$update;
  1193.                 }
  1194.             }
  1195.         }else if($packageTransaction->getPaymentGateway()->getPaymentType()->getName() === TransactionPlatform::STRIPE){
  1196.             $objectQuery = $objectQuery;
  1197.             $beginDate = \DateTime::createFromFormat('U', $objectQuery->current_period_start);
  1198.             $endDate = \DateTime::createFromFormat('U', $objectQuery->current_period_end);
  1199.             if($beginDate->getTimestamp() > $packageSongWriter->getAvialableOn()->getTimestamp()){
  1200.                 $stripeInvoice = $this->paymentMethodService->processtoGetInvoiceInformation(
  1201.                     $packageTransaction,
  1202.                     $objectQuery->latest_invoice
  1203.                 );
  1204.                 $invoiceBeginDate = \DateTime::createFromFormat('U', $stripeInvoice->period_start);
  1205.                 if($invoiceBeginDate->format('Y-m-d') != $packageSongWriter->getAvialableOn()->format('Y-m-d')){
  1206.                     if($stripeInvoice->status === StripeApiInvoiceStatus::PAID){
  1207.                         $update = !$update;
  1208.                     }
  1209.                 }
  1210.             }
  1211.         }
  1212.         if($update){
  1213.             $packageSongWriter->setAvialableOn($beginDate);
  1214.             $packageSongWriter->setAvialableOff($endDate);
  1215.             $this->packageSongwriterRepository->flush($packageSongWriter);
  1216.             $this->updateTheInvoiceStatus($packageSongWriter, PackageSongwriterStatus::INACTIVE);
  1217.             $invoice = (new Invoice())
  1218.                 ->setPackageSongWriter($packageSongWriter)
  1219.                 ->setNumber($packageTransaction->getId().$packageSongWriter->getId()."-".$this->invoiceCounter($packageSongWriter))
  1220.                 ->setBillingDate($beginDate)
  1221.                 ->setSubTotal($packageTransaction->getPackage()->getPrice())
  1222.                 ->setDiscount($packageTransaction->getPackage()->getDiscount() * $packageTransaction->getPackage()->getPrice())
  1223.                 ->setTaxes(0)
  1224.                 ->setStatus(PackageSongwriterStatus::ACTIVE)
  1225.                 ->setAvialableOn($packageSongWriter->getAvialableOn())
  1226.                 ->setAvialableOff($packageSongWriter->getAvialableOff());
  1227.             $invoiceItems = [
  1228.                 $this->serializer->serialize($packageTransaction->getPackage(), "json", ['groups' => 'invoice:json'])
  1229.             ];
  1230.             $invoice->setItems(json_encode($invoiceItems));
  1231.             $totalAmount = (float)$packageTransaction->getPackage()->getPrice() - ((float)$packageTransaction->getPackage()->getDiscount() * (float)$packageTransaction->getPackage()->getPrice());
  1232.             $invoice->setTotal($totalAmount);
  1233.             $invoice = $this->invoiceRepository->save($invoice);
  1234.             $this->eventDispatcher->dispatch(new PackageTransactionApprovedEvent(
  1235.                 $packageTransaction,
  1236.                 "command"
  1237.             ));
  1238.         }*/
  1239.         return $this->packageTransactionRepository->findOneBy(['id' => $packageTransaction->getId()]);
  1240.     }
  1241.     /**
  1242.      * @param PackageSongWriter $packageSongWriter
  1243.      * @param string $status
  1244.      */
  1245.     public function updateTheInvoiceStatus(PackageSongWriter $packageSongWriterstring $status)
  1246.     {
  1247.         /** @var Invoice $invoice */
  1248.         foreach ($this->invoiceRepository->findBy(['packageSongWriter' => $packageSongWriter]) as $invoice){
  1249.             $invoice->setStatus($status);
  1250.             $this->invoiceRepository->flush($invoice);
  1251.         }
  1252.     }
  1253.     /**
  1254.      * @param PackageTransaction $packageTransaction
  1255.      * @return ReactivationAttempts|null
  1256.      */
  1257.     public function getReactivationAttempts(PackageTransaction $packageTransaction)
  1258.     {
  1259.         $result null;
  1260.         /** @var ReactivationAttempts $reactivationAttempt */
  1261.         foreach ($this->reactiveAttemptsRepository->findBy(['packageTransaction' => $packageTransaction]) as $reactivationAttempt){
  1262.             if(is_null($result)){
  1263.                 $result $reactivationAttempt;
  1264.             }else if($result->getNextAttemptDate()->getTimestamp() <= $reactivationAttempt->getNextAttemptDate()->getTimestamp()){
  1265.                 $result $reactivationAttempt;
  1266.             }
  1267.         }
  1268.         return $result;
  1269.     }
  1270.     /**
  1271.      * @param string $data
  1272.      * @param PaymentGateway $paymentGateway
  1273.      * @param string $sigHeader
  1274.      * @return void
  1275.      * @throws \GuzzleHttp\Exception\GuzzleException
  1276.      */
  1277.     public function processingWebHook(string $dataPaymentGateway $paymentGatewaystring $sigHeader)
  1278.     {
  1279.         $result $this->paymentMethodService->processToGetWebHook($paymentGateway$data$sigHeader);
  1280.         $event = (new PaymentGatewayEvent())
  1281.             ->setPaymentGateway($paymentGateway)
  1282.             ->setInformation($data);
  1283.         if($paymentGateway->getPaymentType()->getName() === TransactionPlatform::PAYPAL){
  1284.             /** @var PaypalWebHookDTO $result */
  1285.             $result $result;
  1286.             $event->setEvent($result->getEventType())
  1287.                 ->setExternalId($result->getId());
  1288.             $objectArray $result->getResource();
  1289.             switch ($result->getEventType()){
  1290.                 case PaypalWebHookList::PAYMENT_SALE_COMPLETED:
  1291.                     if(isset($objectArray['billing_agreement_id'])){
  1292.                         $packageTransaction $this->getTransactionByExternalId($objectArray['billing_agreement_id']);
  1293.                         /** @var PaypalSubscriptionDTO $paypalSubscription */
  1294.                         $paypalSubscription $this->paymentMethodService->processToGetSubscriptionTransactionInformation(
  1295.                             $packageTransaction
  1296.                         );
  1297.                         $beginDate = \DateTime::createFromFormat('Y-m-d\TH:i:s\Z'$paypalSubscription->getUpdateTIme());
  1298.                         $endDate = \DateTime::createFromFormat('Y-m-d\TH:i:s\Z'$paypalSubscription->getBillingInfo()->getNextBillingTime());
  1299.                         $packageSongwriter $this->getRelationByPackageTransaction($packageTransaction);
  1300.                         if($packageSongwriter->getAvialableOn()->format("Y-m-d") !== $beginDate->format("Y-m-d")){
  1301.                             $packageTransaction $this->updateTransactionDates(
  1302.                                 $packageTransaction,
  1303.                                 $packageSongwriter,
  1304.                                 $beginDate,
  1305.                                 $endDate
  1306.                             );
  1307.                         }
  1308.                     }
  1309.                     break;
  1310.                 case PaypalWebHookList::BILLING_SUBSCRIPTION_CANCELLED:
  1311.                     $packageTransaction $this->getTransactionByExternalId($objectArray['id']);
  1312.                     $packageTransaction $this->processToCancelASubscription(
  1313.                         "From Webhook",
  1314.                         $packageTransaction,
  1315.                         "webhook"
  1316.                     );
  1317.                     break;
  1318.                 case PaypalWebHookList::BILLING_SUBSCRIPTION_SUSPENDED:
  1319.                 case PaypalWebHookList::PAYMENT_SALE_DENIED:
  1320.                 case PaypalWebHookList::BILLING_SUBSCRIPTION_PAYMENT_FAILED:
  1321.                     $packageTransaction $this->getTransactionByExternalId($objectArray['id']);
  1322.                     $packageTransaction $this->processToInactiveASubscription(
  1323.                         "From Webhook",
  1324.                         $objectArray['status'],
  1325.                         $packageTransaction,
  1326.                         "webhook"
  1327.                     );
  1328.                     break;
  1329.                 case PaypalWebHookList::BILLING_SUBSCRIPTION_ACTIVATED:
  1330.                     /*$packageTransaction = $this->getTransactionByExternalId($objectArray['id']);
  1331.                     $paypalSubscription = $this->paymentMethodService->processToGetSubscriptionTransactionInformation(
  1332.                         $packageTransaction
  1333.                     );
  1334.                     $beginDate = \DateTime::createFromFormat('Y-m-d\TH:i:s\Z', $paypalSubscription->getStatusUpdateTime());
  1335.                     $endDate = \DateTime::createFromFormat('Y-m-d\TH:i:s\Z', $paypalSubscription->getBillingInfo()->getNextBillingTime());
  1336.                     $packageSongwriter = $this->getRelationByPackageTransaction($packageTransaction);
  1337.                     if($beginDate->getTimestamp() > $packageSongwriter->getAvialableOn()->getTimestamp()){
  1338.                         $packageTransaction = $this->processToReactiveASubscription(
  1339.                             "From Webhook",
  1340.                             $packageTransaction,
  1341.                             "webhook"
  1342.                         );
  1343.                     }
  1344.                     if($packageSongwriter->getAvialableOn()->getTimestamp() !== $beginDate->getTimestamp()){
  1345.                         $packageTransaction = $this->updateTransactionDates(
  1346.                             $packageTransaction,
  1347.                             $packageSongwriter,
  1348.                             $beginDate,
  1349.                             $endDate
  1350.                         );
  1351.                     }*/
  1352.                     break;
  1353.             }
  1354.         }else if($paymentGateway->getPaymentType()->getName() === TransactionPlatform::STRIPE){
  1355.             /** @var \Stripe\Event $result */
  1356.             $result $result;
  1357.             $arrayResult json_decode($result->toJSON(), true);
  1358.             $arrayResult $arrayResult['data']['object'];
  1359.             $f fopen("uploads/webhook.txt"'a+');
  1360.             fwrite($fjson_encode($arrayResult)."\n");
  1361.             fwrite($fjson_encode($result->type)."\n");
  1362.             fclose($f);
  1363.             
  1364.             $event->setEvent($result->type)
  1365.                 ->setExternalId($result->id);
  1366.             switch ($result->type){
  1367.                 case StripeWebHookList::INVOICE_PAID:
  1368.                     if(isset($arrayResult['subscription']) && !is_null($arrayResult['subscription'])){
  1369.                         $packageTransaction $this->getTransactionByExternalId($arrayResult['subscription']);
  1370.                         /** @var Subscription $stripeSubscription */
  1371.                         $stripeSubscription $this->paymentMethodService->processToGetSubscriptionTransactionInformation(
  1372.                             $packageTransaction
  1373.                         );
  1374.                         $beginDate = \DateTime::createFromFormat('U'$stripeSubscription->current_period_start);
  1375.                         $endDate = \DateTime::createFromFormat('U'$stripeSubscription->current_period_end);
  1376.                         $f fopen("uploads/webhook.txt"'a+');
  1377.                         fwrite($f$beginDate->getTimestamp()."\n");
  1378.                         fwrite($f$stripeSubscription->latest_invoice."\n");
  1379.                         fclose($f);
  1380.                         /** @var \Stripe\Invoice $stripeInvoice */
  1381.                         $stripeInvoice $this->paymentMethodService->processtoGetInvoiceInformation(
  1382.                             $packageTransaction,
  1383.                             $stripeSubscription->latest_invoice
  1384.                         );
  1385.                         if($stripeInvoice->status === StripeApiInvoiceStatus::PAID && $arrayResult['id'] === $stripeInvoice->id){
  1386.                             $packageSongWriter $this->getRelationByPackageTransaction($packageTransaction);
  1387.                             if($packageSongWriter->getAvialableOn()->format("Y-m-d") !== $beginDate->format("Y-m-d")){
  1388.                                 $packageTransaction $this->updateTransactionDates(
  1389.                                     $packageTransaction,
  1390.                                     $packageSongWriter,
  1391.                                     $beginDate,
  1392.                                     $endDate
  1393.                                 );
  1394.                             }
  1395.                         }
  1396.                     }
  1397.                     break;
  1398.                 case StripeWebHookList::SUBSCRIPTION_DELETED:
  1399.                     $packageTransaction $this->getTransactionByExternalId($arrayResult['id']);
  1400.                     $packageTransaction $this->processToCancelASubscription(
  1401.                         "From Webhook",
  1402.                         $packageTransaction,
  1403.                         "webhook"
  1404.                     );
  1405.                     break;
  1406.                 case StripeWebHookList::SUBSCRIPTION_PAUSED:
  1407.                 case StripeWebHookList::INVOICE_PAYMENT_FAILED:
  1408.                 case StripeWebHookList::INVOICE_OVERDUE:
  1409.                     $packageTransaction $this->getTransactionByExternalId($arrayResult['id']);
  1410.                     $packageTransaction $this->processToInactiveASubscription(
  1411.                         "From Webhook",
  1412.                         $arrayResult['status']." ".$arrayResult['pause_collection'],
  1413.                         $packageTransaction,
  1414.                         "webhook"
  1415.                     );
  1416.                     break;
  1417.                 case StripeWebHookList::SUBSCRIPTION_RESUMED:
  1418.                     /*$packageTransaction = $this->getTransactionByExternalId($arrayResult['id']);
  1419.                     $packageTransaction = $this->processToReactiveASubscription(
  1420.                         "From Webhook",
  1421.                         $packageTransaction,
  1422.                         "webhook"
  1423.                     );
  1424.                     $stripeSubscription = $this->paymentMethodService->processToGetSubscriptionTransactionInformation(
  1425.                         $packageTransaction
  1426.                     );
  1427.                     $beginDate = \DateTime::createFromFormat('U', $stripeSubscription->current_period_start);
  1428.                     $endDate = \DateTime::createFromFormat('U', $stripeSubscription->current_period_end);
  1429.                     $packageSongwriter = $this->getRelationByPackageTransaction($packageTransaction);
  1430.                     if($packageSongwriter->getAvialableOn()->getTimestamp() !== $beginDate->getTimestamp()){
  1431.                         $packageTransaction = $this->updateTransactionDates(
  1432.                             $packageTransaction,
  1433.                             $packageSongwriter,
  1434.                             $beginDate,
  1435.                             $endDate
  1436.                         );
  1437.                     }*/
  1438.                     break;
  1439.             }
  1440.         }
  1441.         $this->paymentGatewayEventRepository->save($event);
  1442.     }
  1443.     //------------------------------------------PRIVATE FUNCTIONS-------------------------------------------------------
  1444.     /**
  1445.      * @param $externalId
  1446.      * @return PackageTransaction
  1447.      */
  1448.     private function getTransactionByExternalId($externalId)
  1449.     {
  1450.         /** @var PackageTransaction $packageTransaction */
  1451.         $packageTransaction $this->packageTransactionRepository->findOneBy([
  1452.             'paymentGatewayExternalId' => $externalId
  1453.         ]);
  1454.         if(is_null($packageTransaction)){
  1455.             throw new BadRequestHttpException("The transaction does not  exist");
  1456.         }
  1457.         return $packageTransaction;
  1458.     }
  1459.     /**
  1460.      * @param PackageTransaction $packageTransaction
  1461.      * @return PackageSongWriter
  1462.      */
  1463.     private function getRelationByPackageTransaction(PackageTransaction $packageTransaction)
  1464.     {
  1465.         /** @var PackageSongWriter $packageSongwriter */
  1466.         $packageSongwriter $this->packageSongwriterRepository->findOneBy([
  1467.            'packageTransaction' => $packageTransaction
  1468.         ]);
  1469.         if(is_null($packageSongwriter)){
  1470.             throw new BadRequestHttpException("The relation does not  exist");
  1471.         }
  1472.         return $packageSongwriter;
  1473.     }
  1474.     /**
  1475.      * @param Profile $profile
  1476.      * @return array|mixed
  1477.      */
  1478.     private function getCredentialFOrPaymentGateway(Profile $profile)
  1479.     {
  1480.         $credentials = [];
  1481.         if($profile->getProfileType()->getName() === Constants::PROFILE_TYPE_PUBLISHER_ADMINISTRATOR){
  1482.             $credentials $this->profileForPaymentMethodService->getParentPaymentGateways($profile);
  1483.         }else if($profile->getProfileType()->getName() === Constants::PROFILE_TYPE_PUBLISHER
  1484.             || $profile->getProfileType()->getName() === Constants::PROFILE_TYPE_SONGWRITER){
  1485.             $publisherAdministrator $this->profileForPaymentMethodService->findPublisherAdministratorForProfile($profile);
  1486.             $credentials $this->profileForPaymentMethodService->getParentPaymentGateways($publisherAdministrator);
  1487.         }
  1488.         return $credentials;
  1489.     }
  1490.     /**
  1491.      * @param Package $package
  1492.      * @param PackageSongWriter $oldPackageSongWriter
  1493.      * @return string
  1494.      */
  1495.     public function calculatePriceToUpgrade(
  1496.         Package $package,
  1497.         PackageSongWriter $oldPackageSongWriter
  1498.     )
  1499.     {
  1500.         $currentDate= (new \DateTime());
  1501.         $amountNewPackage = (float)$package->getPrice() - ((float)$package->getPrice() * (float)$package->getDiscount());
  1502.         $amountOldPackage =  0.00;
  1503.         $oldPackage = (is_null($oldPackageSongWriter->getPackage()->getParent())) ?
  1504.             $oldPackageSongWriter->getPackage():
  1505.             $oldPackageSongWriter->getPackage()->getParent();
  1506.         $amountOldPackage = (float)$oldPackage->getPrice() - ((float)$oldPackage->getPrice() * (float)$oldPackage->getDiscount());
  1507.         if($oldPackageSongWriter->getPackageTransaction()->getProcessedAt()->format("Y-m-d") !== $currentDate->format("Y-m-d")){
  1508.             $amountOldPackageDivided = ($oldPackage->isAnnual()) ? ($amountOldPackage 365) : ($amountOldPackage 30);
  1509.             $interval $oldPackageSongWriter->getAvialableOn()->diff($currentDate);
  1510.             $days = ($interval-><= 0) ? $interval->d;
  1511.             $amountOldPackage $amountOldPackageDivided $days;
  1512.         }
  1513.         $customPriceToUpgrade $amountNewPackage $amountOldPackage;
  1514.         return number_format($customPriceToUpgrade2".""");
  1515.     }
  1516.     /**
  1517.      * @param float $customPriceToUpgrade
  1518.      * @param Package $package
  1519.      * @param Package $oldPackage
  1520.      * @return mixed
  1521.      */
  1522.     private function buildAPackageArray(float $customPriceToUpgradePackage $packagePackage $oldPackage)
  1523.     {
  1524.         $jsonData '{
  1525.           "name": "'.$package->getName().' from '.$oldPackage->getName().'",
  1526.           "description": "Upgrade to '.$package->getName().' from '.$oldPackage->getName().'",
  1527.           "duration": '.$package->getDuration().',
  1528.           "is_monthly": '.(($package->isMonthly()) ? "true" "false").',
  1529.           "composition_limit": '.$package->getCompositionLimit().',
  1530.           "subprofile_limit": '.$package->getSubprofileLimit().',
  1531.           "is_semester": '.(($package->isSemester()) ? "true" "false").',
  1532.           "is_annual": '.(($package->isAnnual()) ? "true" "false").',
  1533.           "admin_percentage": '.$package->getAdminPercentage().',
  1534.           "price": '.$customPriceToUpgrade.',
  1535.           "quantity_sold": 0,
  1536.           "impressions_count": 0,
  1537.           "type": "'.$package->getType().'",
  1538.           "discount": '.$package->getDiscount().',
  1539.           "allow_extras": '.(($package->isAllowExtras()) ? "true" "false").',
  1540.           "visible_to_admin_only": true,
  1541.           "has_standard": false,
  1542.           "has_plus": false,
  1543.           "package_standard": null,
  1544.           "package_plus": null,
  1545.           "visible": false,
  1546.           "profile_type": {
  1547.            "id": '.$package->getProfileType()->getId().',
  1548.            "name": "'.$package->getProfileType()->getName().'"
  1549.           }
  1550.         }';
  1551.         return json_decode($jsonDatatrue);
  1552.     }
  1553.     /**
  1554.      * @param Package $oldPackage
  1555.      * @param Package $newPackage
  1556.      * @return void
  1557.      */
  1558.     private function processToCheckOldPackageNewPackage(Package $oldPackagePackage $newPackage)
  1559.     {
  1560.         $error true;
  1561.         if($oldPackage->isAnnual()){
  1562.             if($newPackage->isAnnual()){
  1563.                 $error false;
  1564.             }
  1565.         }else if($oldPackage->isMonthly()){
  1566.             if($newPackage->isMonthly()){
  1567.                 $error false;
  1568.             }
  1569.         }
  1570.         if($error){
  1571.             throw new BadRequestHttpException(
  1572.                 "Upgrade from monthly->yearly and yearly->monthly is not possible without cancellations of ongoing subscription."
  1573.             );
  1574.         }
  1575.     }
  1576.     /**
  1577.      * @param PackageTransaction $packageTransaction
  1578.      * @param PackageSongWriter $packageSongWriter
  1579.      * @param \DateTime $beginDate
  1580.      * @param \DateTime $endDate
  1581.      * @return PackageTransaction
  1582.      */
  1583.     private function updateTransactionDates(
  1584.         PackageTransaction $packageTransaction,
  1585.         PackageSongWriter $packageSongWriter,
  1586.         \DateTime $beginDate,
  1587.         \DateTime $endDate
  1588.     )
  1589.     {
  1590.         $packageSongWriter->setAvialableOn($beginDate);
  1591.         $packageSongWriter->setAvialableOff($endDate);
  1592.         $packageSongWriter->setStatus(PackageSongwriterStatus::ACTIVE);
  1593.         $this->packageSongwriterRepository->flush($packageSongWriter);
  1594.         $this->updateTheInvoiceStatus($packageSongWriterPackageSongwriterStatus::INACTIVE);
  1595.         $invoice = (new Invoice())
  1596.             ->setPackageSongWriter($packageSongWriter)
  1597.             ->setNumber($packageTransaction->getId().$packageSongWriter->getId()."-".$this->invoiceCounter($packageSongWriter))
  1598.             ->setBillingDate($beginDate)
  1599.             ->setSubTotal($packageTransaction->getPackage()->getPrice())
  1600.             ->setDiscount($packageTransaction->getPackage()->getDiscount() * $packageTransaction->getPackage()->getPrice())
  1601.             ->setTaxes(0)
  1602.             ->setStatus(PackageSongwriterStatus::ACTIVE)
  1603.             ->setAvialableOn($packageSongWriter->getAvialableOn())
  1604.             ->setAvialableOff($packageSongWriter->getAvialableOff());
  1605.         $invoiceItems = [
  1606.             $this->serializer->serialize($packageTransaction->getPackage(), "json", ['groups' => 'invoice:json'])
  1607.         ];
  1608.         $invoice->setItems(json_encode($invoiceItems));
  1609.         $totalAmount = (float)$packageTransaction->getPackage()->getPrice() - ((float)$packageTransaction->getPackage()->getDiscount() * (float)$packageTransaction->getPackage()->getPrice());
  1610.         $invoice->setTotal($totalAmount);
  1611.         $invoice $this->invoiceRepository->save($invoice);
  1612.         $this->eventDispatcher->dispatch(new PackageTransactionApprovedEvent(
  1613.             $packageTransaction,
  1614.             "command"
  1615.         ));
  1616.         return $this->packageTransactionRepository->findOneBy(['id' => $packageTransaction->getId()]);
  1617.     }
  1618.     /**
  1619.      * @param PackageSongWriter $packageSongWriter
  1620.      * @param ManualInvoice $manualInvoice
  1621.      * @return Invoice|null
  1622.      */
  1623.     private function activeTheLastInvoice(PackageSongWriter $packageSongWriterManualInvoice $manualInvoice)
  1624.     {
  1625.         $currentDate = new \DateTime();
  1626.         $invoiceCounter 0;
  1627.         $lastInvoice null;
  1628.         /** @var Invoice $invoice */
  1629.         foreach ($this->invoiceRepository->findBy(['packageSongWriter' => $packageSongWriter]) as $invoice){
  1630.             if($invoiceCounter == 0){
  1631.                 $lastInvoice $invoice;
  1632.             }else{
  1633.                 if($invoice->getAvialableOn()->getTimestamp() > $lastInvoice->getAvialableOn()->getTimestamp()){
  1634.                     $lastInvoice $invoice;
  1635.                 }
  1636.             }
  1637.         }
  1638.         $lastInvoice->setStatus(PackageSongwriterStatus::ACTIVE);
  1639.         $lastInvoice->setAvialableOn($manualInvoice->getDateBegin());
  1640.         $lastInvoice->setAvialableOff($manualInvoice->getDateEnd());
  1641.         if($lastInvoice->getAvialableOn()->getTimestamp() > $currentDate->getTimestamp()){
  1642.             $lastInvoice->setStatus(PackageSongwriterStatus::PENDING);
  1643.         }
  1644.         $this->invoiceRepository->flush($lastInvoice);
  1645.         return $lastInvoice;
  1646.     }
  1647. }