Ejemplo n.º 1
0
 public function onReceive(PaymentEvent $event)
 {
     $payment = $event->getPayment();
     $cpRepo = $this->em->getRepository('TSK\\PaymentBundle\\Entity\\ChargePayment');
     $chargePayments = $cpRepo->findBy(array('payment' => $payment));
     foreach ($chargePayments as $cp) {
         if ($cp->getCharge()->getAccount()->getName() == 'Inc Fm Students') {
             $results = array();
             $contracts = $cp->getCharge()->getContracts();
             foreach ($contracts as $contract) {
                 $inits = $this->getMonthlyPrepayments($contract);
                 $today = new \DateTime();
                 $terms = $contract->getPaymentTerms();
                 $obj = json_decode($terms['paymentsData']);
                 $d = new Deferral($obj->principal, $contract->getDeferralRate(), $contract->getDeferralDurationMonths(), $inits, $contract->getContractStartDate());
                 $numFirsts = $this->countFirstOfMonthsSince($contract->getContractStartDate());
                 $deferrals = $d->distributePaymentMax($cp->getAmount(), $contract->getDeferralDurationMonths() - $numFirsts);
                 $Deferrals = $d->datestampPayments($deferrals);
                 $debitAccount = $payment->getPaymentMethod()->getAccount();
                 $chargeDeferralAccount = $cp->getCharge()->getDeferralAccount();
                 $chargeAccount = $cp->getCharge()->getAccount();
                 foreach ($Deferrals as $DeferralDate => $DeferralAmount) {
                     $DD = new \DateTime($DeferralDate);
                     if ($DeferralAmount) {
                         if ($DD <= $today) {
                             $results[] = array('date' => $DeferralDate, 'creditAccount' => $chargeAccount, 'debitAccount' => $debitAccount, 'debitAmount' => $DeferralAmount, 'creditAmount' => $DeferralAmount, 'chargePayment' => $cp, 'description' => $cp->getCharge()->getDescription());
                             if ($cp->getAmount() > $DeferralAmount) {
                                 $results[] = array('date' => $DeferralDate, 'creditAccount' => $chargeDeferralAccount, 'debitAccount' => $debitAccount, 'debitAmount' => $cp->getAmount() - $DeferralAmount, 'creditAmount' => $cp->getAmount() - $DeferralAmount, 'chargePayment' => $cp, 'description' => $cp->getCharge()->getDescription());
                             }
                         } else {
                             $results[] = array('date' => $DeferralDate, 'creditAccount' => $chargeAccount, 'debitAccount' => $chargeDeferralAccount, 'debitAmount' => $DeferralAmount, 'creditAmount' => $DeferralAmount, 'chargePayment' => $cp, 'description' => $cp->getCharge()->getDescription());
                         }
                     }
                 }
             }
             // Here is where we actually insert into journal ...
             if (count($results)) {
                 foreach ($results as $result) {
                     $journal = $this->generateJournal($result);
                     $this->em->persist($journal);
                 }
                 $this->em->flush();
             }
         }
     }
 }
