diff --git a/app/Events/PaymentWasRefunded.php b/app/Events/PaymentWasRefunded.php
new file mode 100644
index 000000000000..54eeeabc3259
--- /dev/null
+++ b/app/Events/PaymentWasRefunded.php
@@ -0,0 +1,25 @@
+payment = $payment;
+ $this->refundAmount = $refundAmount;
+ }
+
+}
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index 3f8917b65427..cf0e4508610e 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -182,14 +182,7 @@ class AccountController extends BaseController
if ($account->company->payment) {
$payment = $account->company->payment;
-
- $gateway = $this->paymentService->createGateway($payment->account_gateway);
- $refund = $gateway->refund(array(
- 'transactionReference' => $payment->transaction_reference,
- 'amount' => $payment->amount
- ));
- $refund->send();
- $payment->delete();
+ $this->paymentService->refund($payment);
Session::flash('message', trans('texts.plan_refunded'));
\Log::info("Refunded Plan Payment: {$account->name} - {$user->email}");
} else {
diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php
index 1f53b4a0bc54..f5ecc89f8e8e 100644
--- a/app/Http/Controllers/PaymentController.php
+++ b/app/Http/Controllers/PaymentController.php
@@ -57,6 +57,7 @@ class PaymentController extends BaseController
'method',
'payment_amount',
'payment_date',
+ 'status',
''
]),
));
@@ -630,11 +631,12 @@ class PaymentController extends BaseController
public function bulk()
{
$action = Input::get('action');
+ $amount = Input::get('amount');
$ids = Input::get('public_id') ? Input::get('public_id') : Input::get('ids');
- $count = $this->paymentService->bulk($ids, $action);
+ $count = $this->paymentService->bulk($ids, $action, array('amount'=>$amount));
if ($count > 0) {
- $message = Utils::pluralize($action.'d_payment', $count);
+ $message = Utils::pluralize($action=='refund'?'refunded_payment':$action.'d_payment', $count);
Session::flash('message', $message);
}
diff --git a/app/Http/Controllers/PublicClientController.php b/app/Http/Controllers/PublicClientController.php
index 32d6d53c3887..d756bd7eaaa0 100644
--- a/app/Http/Controllers/PublicClientController.php
+++ b/app/Http/Controllers/PublicClientController.php
@@ -252,6 +252,9 @@ class PublicClientController extends BaseController
'invoice' => trans('texts.invoice') . ' ' . $model->invoice,
'contact' => Utils::getClientDisplayName($model),
'payment' => trans('texts.payment') . ($model->payment ? ' ' . $model->payment : ''),
+ 'credit' => $model->payment_amount ? Utils::formatMoney($model->credit, $model->currency_id, $model->country_id) : '',
+ 'payment_amount' => $model->payment_amount ? Utils::formatMoney($model->payment_amount, $model->currency_id, $model->country_id) : null,
+ 'adjustment' => $model->adjustment ? Utils::formatMoney($model->adjustment, $model->currency_id, $model->country_id) : null,
];
return trans("texts.activity_{$model->activity_type_id}", $data);
@@ -321,7 +324,7 @@ class PublicClientController extends BaseController
'clientFontUrl' => $account->getFontsUrl(),
'entityType' => ENTITY_PAYMENT,
'title' => trans('texts.payments'),
- 'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date'])
+ 'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date', 'status'])
];
return response()->view('public_list', $data);
@@ -340,8 +343,36 @@ class PublicClientController extends BaseController
->addColumn('payment_type', function ($model) { return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? 'Online payment' : ''); })
->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); })
->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); })
+ ->addColumn('status', function ($model) { return $this->getPaymentStatusLabel($model); })
->make();
}
+
+ private function getPaymentStatusLabel($model)
+ {
+ $label = trans("texts.status_" . strtolower($model->payment_status_name));
+ $class = 'default';
+ switch ($model->payment_status_id) {
+ case PAYMENT_STATUS_PENDING:
+ $class = 'info';
+ break;
+ case PAYMENT_STATUS_COMPLETED:
+ $class = 'success';
+ break;
+ case PAYMENT_STATUS_FAILED:
+ $class = 'danger';
+ break;
+ case PAYMENT_STATUS_PARTIALLY_REFUNDED:
+ $label = trans('texts.status_partially_refunded_amount', [
+ 'amount' => Utils::formatMoney($model->refunded, $model->currency_id, $model->country_id),
+ ]);
+ $class = 'primary';
+ break;
+ case PAYMENT_STATUS_REFUNDED:
+ $class = 'default';
+ break;
+ }
+ return "
$label
";
+ }
public function quoteIndex()
{
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 48f06e5e7b3d..25041048f102 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -398,6 +398,7 @@ if (!defined('CONTACT_EMAIL')) {
//define('ACTIVITY_TYPE_UPDATE_PAYMENT', 11);
define('ACTIVITY_TYPE_ARCHIVE_PAYMENT', 12);
define('ACTIVITY_TYPE_DELETE_PAYMENT', 13);
+ define('ACTIVITY_TYPE_REFUNDED_PAYMENT', 39);
define('ACTIVITY_TYPE_CREATE_CREDIT', 14);
//define('ACTIVITY_TYPE_UPDATE_CREDIT', 15);
@@ -474,6 +475,12 @@ if (!defined('CONTACT_EMAIL')) {
define('INVOICE_STATUS_APPROVED', 4);
define('INVOICE_STATUS_PARTIAL', 5);
define('INVOICE_STATUS_PAID', 6);
+
+ define('PAYMENT_STATUS_PENDING', 1);
+ define('PAYMENT_STATUS_FAILED', 2);
+ define('PAYMENT_STATUS_COMPLETED', 3);
+ define('PAYMENT_STATUS_PARTIALLY_REFUNDED', 4);
+ define('PAYMENT_STATUS_REFUNDED', 5);
define('PAYMENT_TYPE_CREDIT', 1);
define('CUSTOM_DESIGN', 11);
diff --git a/app/Listeners/ActivityListener.php b/app/Listeners/ActivityListener.php
index 52c2e26f9027..811d1050b9cb 100644
--- a/app/Listeners/ActivityListener.php
+++ b/app/Listeners/ActivityListener.php
@@ -22,6 +22,7 @@ use App\Events\QuoteInvitationWasViewed;
use App\Events\QuoteInvitationWasApproved;
use App\Events\PaymentWasCreated;
use App\Events\PaymentWasDeleted;
+use App\Events\PaymentWasRefunded;
use App\Events\PaymentWasArchived;
use App\Events\PaymentWasRestored;
use App\Events\CreditWasCreated;
@@ -309,6 +310,18 @@ class ActivityListener
);
}
+ public function refundedPayment(PaymentWasRefunded $event)
+ {
+ $payment = $event->payment;
+
+ $this->activityRepo->create(
+ $payment,
+ ACTIVITY_TYPE_REFUNDED_PAYMENT,
+ $event->refundAmount,
+ $event->refundAmount * -1
+ );
+ }
+
public function archivedPayment(PaymentWasArchived $event)
{
if ($event->payment->is_deleted) {
diff --git a/app/Listeners/CreditListener.php b/app/Listeners/CreditListener.php
index bed71a47f59d..5c2ce2539d80 100644
--- a/app/Listeners/CreditListener.php
+++ b/app/Listeners/CreditListener.php
@@ -3,6 +3,7 @@
use Carbon;
use App\Models\Credit;
use App\Events\PaymentWasDeleted;
+use App\Events\PaymentWasRefunded;
use App\Ninja\Repositories\CreditRepository;
class CreditListener
@@ -26,7 +27,24 @@ class CreditListener
$credit = Credit::createNew();
$credit->client_id = $payment->client_id;
$credit->credit_date = Carbon::now()->toDateTimeString();
- $credit->balance = $credit->amount = $payment->amount;
+ $credit->balance = $credit->amount = $payment->amount - $payment->refunded;
+ $credit->private_notes = $payment->transaction_reference;
+ $credit->save();
+ }
+
+ public function refundedPayment(PaymentWasRefunded $event)
+ {
+ $payment = $event->payment;
+
+ // if the payment was from a credit we need to refund the credit
+ if ($payment->payment_type_id != PAYMENT_TYPE_CREDIT) {
+ return;
+ }
+
+ $credit = Credit::createNew();
+ $credit->client_id = $payment->client_id;
+ $credit->credit_date = Carbon::now()->toDateTimeString();
+ $credit->balance = $credit->amount = $event->refundAmount;
$credit->private_notes = $payment->transaction_reference;
$credit->save();
}
diff --git a/app/Listeners/InvoiceListener.php b/app/Listeners/InvoiceListener.php
index 91f3de8cc213..290a8f4a0426 100644
--- a/app/Listeners/InvoiceListener.php
+++ b/app/Listeners/InvoiceListener.php
@@ -7,6 +7,7 @@ use App\Events\InvoiceWasUpdated;
use App\Events\InvoiceWasCreated;
use App\Events\PaymentWasCreated;
use App\Events\PaymentWasDeleted;
+use App\Events\PaymentWasRefunded;
use App\Events\PaymentWasRestored;
use App\Events\InvoiceInvitationWasViewed;
@@ -58,7 +59,17 @@ class InvoiceListener
{
$payment = $event->payment;
$invoice = $payment->invoice;
- $adjustment = $payment->amount;
+ $adjustment = $payment->amount - $payment->refunded;
+
+ $invoice->updateBalances($adjustment);
+ $invoice->updatePaidStatus();
+ }
+
+ public function refundedPayment(PaymentWasRefunded $event)
+ {
+ $payment = $event->payment;
+ $invoice = $payment->invoice;
+ $adjustment = $event->refundAmount;
$invoice->updateBalances($adjustment);
$invoice->updatePaidStatus();
@@ -72,7 +83,7 @@ class InvoiceListener
$payment = $event->payment;
$invoice = $payment->invoice;
- $adjustment = $payment->amount * -1;
+ $adjustment = ($payment->amount - $payment->refunded) * -1;
$invoice->updateBalances($adjustment);
$invoice->updatePaidStatus();
diff --git a/app/Models/Activity.php b/app/Models/Activity.php
index 921c037d5f69..2fa9e6e8e349 100644
--- a/app/Models/Activity.php
+++ b/app/Models/Activity.php
@@ -70,6 +70,8 @@ class Activity extends Eloquent
'quote' => $invoice ? link_to($invoice->getRoute(), $invoice->getDisplayName()) : null,
'contact' => $contactId ? $client->getDisplayName() : $user->getDisplayName(),
'payment' => $payment ? $payment->transaction_reference : null,
+ 'payment_amount' => $payment ? $account->formatMoney($payment->amount, $payment) : null,
+ 'adjustment' => $this->adjustment ? $account->formatMoney($this->adjustment, $this) : asdf,
'credit' => $credit ? $account->formatMoney($credit->amount, $client) : null,
];
diff --git a/app/Models/Payment.php b/app/Models/Payment.php
index a2e8b2591fe3..22924cc61297 100644
--- a/app/Models/Payment.php
+++ b/app/Models/Payment.php
@@ -1,7 +1,9 @@
belongsTo('App\Models\PaymentType');
+ }
+
+ public function payment_status()
+ {
+ return $this->belongsTo('App\Models\PaymentStatus');
}
public function getRoute()
@@ -69,6 +76,51 @@ class Payment extends EntityModel
return trim("payment {$this->transaction_reference}");
}
+ public function isPending()
+ {
+ return $this->payment_status_id = PAYMENT_STATUS_PENDING;
+ }
+
+ public function isFailed()
+ {
+ return $this->payment_status_id = PAYMENT_STATUS_FAILED;
+ }
+
+ public function isCompleted()
+ {
+ return $this->payment_status_id >= PAYMENT_STATUS_COMPLETED;
+ }
+
+ public function isPartiallyRefunded()
+ {
+ return $this->payment_status_id == PAYMENT_STATUS_PARTIALLY_REFUNDED;
+ }
+
+ public function isRefunded()
+ {
+ return $this->payment_status_id == PAYMENT_STATUS_REFUNDED;
+ }
+
+ public function recordRefund($amount = null)
+ {
+ if (!$this->isRefunded()) {
+ if (!$amount) {
+ $amount = $this->amount;
+ }
+
+ $new_refund = min($this->amount, $this->refunded + $amount);
+ $refund_change = $new_refund - $this->refunded;
+
+ if ($refund_change) {
+ $this->refunded = $new_refund;
+ $this->payment_status_id = $this->refunded == $this->amount ? PAYMENT_STATUS_REFUNDED : PAYMENT_STATUS_PARTIALLY_REFUNDED;
+ $this->save();
+
+ Event::fire(new PaymentWasRefunded($this, $refund_change));
+ }
+ }
+ }
+
public function getEntityType()
{
return ENTITY_PAYMENT;
diff --git a/app/Models/PaymentStatus.php b/app/Models/PaymentStatus.php
new file mode 100644
index 000000000000..fdb1e0f43d5b
--- /dev/null
+++ b/app/Models/PaymentStatus.php
@@ -0,0 +1,8 @@
+join('clients', 'clients.id', '=', 'payments.client_id')
->join('invoices', 'invoices.id', '=', 'payments.invoice_id')
->join('contacts', 'contacts.client_id', '=', 'clients.id')
+ ->join('payment_statuses', 'payment_statuses.id', '=', 'payments.payment_status_id')
->leftJoin('payment_types', 'payment_types.id', '=', 'payments.payment_type_id')
->leftJoin('account_gateways', 'account_gateways.id', '=', 'payments.account_gateway_id')
->leftJoin('gateways', 'gateways.id', '=', 'account_gateways.gateway_id')
@@ -39,6 +40,8 @@ class PaymentRepository extends BaseRepository
'clients.user_id as client_user_id',
'payments.amount',
'payments.payment_date',
+ 'payments.payment_status_id',
+ 'payments.payment_type_id',
'invoices.public_id as invoice_public_id',
'invoices.user_id as invoice_user_id',
'invoices.invoice_number',
@@ -50,8 +53,11 @@ class PaymentRepository extends BaseRepository
'payments.deleted_at',
'payments.is_deleted',
'payments.user_id',
+ 'payments.refunded',
'invoices.is_deleted as invoice_is_deleted',
- 'gateways.name as gateway_name'
+ 'gateways.name as gateway_name',
+ 'gateways.id as gateway_id',
+ 'payment_statuses.name as payment_status_name'
);
if (!\Session::get('show_trash:payment')) {
@@ -78,6 +84,7 @@ class PaymentRepository extends BaseRepository
->join('clients', 'clients.id', '=', 'payments.client_id')
->join('invoices', 'invoices.id', '=', 'payments.invoice_id')
->join('contacts', 'contacts.client_id', '=', 'clients.id')
+ ->join('payment_statuses', 'payment_statuses.id', '=', 'payments.payment_status_id')
->leftJoin('invitations', function ($join) {
$join->on('invitations.invoice_id', '=', 'invoices.id')
->on('invitations.contact_id', '=', 'contacts.id');
@@ -104,7 +111,10 @@ class PaymentRepository extends BaseRepository
'contacts.last_name',
'contacts.email',
'payment_types.name as payment_type',
- 'payments.account_gateway_id'
+ 'payments.account_gateway_id',
+ 'payments.refunded',
+ 'payments.payment_status_id',
+ 'payment_statuses.name as payment_status_name'
);
if ($filter) {
@@ -189,6 +199,4 @@ class PaymentRepository extends BaseRepository
parent::restore($payment);
}
-
-
}
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index bb4e94d79546..3ce5fcfa29e0 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -107,6 +107,11 @@ class EventServiceProvider extends ServiceProvider {
'App\Listeners\InvoiceListener@deletedPayment',
'App\Listeners\CreditListener@deletedPayment',
],
+ 'App\Events\PaymentWasRefunded' => [
+ 'App\Listeners\ActivityListener@refundedPayment',
+ 'App\Listeners\InvoiceListener@refundedPayment',
+ 'App\Listeners\CreditListener@refundedPayment',
+ ],
'App\Events\PaymentWasRestored' => [
'App\Listeners\ActivityListener@restoredPayment',
'App\Listeners\InvoiceListener@restoredPayment',
diff --git a/app/Services/ActivityService.php b/app/Services/ActivityService.php
index d3b08b997189..6f6ef4b35956 100644
--- a/app/Services/ActivityService.php
+++ b/app/Services/ActivityService.php
@@ -44,7 +44,9 @@ class ActivityService extends BaseService
'quote' => $model->invoice ? link_to('/quotes/' . $model->invoice_public_id, $model->invoice)->toHtml() : null,
'contact' => $model->contact_id ? link_to('/clients/' . $model->client_public_id, Utils::getClientDisplayName($model))->toHtml() : Utils::getPersonDisplayName($model->user_first_name, $model->user_last_name, $model->user_email),
'payment' => $model->payment ?: '',
- 'credit' => Utils::formatMoney($model->credit, $model->currency_id, $model->country_id)
+ 'credit' => $model->payment_amount ? Utils::formatMoney($model->credit, $model->currency_id, $model->country_id) : '',
+ 'payment_amount' => $model->payment_amount ? Utils::formatMoney($model->payment_amount, $model->currency_id, $model->country_id) : null,
+ 'adjustment' => $model->adjustment ? Utils::formatMoney($model->adjustment, $model->currency_id, $model->country_id) : null
];
return trans("texts.activity_{$model->activity_type_id}", $data);
diff --git a/app/Services/PaymentService.php b/app/Services/PaymentService.php
index 61af6cd2336c..8e24370bd930 100644
--- a/app/Services/PaymentService.php
+++ b/app/Services/PaymentService.php
@@ -23,6 +23,10 @@ class PaymentService extends BaseService
{
public $lastError;
protected $datatableService;
+
+ protected static $refundableGateways = array(
+ GATEWAY_STRIPE
+ );
public function __construct(PaymentRepository $paymentRepo, AccountRepository $accountRepo, DatatableService $datatableService)
{
@@ -375,6 +379,12 @@ class PaymentService extends BaseService
function ($model) {
return Utils::dateToString($model->payment_date);
}
+ ],
+ [
+ 'payment_status_name',
+ function ($model) use ($entityType) {
+ return self::getStatusLabel($entityType, $model);
+ }
]
];
}
@@ -390,9 +400,103 @@ class PaymentService extends BaseService
function ($model) {
return Payment::canEditItem($model);
}
+ ],
+ [
+ trans('texts.refund_payment'),
+ function ($model) {
+ $max_refund = number_format($model->amount - $model->refunded, 2);
+ $formatted = Utils::formatMoney($max_refund, $model->currency_id, $model->country_id);
+ $symbol = Utils::getFromCache($model->currency_id, 'currencies')->symbol;
+ return "javascript:showRefundModal({$model->public_id}, '{$max_refund}', '{$formatted}', '{$symbol}')";
+ },
+ function ($model) {
+ return Payment::canEditItem($model) && (
+ ($model->transaction_reference && in_array($model->gateway_id , static::$refundableGateways))
+ || $model->payment_type_id == PAYMENT_TYPE_CREDIT
+ );
+ }
]
];
}
+
+ public function bulk($ids, $action, $params = array())
+ {
+ if ($action == 'refund') {
+ if ( ! $ids ) {
+ return 0;
+ }
+ $payments = $this->getRepo()->findByPublicIdsWithTrashed($ids);
+ foreach ($payments as $payment) {
+ if($payment->canEdit()){
+ if(!empty($params['amount'])) {
+ $this->refund($payment, floatval($params['amount']));
+ } else {
+ $this->refund($payment);
+ }
+ }
+ }
+
+ return count($payments);
+ } else {
+ return parent::bulk($ids, $action);
+ }
+ }
+
+ private function getStatusLabel($entityType, $model)
+ {
+ $label = trans("texts.status_" . strtolower($model->payment_status_name));
+ $class = 'default';
+ switch ($model->payment_status_id) {
+ case PAYMENT_STATUS_PENDING:
+ $class = 'info';
+ break;
+ case PAYMENT_STATUS_COMPLETED:
+ $class = 'success';
+ break;
+ case PAYMENT_STATUS_FAILED:
+ $class = 'danger';
+ break;
+ case PAYMENT_STATUS_PARTIALLY_REFUNDED:
+ $label = trans('texts.status_partially_refunded_amount', [
+ 'amount' => Utils::formatMoney($model->refunded, $model->currency_id, $model->country_id),
+ ]);
+ $class = 'primary';
+ break;
+ case PAYMENT_STATUS_REFUNDED:
+ $class = 'default';
+ break;
+ }
+ return "$label
";
+ }
+
+ public function refund($payment, $amount = null) {
+ if (!$amount) {
+ $amount = $payment->amount;
+ }
+
+ $amount = min($amount, $payment->amount - $payment->refunded);
+
+ if (!$amount) {
+ return;
+ }
+
+ if ($payment->payment_type_id != PAYMENT_TYPE_CREDIT) {
+ $accountGateway = $this->createGateway($payment->account_gateway);
+ $refund = $accountGateway->refund(array(
+ 'transactionReference' => $payment->transaction_reference,
+ 'amount' => $amount,
+ ));
+ $response = $refund->send();
+
+ if ($response->isSuccessful()) {
+ $payment->recordRefund($amount);
+ } else {
+ $this->error('Unknown', $response->getMessage(), $accountGateway);
+ }
+ } else {
+ $payment->recordRefund($amount);
+ }
+ }
}
diff --git a/database/migrations/2016_04_23_182223_payments_changes.php b/database/migrations/2016_04_23_182223_payments_changes.php
new file mode 100644
index 000000000000..641ec06e2c2d
--- /dev/null
+++ b/database/migrations/2016_04_23_182223_payments_changes.php
@@ -0,0 +1,49 @@
+increments('id');
+ $table->string('name');
+ });
+
+ (new \PaymentStatusSeeder())->run();
+
+ Schema::table('payments', function($table)
+ {
+ $table->decimal('refunded', 13, 2);
+ $table->unsignedInteger('payment_status_id')->default(3);
+ $table->foreign('payment_status_id')->references('id')->on('payment_statuses');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('payments', function($table)
+ {
+ $table->dropColumn('refunded');
+ $table->dropForeign('payments_payment_status_id_foreign');
+ $table->dropColumn('payment_status_id');
+ });
+
+ Schema::dropIfExists('payment_statuses');
+ }
+}
diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php
index 8791f30e71fb..753a1ce54e30 100644
--- a/database/seeds/DatabaseSeeder.php
+++ b/database/seeds/DatabaseSeeder.php
@@ -19,6 +19,7 @@ class DatabaseSeeder extends Seeder
$this->call('FontsSeeder');
$this->call('BanksSeeder');
$this->call('InvoiceStatusSeeder');
+ $this->call('PaymentStatusSeeder');
$this->call('CurrenciesSeeder');
$this->call('DateFormatsSeeder');
$this->call('InvoiceDesignsSeeder');
diff --git a/database/seeds/PaymentStatusSeeder.php b/database/seeds/PaymentStatusSeeder.php
new file mode 100644
index 000000000000..8e93d57798fd
--- /dev/null
+++ b/database/seeds/PaymentStatusSeeder.php
@@ -0,0 +1,36 @@
+createPaymentStatuses();
+
+ Eloquent::reguard();
+ }
+
+ private function createPaymentStatuses()
+ {
+ $statuses = [
+ ['id' => '1', 'name' => 'Pending'],
+ ['id' => '2', 'name' => 'Failed'],
+ ['id' => '3', 'name' => 'Completed'],
+ ['id' => '4', 'name' => 'Partially Refunded'],
+ ['id' => '5', 'name' => 'Refunded'],
+ ];
+
+ foreach ($statuses as $status) {
+ $record = PaymentStatus::find($status['id']);
+ if ($record) {
+ $record->name = $status['name'];
+ $record->save();
+ } else {
+ PaymentStatus::create($status);
+ }
+ }
+ }
+}
diff --git a/database/seeds/UpdateSeeder.php b/database/seeds/UpdateSeeder.php
index e4d43f78e512..e5335e311b42 100644
--- a/database/seeds/UpdateSeeder.php
+++ b/database/seeds/UpdateSeeder.php
@@ -15,6 +15,7 @@ class UpdateSeeder extends Seeder
$this->call('FontsSeeder');
$this->call('BanksSeeder');
$this->call('InvoiceStatusSeeder');
+ $this->call('PaymentStatusSeeder');
$this->call('CurrenciesSeeder');
$this->call('DateFormatsSeeder');
$this->call('InvoiceDesignsSeeder');
diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php
index 37478c5d73e3..ae717b297b23 100644
--- a/resources/lang/en/texts.php
+++ b/resources/lang/en/texts.php
@@ -1176,6 +1176,20 @@ $LANG = array(
'page_size' => 'Page Size',
'live_preview_disabled' => 'Live preview has been disabled to support selected font',
'invoice_number_padding' => 'Padding',
+
+ // Payment updates
+ 'refund_payment' => 'Refund Payment',
+ 'refund_max' => 'Max:',
+ 'refund' => 'Refund',
+ 'are_you_sure_refund' => 'Refund selected payments?',
+ 'status_pending' => 'Pending',
+ 'status_completed' => 'Completed',
+ 'status_failed' => 'Failed',
+ 'status_partially_refunded' => 'Partially Refunded',
+ 'status_partially_refunded_amount' => ':amount Refunded',
+ 'status_refunded' => 'Refunded',
+ 'refunded_payment' => 'Refunded Payment',
+ 'activity_39' => ':user refunded :adjustment of a :payment_amount payment (:payment)',
);
diff --git a/resources/views/list.blade.php b/resources/views/list.blade.php
index 8e8ba97116d7..07db6b5e6b91 100644
--- a/resources/views/list.blade.php
+++ b/resources/views/list.blade.php
@@ -53,7 +53,41 @@
->setOptions('sPaginationType', 'bootstrap')
->setOptions('aaSorting', [[isset($sortCol) ? $sortCol : '1', 'desc']])
->render('datatable') !!}
-
+
+ @if ($entityType == ENTITY_PAYMENT)
+
+ @endif
+
{!! Former::close() !!}