mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 18:27:32 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			172 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php namespace App\Services;
 | |
| 
 | |
| use App\Models\Invoice;
 | |
| use Utils;
 | |
| use Auth;
 | |
| use Exception;
 | |
| use App\Models\Account;
 | |
| use App\Models\Client;
 | |
| use App\Models\Activity;
 | |
| use App\Ninja\Repositories\PaymentRepository;
 | |
| use App\Ninja\Repositories\AccountRepository;
 | |
| use App\Ninja\Datatables\PaymentDatatable;
 | |
| 
 | |
| class PaymentService extends BaseService
 | |
| {
 | |
|     /**
 | |
|      * PaymentService constructor.
 | |
|      *
 | |
|      * @param PaymentRepository $paymentRepo
 | |
|      * @param AccountRepository $accountRepo
 | |
|      * @param DatatableService $datatableService
 | |
|      */
 | |
|     public function __construct(
 | |
|         PaymentRepository $paymentRepo,
 | |
|         AccountRepository $accountRepo,
 | |
|         DatatableService $datatableService
 | |
|     )
 | |
|     {
 | |
|         $this->datatableService = $datatableService;
 | |
|         $this->paymentRepo = $paymentRepo;
 | |
|         $this->accountRepo = $accountRepo;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @return PaymentRepository
 | |
|      */
 | |
|     protected function getRepo()
 | |
|     {
 | |
|         return $this->paymentRepo;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @param Invoice $invoice
 | |
|      * @return bool
 | |
|      */
 | |
|     public function autoBillInvoice(Invoice $invoice)
 | |
|     {
 | |
|         /** @var \App\Models\Client $client */
 | |
|         $client = $invoice->client;
 | |
| 
 | |
|         /** @var \App\Models\Account $account */
 | |
|         $account = $client->account;
 | |
| 
 | |
|         /** @var \App\Models\Invitation $invitation */
 | |
|         $invitation = $invoice->invitations->first();
 | |
| 
 | |
|         if ( ! $invitation) {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         if ($credits = $client->credits->sum('balance')) {
 | |
|             $balance = $invoice->balance;
 | |
|             $amount = min($credits, $balance);
 | |
|             $data = [
 | |
|                 'payment_type_id' => PAYMENT_TYPE_CREDIT,
 | |
|                 'invoice_id' => $invoice->id,
 | |
|                 'client_id' => $client->id,
 | |
|                 'amount' => $amount,
 | |
|             ];
 | |
|             $payment = $this->paymentRepo->save($data);
 | |
|             if ($amount == $balance) {
 | |
|                 return $payment;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         $paymentDriver = $account->paymentDriver($invitation, GATEWAY_TYPE_TOKEN);
 | |
| 
 | |
|         if ( ! $paymentDriver) {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         $customer = $paymentDriver->customer();
 | |
| 
 | |
|         if ( ! $customer) {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         $paymentMethod = $customer->default_payment_method;
 | |
| 
 | |
|         if ($paymentMethod->requiresDelayedAutoBill()) {
 | |
|             $invoiceDate = \DateTime::createFromFormat('Y-m-d', $invoice->invoice_date);
 | |
|             $minDueDate = clone $invoiceDate;
 | |
|             $minDueDate->modify('+10 days');
 | |
| 
 | |
|             if (date_create() < $minDueDate) {
 | |
|                 // Can't auto bill now
 | |
|                 return false;
 | |
|             }
 | |
| 
 | |
|             if ($invoice->partial > 0) {
 | |
|                 // The amount would be different than the amount in the email
 | |
|                 return false;
 | |
|             }
 | |
| 
 | |
|             $firstUpdate = Activity::where('invoice_id', '=', $invoice->id)
 | |
|                 ->where('activity_type_id', '=', ACTIVITY_TYPE_UPDATE_INVOICE)
 | |
|                 ->first();
 | |
| 
 | |
|             if ($firstUpdate) {
 | |
|                 $backup = json_decode($firstUpdate->json_backup);
 | |
| 
 | |
|                 if ($backup->balance != $invoice->balance || $backup->due_date != $invoice->due_date) {
 | |
|                     // It's changed since we sent the email can't bill now
 | |
|                     return false;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if ($invoice->payments->count()) {
 | |
|                 // ACH requirements are strict; don't auto bill this
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         try {
 | |
|             return $paymentDriver->completeOnsitePurchase(false, $paymentMethod);
 | |
|         } catch (Exception $exception) {
 | |
|             return false;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public function getDatatable($clientPublicId, $search)
 | |
|     {
 | |
|         $datatable = new PaymentDatatable(true, $clientPublicId);
 | |
|         $query = $this->paymentRepo->find($clientPublicId, $search);
 | |
| 
 | |
|         if(!Utils::hasPermission('view_all')){
 | |
|             $query->where('payments.user_id', '=', Auth::user()->id);
 | |
|         }
 | |
| 
 | |
|         return $this->datatableService->createDatatable($datatable, $query);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function bulk($ids, $action, $params = [])
 | |
|     {
 | |
|         if ($action == 'refund') {
 | |
|             if ( ! $ids ) {
 | |
|                 return 0;
 | |
|             }
 | |
| 
 | |
|             $payments = $this->getRepo()->findByPublicIdsWithTrashed($ids);
 | |
|             $successful = 0;
 | |
| 
 | |
|             foreach ($payments as $payment) {
 | |
|                 if (Auth::user()->can('edit', $payment)) {
 | |
|                     $amount = !empty($params['amount']) ? floatval($params['amount']) : null;
 | |
|                     if ($accountGateway = $payment->account_gateway) {
 | |
|                         $paymentDriver = $accountGateway->paymentDriver();
 | |
|                         if ($paymentDriver->refundPayment($payment, $amount)) {
 | |
|                             $successful++;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return $successful;
 | |
|         } else {
 | |
|             return parent::bulk($ids, $action);
 | |
|         }
 | |
|     }
 | |
| }
 |