Ejemplo n.º 2
0
 /**
  * @Route("/defer/{id}/{amount}/{contractStartDate}")
  * @Template()
  * @Method({"GET"})
  */
 public function testAction(Payment $payment, $amount, \DateTime $contractStartDate = null)
 {
     $em = $this->getDoctrine()->getManager();
     $cpRepo = $em->getRepository('TSK\\PaymentBundle\\Entity\\ChargePayment');
     $chargePayments = $cpRepo->findBy(array('payment' => $payment));
     foreach ($chargePayments as $cp) {
         if ($cp->getCharge()->getAccount()->getName() == 'Inc Fm Students') {
             $contracts = $cp->getCharge()->getContracts();
             foreach ($contracts as $contract) {
                 $inits = $this->getMonthlyPrepayments($contract, $contractStartDate);
                 print '<pre>inits';
                 print_r($inits) . '</pre>';
                 $today = new \DateTime();
                 $terms = $contract->getPaymentTerms();
                 $obj = json_decode($terms['paymentsData']);
                 $d = new Deferral($obj->principal, $contract->getDeferralRate(), $contract->getDeferralDurationMonths(), $inits, $contractStartDate);
                 $numFirsts = $this->countFirstOfMonthsSince($contractStartDate);
                 // $numFirsts = $this->countFirstOfMonthsSince($contract->getContractStartDate);
                 // $deferrals = $d->distributePaymentMax($cp->getAmount(), 9);
                 $deferrals = $d->distributePaymentMax($amount, $contract->getDeferralDurationMonths() - $numFirsts);
                 $Deferrals = $d->datestampPayments($deferrals);
                 $debitAccountName = $payment->getPaymentMethod()->getAccount()->getName();
                 $chargeDeferralAccountName = $cp->getCharge()->getDeferralAccount()->getName();
                 $chargeAccountName = $cp->getCharge()->getAccount()->getName();
                 foreach ($Deferrals as $DeferralDate => $DeferralAmount) {
                     print "{$DeferralDate} - {$DeferralAmount}<br>";
                     $DD = new \DateTime($DeferralDate);
                     if ($DeferralAmount) {
                         if ($DD <= $today) {
                             $results[] = array('date' => $DeferralDate, 'creditAccount' => $chargeAccountName, 'debitAccount' => $debitAccountName, 'debitAmount' => $DeferralAmount, 'creditAmount' => $DeferralAmount);
                             if ($amount > $DeferralAmount) {
                                 $results[] = array('date' => $DeferralDate, 'creditAccount' => $chargeDeferralAccountName, 'debitAccount' => $debitAccountName, 'debitAmount' => $amount - $DeferralAmount, 'creditAmount' => $amount - $DeferralAmount);
                             }
                         } else {
                             $results[] = array('date' => $DeferralDate, 'creditAccount' => $chargeAccountName, 'debitAccount' => $chargeDeferralAccountName, 'debitAmount' => $DeferralAmount, 'creditAmount' => $DeferralAmount);
                         }
                     }
                 }
                 function sorter($key)
                 {
                     return function ($a, $b) use($key) {
                         $ad = new \DateTime($a[$key]);
                         $bd = new \DateTime($b[$key]);
                         return $ad > $bd;
                     };
                 }
                 usort($results, sorter('date'));
             }
         }
     }
     return array('today' => $today, 'results' => $results, 'foo' => '$1200 contract, 10 payments @ $120, starting on ' . $contractStartDate->format('Y-m-d') . ', deferral rate of 0.75, deferred over 10 months');
     // return array('foo' => '$1200 contract, 10 payments @ $120, starting on '.$contract->getContractStartDate()->format('Y-m-d').', deferral rate of 0.75, deferred over 10 months');
 }
