2020-06-28 00:24:08 +02:00
< ? php
2020-07-01 03:06:40 +02:00
/**
2020-09-06 11:38:10 +02:00
* Invoice Ninja ( https :// invoiceninja . com ) .
2020-07-01 03:06:40 +02:00
*
* @ link https :// github . com / invoiceninja / invoiceninja source repository
*
2023-01-28 23:21:40 +01:00
* @ copyright Copyright ( c ) 2023. Invoice Ninja LLC ( https :// invoiceninja . com )
2020-07-01 03:06:40 +02:00
*
2021-06-16 08:58:16 +02:00
* @ license https :// www . elastic . co / licensing / elastic - license
2020-07-01 03:06:40 +02:00
*/
2020-06-28 00:24:08 +02:00
namespace App\Services\Payment ;
2023-10-26 04:57:44 +02:00
use App\Models\BankTransaction ;
2020-06-28 00:24:08 +02:00
use App\Models\Credit ;
use App\Models\Invoice ;
use App\Models\Payment ;
2022-12-14 06:17:43 +01:00
use Illuminate\Contracts\Container\BindingResolutionException ;
2020-06-28 00:24:08 +02:00
class DeletePayment
{
2022-12-14 06:17:43 +01:00
private float $_paid_to_date_deleted = 0 ;
2020-06-28 00:24:08 +02:00
2022-12-14 06:17:43 +01:00
/**
2023-07-26 05:19:13 +02:00
* @ param Payment $payment
2023-02-16 02:36:09 +01:00
* @ return void
2022-12-14 06:17:43 +01:00
*/
2023-02-16 02:36:09 +01:00
public function __construct ( public Payment $payment , private bool $update_client_paid_to_date )
{
}
2020-06-28 00:24:08 +02:00
2022-12-14 06:17:43 +01:00
/**
2023-07-26 05:19:13 +02:00
* @ return Payment
2023-02-16 02:36:09 +01:00
* @ throws BindingResolutionException
2022-12-14 06:17:43 +01:00
*/
2020-06-28 00:24:08 +02:00
public function run ()
{
2022-12-14 06:17:43 +01:00
\DB :: connection ( config ( 'database.default' )) -> transaction ( function () {
2022-10-05 02:21:55 +02:00
$this -> payment = Payment :: withTrashed () -> where ( 'id' , $this -> payment -> id ) -> lockForUpdate () -> first ();
2023-01-15 04:59:42 +01:00
if ( $this -> payment && ! $this -> payment -> is_deleted ) {
2023-01-14 06:22:26 +01:00
$this -> setStatus ( Payment :: STATUS_CANCELLED ) //sets status of payment
-> updateCreditables () //return the credits first
-> adjustInvoices ()
-> deletePaymentables ()
-> cleanupPayment ()
-> save ();
}
2023-01-18 06:52:32 +01:00
}, 2 );
2022-10-05 02:21:55 +02:00
return $this -> payment ;
2020-06-28 00:24:08 +02:00
}
2022-12-14 06:17:43 +01:00
/** @return $this */
2020-11-23 13:55:04 +01:00
private function cleanupPayment ()
{
2023-07-31 10:22:34 +02:00
2020-11-23 13:55:04 +01:00
$this -> payment -> is_deleted = true ;
$this -> payment -> delete ();
2022-06-21 11:57:17 +02:00
2023-10-26 04:57:44 +02:00
BankTransaction :: query () -> where ( 'payment_id' , $this -> payment -> id ) -> cursor () -> each ( function ( $bt ) {
2023-07-31 10:22:34 +02:00
$bt -> payment_id = null ;
2023-08-29 05:40:35 +02:00
$bt -> status_id = 1 ;
2023-07-31 10:22:34 +02:00
$bt -> save ();
});
2023-07-27 03:14:59 +02:00
2020-11-23 13:55:04 +01:00
return $this ;
}
2022-12-14 06:17:43 +01:00
/** @return $this */
2020-11-15 22:23:20 +01:00
private function deletePaymentables ()
{
$this -> payment -> paymentables () -> update ([ 'deleted_at' => now ()]);
return $this ;
}
2022-12-14 06:17:43 +01:00
/** @return $this */
2020-06-28 05:05:58 +02:00
private function adjustInvoices ()
{
2022-12-14 06:17:43 +01:00
$this -> _paid_to_date_deleted = 0 ;
2020-09-06 11:38:10 +02:00
if ( $this -> payment -> invoices () -> exists ()) {
$this -> payment -> invoices () -> each ( function ( $paymentable_invoice ) {
2021-04-22 01:35:31 +02:00
$net_deletable = $paymentable_invoice -> pivot -> amount - $paymentable_invoice -> pivot -> refunded ;
2022-06-21 11:57:17 +02:00
2022-12-14 06:17:43 +01:00
$this -> _paid_to_date_deleted += $net_deletable ;
2023-03-11 02:26:56 +01:00
$paymentable_invoice = $paymentable_invoice -> fresh ();
2022-03-09 03:49:31 +01:00
2021-09-04 07:51:31 +02:00
nlog ( " net deletable amount - refunded = { $net_deletable } " );
2022-06-21 11:57:17 +02:00
if ( ! $paymentable_invoice -> is_deleted ) {
2022-03-14 10:52:38 +01:00
$paymentable_invoice -> restore ();
2021-09-06 03:04:00 +02:00
$paymentable_invoice -> service ()
-> updateBalance ( $net_deletable )
-> updatePaidToDate ( $net_deletable * - 1 )
-> save ();
2023-11-07 04:54:44 +01:00
// $paymentable_invoice->ledger()
// ->updateInvoiceBalance($net_deletable, "Adjusting invoice {$paymentable_invoice->number} due to deletion of Payment {$this->payment->number}")
// ->save();
2021-09-06 03:04:00 +02:00
$paymentable_invoice -> ledger ()
2023-11-07 04:54:44 +01:00
-> mutateInvoiceBalance ( $paymentable_invoice -> amount , " Adjusting invoice { $paymentable_invoice -> number } due to deletion of Payment { $this -> payment -> number } " );
2021-09-06 03:04:00 +02:00
2023-11-07 04:54:44 +01:00
//@todo refactor
2023-03-11 02:26:56 +01:00
$this -> payment
-> client
-> service ()
-> updateBalanceAndPaidToDate ( $net_deletable , $net_deletable *- 1 )
-> save ();
2021-09-06 03:04:00 +02:00
if ( $paymentable_invoice -> balance == $paymentable_invoice -> amount ) {
$paymentable_invoice -> service () -> setStatus ( Invoice :: STATUS_SENT ) -> save ();
2023-10-26 04:57:44 +02:00
} elseif ( $paymentable_invoice -> balance == 0 ) {
2023-10-20 07:40:53 +02:00
$paymentable_invoice -> service () -> setStatus ( Invoice :: STATUS_PAID ) -> save ();
2023-10-26 04:57:44 +02:00
} else {
2021-09-06 03:04:00 +02:00
$paymentable_invoice -> service () -> setStatus ( Invoice :: STATUS_PARTIAL ) -> save ();
}
2022-06-21 11:57:17 +02:00
} else {
2022-12-14 06:17:43 +01:00
$paymentable_invoice -> restore ();
2021-09-06 07:08:41 +02:00
$paymentable_invoice -> service ()
-> updatePaidToDate ( $net_deletable * - 1 )
2021-09-06 03:04:00 +02:00
-> save ();
2023-07-14 09:09:23 +02:00
$paymentable_invoice -> delete ();
2020-09-06 11:38:10 +02:00
}
2020-06-28 05:05:58 +02:00
});
}
2021-10-26 12:47:28 +02:00
2022-12-14 06:17:43 +01:00
//sometimes the payment is NOT created properly, this catches the payment and prevents the paid to date reducing inappropriately.
2023-02-16 02:36:09 +01:00
if ( $this -> update_client_paid_to_date ) {
2022-12-14 06:17:43 +01:00
$this -> payment
-> client
-> service ()
-> updatePaidToDate ( min ( 0 , ( $this -> payment -> amount - $this -> payment -> refunded - $this -> _paid_to_date_deleted ) * - 1 ))
-> save ();
}
2020-06-28 05:05:58 +02:00
return $this ;
}
2022-12-14 06:17:43 +01:00
/** @return $this */
2020-06-28 05:05:58 +02:00
private function updateCreditables ()
{
2020-09-06 11:38:10 +02:00
if ( $this -> payment -> credits () -> exists ()) {
2023-02-16 02:36:09 +01:00
$this -> payment -> credits () -> where ( 'is_deleted' , 0 ) -> each ( function ( $paymentable_credit ) {
2021-11-22 11:09:28 +01:00
$multiplier = 1 ;
2022-06-21 11:57:17 +02:00
if ( $paymentable_credit -> pivot -> amount < 0 ) {
2022-03-16 03:06:25 +01:00
$multiplier = - 1 ;
2022-06-21 11:57:17 +02:00
}
2021-11-22 11:09:28 +01:00
2021-01-24 07:44:14 +01:00
$paymentable_credit -> service ()
2022-06-21 11:57:17 +02:00
-> updateBalance ( $paymentable_credit -> pivot -> amount * $multiplier * - 1 )
-> updatePaidToDate ( $paymentable_credit -> pivot -> amount * $multiplier )
2021-01-24 07:44:14 +01:00
-> setStatus ( Credit :: STATUS_SENT )
-> save ();
2022-03-01 11:25:18 +01:00
2022-03-16 03:06:25 +01:00
$client = $this -> payment -> client -> fresh ();
$client
-> service ()
2022-08-22 02:44:36 +02:00
-> adjustCreditBalance ( $paymentable_credit -> pivot -> amount )
2022-03-16 03:06:25 +01:00
-> save ();
2020-06-28 05:05:58 +02:00
});
}
return $this ;
}
2022-12-14 06:17:43 +01:00
/**
2023-02-16 02:36:09 +01:00
* @ param mixed $status
* @ return $this
2022-12-14 06:17:43 +01:00
*/
2020-06-28 05:05:58 +02:00
private function setStatus ( $status )
{
2020-07-06 13:22:36 +02:00
$this -> payment -> status_id = Payment :: STATUS_CANCELLED ;
2020-06-28 05:05:58 +02:00
return $this ;
}
2020-09-06 11:38:10 +02:00
2020-06-28 00:24:08 +02:00
/**
2020-09-06 11:38:10 +02:00
* Saves the payment .
*
2020-06-28 00:24:08 +02:00
* @ return Payment $payment
*/
private function save ()
{
$this -> payment -> save ();
return $this -> payment ;
}
}