Ejemplo n.º 3
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     try {
         $since = $input->getOption('since');
         $dry_run = $input->getOption('dry-run');
         $paymentID = $input->getOption('payment-id');
         $max = (int) $input->getOption('max');
         $MAX = 20;
         if ($max > 0 && $max < $MAX) {
             // nada
         } else {
             $max = $MAX;
         }
         $clauses[] = 'p.deferralTimestamp IS NULL';
         $params = array();
         if ($since) {
             $clauses[] = 'p.payment_date > :since';
             $params[':since'] = $since;
         }
         if ($paymentID) {
             $clauses[] = 'p.id = :id';
             $params[':id'] = $paymentID;
         }
         $em = $this->getContainer()->get('doctrine')->getManager();
         $query = $em->createQuery('SELECT p from TSK\\PaymentBundle\\Entity\\Payment p WHERE ' . join(' AND ', $clauses));
         $query->setParameters($params);
         $query->setFirstResult(0);
         $query->setMaxResults($max);
         $payments = $query->getResult();
         if (count($payments)) {
             foreach ($payments as $payment) {
                 $appliedCharges = $payment->getChargePayments();
                 if ($appliedCharges->count()) {
                     foreach ($appliedCharges as $chargePayment) {
                         $charge = $chargePayment->getCharge();
                         // Is this charge of type tuition?  We only defer
                         // the portion of the payment applied to tuition
                         if ($charge->getAccount()->getName() == 'Inc Fm Students') {
                             // get contract details
                             $contracts = $charge->getContracts();
                             $contract = $contracts[0];
                             $contractAmount = $contract->getAmount();
                             $contractStartDate = $contract->getCreatedDate()->format('YYYY-mm-dd');
                             $deferralDuration = $contract->getDeferralDurationMonths();
                             $deferralDistributionStrategy = $contract->getDeferralDistributionStrategy();
                             $deferralDistributionStrategy = 'accelerated';
                             if (!in_array($deferralDistributionStrategy, array('straight', 'accelerated'))) {
                                 throw new \Exception('Unrecognized deferral distribution strategy ' . $deferralDistributionStrategy);
                             }
                             $deferralRate = $contract->getDeferralRate();
                             // Sum any REALIZED payments for this contract and group by year-month ...
                             // Sum any pre-existing deferral payments for this contract and group by year-month
                             // Could have done this in mysql w/ the following query, but Doctrine doesn't support it.
                             // select year(date_realized), month(date_realized), sum(amount) from tsk_payments_deferred where fk_contract_id=6 group by year(date_realized), month(date_realized) order by year(date_realized) asc, month(date_realized) asc
                             $query = $em->createQuery('SELECT p from TSK\\PaymentBundle\\Entity\\PaymentsDeferred p WHERE p.contract=:contract ORDER BY p.dateRealized');
                             $query->setParameters(array(':contract' => $contract));
                             $deferments = $query->getResult();
                             $initialDeferrals = array();
                             foreach ($deferments as $deferment) {
                                 $key = $deferment->getDateRealized()->format('Y-m');
                                 if (empty($initialDeferrals[$key])) {
                                     $initialDeferrals[$key] = $deferment->getAmount();
                                 } else {
                                     $initialDeferrals[$key] += $deferment->getAmount();
                                 }
                             }
                             $inits = array_values($initialDeferrals);
                             if (!$inits) {
                                 $inits = array_fill(0, $contract->getDeferralDurationMonths(), 0);
                             }
                             // Set deferral schedule
                             $d = new Deferral($contract->getAmount(), $contract->getDeferralRate(), $contract->getDeferralDurationMonths(), $inits, $contract->getContractStartDate());
                             // RUN THE DEFERRALS!!
                             $deferralMethod = $deferralDistributionStrategy == 'straight' ? 'distributePaymentEvenly' : 'distributePaymentMax';
                             $deferrals = $d->{$deferralMethod}($chargePayment->getAmount(), $contract->getRemainingDeferralPeriods());
                             $Deferrals = $d->datestampPayments($deferrals);
                             if ($dry_run) {
                                 print "schedule =\n";
                                 ladybug_dump($d->getSchedule());
                                 print "initial deferrals\n";
                                 ladybug_dump($inits);
                                 print "deferrals\n";
                                 $summary = sprintf('<options=bold>$%5.2f</options=bold> Deferred at <options=bold>%3.2f</options=bold> over <options=bold>%d</options=bold> months using <options=bold>"%s"</options=bold> Strategy starting on <options=bold>%s</options=bold>', $chargePayment->getAmount(), $contract->getDeferralRate(), $contract->getRemainingDeferralPeriods(), $contract->getDeferralDistributionStrategy(), $contract->getContractStartDate()->format('Y-m-d'));
                                 $formatter = $this->getHelperSet()->get('formatter');
                                 $formattedLine = $formatter->formatSection('Deferral Summary', $summary);
                                 $output->writeln($formattedLine);
                                 ladybug_dump($Deferrals);
                                 print count($Deferrals) . " payments totalling ";
                                 print array_sum(array_values($Deferrals)) . "\n";
                             } else {
                                 foreach ($Deferrals as $DeferralDate => $DeferralAmount) {
                                     if ($DeferralAmount) {
                                         $paymentDeferred = new PaymentsDeferred();
                                         $paymentDeferred->setPayment($payment);
                                         $paymentDeferred->setAmount($DeferralAmount);
                                         $paymentDeferred->setDateRealized(new \DateTime($DeferralDate));
                                         $paymentDeferred->setContract($contract);
                                         $em->persist($paymentDeferred);
                                     }
                                     // we actually save the deferred payment each time ...
                                     $em->flush();
                                 }
                             }
                         }
                     }
                     if (!$dry_run) {
                         // Update payment deferralTimestamp
                         $payment->setDeferralTimestamp(new \DateTime());
                         $em->persist($payment);
                         $em->flush();
                     }
                 } else {
                     throw new \Exception('No charges applied to payment.  Surely, this cannot be true');
                 }
             }
         } else {
             $dialog = $this->getDialogHelper();
             $dialog->writeSection($output, "No deferrable payments match your criteria, nothing to defer.", 'bg=red;fg=white');
         }
     } catch (\PDOException $e) {
     } catch (\Exception $e) {
         $dialog = $this->getDialogHelper();
         $dialog->writeSection($output, $e->getMessage(), 'bg=red;fg=white');
     }
     if (!empty($results['errors'])) {
         $dialog = $this->getDialogHelper();
         $dialog->writeSection($output, $results['errors'][0], 'bg=yellow;fg=white');
     }
 }