Merge pull request #3871 from turbo124/v2

Allow NPM/NODE paths to be configurable
This commit is contained in:
David Bomba 2020-07-01 08:30:43 +10:00 committed by GitHub
commit 0d92d1675a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 346 deletions

View File

@ -30,7 +30,7 @@ Please Note: Your APP_KEY in the .env file is used to encrypt data, if you lose
Run if you want to load sample data, remember to configure .env Run if you want to load sample data, remember to configure .env
``` ```
php artisan migrate:fresh --seed && php artisan db:seed --class=RandomDataSeeder php artisan migrate:fresh --seed && php artisan db:seed && php artisan ninja:create-test-data
``` ```
To Run the web server To Run the web server
@ -42,6 +42,10 @@ Navigate to (replace ninja.test as required)
``` ```
http://ninja.test:8000/setup - To setup your configuration if you didn't load sample data. http://ninja.test:8000/setup - To setup your configuration if you didn't load sample data.
http://ninja.test:8000/ - For Administrator Logon http://ninja.test:8000/ - For Administrator Logon
user: small@example.com
pass: password
http://ninja.test:8000/client/login - For Client Portal http://ninja.test:8000/client/login - For Client Portal
user: user@example.com user: user@example.com

View File

@ -304,7 +304,7 @@ class CheckData extends Command
if($ledger && number_format($invoice_balance, 4) != number_format($client->balance, 4)) if($ledger && number_format($invoice_balance, 4) != number_format($client->balance, 4))
{ {
$wrong_balances++; $wrong_balances++;
$this->logMessage($client->present()->name . " - " . $client->id . " - balances do not match {$invoice_balance} - {$client->balance} - {$ledger->balance}"); $this->logMessage($client->present()->name . " - " . $client->id . " - balances do not match Invoice Balance = {$invoice_balance} Client Balance = {$client->balance} Ledger Balance = {$ledger->balance}");
$this->isValid = false; $this->isValid = false;

View File

@ -11,7 +11,9 @@
namespace App\Repositories; namespace App\Repositories;
use App\Events\Credit\CreditWasUpdated;
use App\Events\Invoice\InvoiceWasUpdated; use App\Events\Invoice\InvoiceWasUpdated;
use App\Events\Quote\QuoteWasUpdated;
use App\Factory\InvoiceInvitationFactory; use App\Factory\InvoiceInvitationFactory;
use App\Factory\QuoteInvitationFactory; use App\Factory\QuoteInvitationFactory;
use App\Jobs\Product\UpdateOrCreateProduct; use App\Jobs\Product\UpdateOrCreateProduct;
@ -73,8 +75,6 @@ class BaseRepository
$entity->delete(); $entity->delete();
info("archived");
$className = $this->getEventClass($entity, 'Archived'); $className = $this->getEventClass($entity, 'Archived');
if (class_exists($className)) { if (class_exists($className)) {
@ -192,10 +192,6 @@ class BaseRepository
*/ */
protected function alternativeSave($data, $model) protected function alternativeSave($data, $model)
{ {
$new_entity = false;
if(!$model->id)
$new_entity = true;
$class = new ReflectionClass($model); $class = new ReflectionClass($model);
@ -234,9 +230,6 @@ class BaseRepository
$model->fill($tmp_data); $model->fill($tmp_data);
$model->save(); $model->save();
if($new_entity)
$this->newEntityEvent($model);
if (array_key_exists('documents', $data)) { if (array_key_exists('documents', $data)) {
$this->saveDocuments($data['documents'], $model); $this->saveDocuments($data['documents'], $model);
} }
@ -291,9 +284,8 @@ class BaseRepository
} }
$model = $model->calc()->getInvoice(); $model = $model->calc()->getInvoice();
$state['finished_amount'] = $model->amount;
info("finished amount = {$model->amount}"); $state['finished_amount'] = $model->amount;
$model = $model->service()->applyNumber()->save(); $model = $model->service()->applyNumber()->save();
@ -302,8 +294,9 @@ class BaseRepository
} }
if ($class->name == Invoice::class) { if ($class->name == Invoice::class) {
if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) { if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) {
info("inside ledger updating");
$model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount'])); $model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount']));
$model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save(); $model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save();
} }
@ -311,8 +304,6 @@ class BaseRepository
if(!$model->design_id) if(!$model->design_id)
$model->design_id = $this->decodePrimaryKey($client->getSetting('invoice_design_id')); $model->design_id = $this->decodePrimaryKey($client->getSetting('invoice_design_id'));
event(new InvoiceWasUpdated($model, $model->company));
} }
if ($class->name == Credit::class) { if ($class->name == Credit::class) {
@ -320,6 +311,8 @@ class BaseRepository
if(!$model->design_id) if(!$model->design_id)
$model->design_id = $this->decodePrimaryKey($client->getSetting('credit_design_id')); $model->design_id = $this->decodePrimaryKey($client->getSetting('credit_design_id'));
} }
if ($class->name == Quote::class) { if ($class->name == Quote::class) {
@ -327,6 +320,9 @@ class BaseRepository
if(!$model->design_id) if(!$model->design_id)
$model->design_id = $this->decodePrimaryKey($client->getSetting('quote_design_id')); $model->design_id = $this->decodePrimaryKey($client->getSetting('quote_design_id'));
} }
$model->save(); $model->save();
@ -334,15 +330,4 @@ class BaseRepository
return $model->fresh(); return $model->fresh();
} }
public function newEntityEvent($model)
{
$className = $this->getEventClass($model, 'Created');
if (class_exists($className)) {
event(new $className($model, $model->company));
}
}
} }

View File

@ -1,302 +0,0 @@
<?php
namespace App\Services\Payment;
use App\Exceptions\PaymentRefundFailed;
use App\Factory\CreditFactory;
use App\Factory\InvoiceItemFactory;
use App\Models\Activity;
use App\Models\CompanyGateway;
use App\Models\Credit;
use App\Models\Invoice;
use App\Models\Payment;
use App\Repositories\ActivityRepository;
class RefundPayment
{
public $payment;
public $refund_data;
private $credit_note;
private $total_refund;
private $gateway_refund_status;
private $activity_repository;
public function __construct($payment, $refund_data)
{
$this->payment = $payment;
$this->refund_data = $refund_data;
$this->total_refund = 0;
$this->gateway_refund_status = false;
$this->activity_repository = new ActivityRepository();
}
public function run()
{
return $this->calculateTotalRefund() //sets amount for the refund (needed if we are refunding multiple invoices in one payment)
->setStatus() //sets status of payment
->buildCreditNote() //generate the credit note
->buildCreditLineItems() //generate the credit note items
->updateCreditables() //return the credits first
->updatePaymentables() //update the paymentable items
->adjustInvoices()
->processGatewayRefund() //process the gateway refund if needed
->save();
}
private function processGatewayRefund()
{
if ($this->refund_data['gateway_refund'] !== false && $this->total_refund > 0) {
$gateway = CompanyGateway::first();
if ($gateway) {
$response = $gateway->driver($this->payment->client)->refund($this->payment, $this->total_refund);
if ($response['success']) {
throw new PaymentRefundFailed();
}
$this->payment->refunded = $this->total_refund;
$this
->createActivity($gateway)
->updateCreditNoteBalance();
}
} else {
$this->payment->refunded += $this->total_refund;
}
return $this;
}
public function updateCreditNoteBalance()
{
$this->credit_note->balance -= $this->total_refund;
$this->credit_note->status_id = Credit::STATUS_APPLIED;
$this->credit_note->balance === 0
? $this->credit_note->status_id = Credit::STATUS_APPLIED
: $this->credit_note->status_id = Credit::STATUS_PARTIAL;
$this->credit_note->save();
return $this;
}
private function createActivity($notes)
{
$fields = new \stdClass;
$activity_repo = new ActivityRepository();
$fields->payment_id = $this->payment->id;
$fields->user_id = $this->payment->user_id;
$fields->company_id = $this->payment->company_id;
$fields->activity_type_id = Activity::REFUNDED_PAYMENT;
$fields->credit_id = $this->credit_note->id;
$fields->notes = json_encode($notes);
if (isset($this->refund_data['invoices'])) {
foreach ($this->refund_data['invoices'] as $invoice) {
$fields->invoice_id = $invoice['invoice_id'];
$activity_repo->save($fields, $this->payment);
}
} else {
$activity_repo->save($fields, $this->payment);
}
return $this;
}
private function calculateTotalRefund()
{
if (array_key_exists('invoices', $this->refund_data) && count($this->refund_data['invoices']) > 0){
info("array of invoice to refund");
$this->total_refund = collect($this->refund_data['invoices'])->sum('amount');
}
else{
info("no invoices found - refunding total.");
$this->total_refund = $this->refund_data['amount'];
}
return $this;
}
private function setStatus()
{
if ($this->refund_data['amount'] == $this->payment->amount) {
$this->payment->status_id = Payment::STATUS_REFUNDED;
} else {
$this->payment->status_id = Payment::STATUS_PARTIALLY_REFUNDED;
}
return $this;
}
private function buildCreditNote()
{
$this->credit_note = CreditFactory::create($this->payment->company_id, $this->payment->user_id);
$this->credit_note->assigned_user_id = isset($this->payment->assigned_user_id) ?: null;
$this->credit_note->date = $this->refund_data['date'];
$this->credit_note->status_id = Credit::STATUS_SENT;
$this->credit_note->client_id = $this->payment->client->id;
$this->credit_note->amount = $this->total_refund;
$this->credit_note->balance = $this->total_refund;
$this->credit_note->save();
$this->credit_note->number = $this->payment->client->getNextCreditNumber($this->payment->client);
$this->credit_note->save();
return $this;
}
private function buildCreditLineItems()
{
$ledger_string = '';
if (isset($this->refund_data['invoices']) && count($this->refund_data['invoices']) > 0) {
foreach ($this->refund_data['invoices'] as $invoice) {
$inv = Invoice::find($invoice['invoice_id']);
$credit_line_item = InvoiceItemFactory::create();
$credit_line_item->quantity = 1;
$credit_line_item->cost = $invoice['amount'];
$credit_line_item->product_key = ctrans('texts.invoice');
$credit_line_item->notes = ctrans('texts.refund_body', ['amount' => $invoice['amount'], 'invoice_number' => $inv->number]);
$credit_line_item->line_total = $invoice['amount'];
$credit_line_item->date = $this->refund_data['date'];
$ledger_string .= $credit_line_item->notes . ' ';
$line_items[] = $credit_line_item;
}
} else {
$credit_line_item = InvoiceItemFactory::create();
$credit_line_item->quantity = 1;
$credit_line_item->cost = $this->refund_data['amount'];
$credit_line_item->product_key = ctrans('texts.credit');
$credit_line_item->notes = ctrans('texts.credit_created_by', ['transaction_reference' => $this->payment->number]);
$credit_line_item->line_total = $this->refund_data['amount'];
$credit_line_item->date = $this->refund_data['date'];
$line_items = [];
$line_items[] = $credit_line_item;
}
$this->credit_note->line_items = $line_items;
$this->credit_note->save();
return $this;
}
private function updatePaymentables()
{
if (isset($this->refund_data['invoices']) && count($this->refund_data['invoices']) > 0) {
$this->payment->invoices->each(function ($paymentable_invoice) {
collect($this->refund_data['invoices'])->each(function ($refunded_invoice) use ($paymentable_invoice) {
if ($refunded_invoice['invoice_id'] == $paymentable_invoice->id) {
$paymentable_invoice->pivot->refunded += $refunded_invoice['amount'];
$paymentable_invoice->pivot->save();
}
});
});
}
return $this;
}
private function updateCreditables()
{
if ($this->payment->credits()->exists()) {
//Adjust credits first!!!
foreach ($this->payment->credits as $paymentable_credit) {
$available_credit = $paymentable_credit->pivot->amount - $paymentable_credit->pivot->refunded;
if ($available_credit > $this->total_refund) {
$paymentable_credit->pivot->refunded += $this->total_refund;
$paymentable_credit->pivot->save();
$paymentable_credit->balance += $this->total_refund;
$paymentable_credit->save();
$this->total_refund = 0;
} else {
$paymentable_credit->pivot->refunded += $available_credit;
$paymentable_credit->pivot->save();
$paymentable_credit->balance += $available_credit;
$paymentable_credit->save();
$this->total_refund -= $available_credit;
}
if ($this->total_refund == 0) {
break;
}
}
}
return $this;
}
private function adjustInvoices()
{
$adjustment_amount = 0;
if (isset($this->refund_data['invoices']) && count($this->refund_data['invoices']) > 0) {
foreach ($this->refund_data['invoices'] as $refunded_invoice) {
$invoice = Invoice::find($refunded_invoice['invoice_id']);
$invoice->service()->updateBalance($refunded_invoice['amount'])->save();
if ($invoice->amount == $invoice->balance) {
$invoice->service()->setStatus(Invoice::STATUS_SENT);
} else {
$invoice->service()->setStatus(Invoice::STATUS_PARTIAL);
}
$invoice->save();
$client = $invoice->client;
$adjustment_amount += $refunded_invoice['amount'];
$client->balance += $refunded_invoice['amount'];
$client->save();
//todo adjust ledger balance here? or after and reference the credit and its total
}
$ledger_string = ''; //todo
$this->credit_note->ledger()->updateCreditBalance($adjustment_amount, $ledger_string);
$this->payment->client->paid_to_date -= $this->refund_data['amount'];
$this->payment->client->save();
}
return $this;
}
private function save()
{
$this->payment->save();
return $this->payment;
}
}

View File

@ -28,6 +28,22 @@ trait PdfMaker
public function makePdf($header, $footer, $html) public function makePdf($header, $footer, $html)
{ {
$browser = Browsershot::html($html);
if(config('ninja.system.node_path'))
$browser->setNodeBinary(config('ninja.system.node_path'));
if(config('ninja.system.npm_path'))
$browser->setNpmBinary(config('ninja.system.npm_path'));
return $browser->deviceScaleFactor(1)
->showBackground()
->deviceScaleFactor(1)
->waitUntilNetworkIdle(true)
->pdf();
}
}
// if($header && $footer){ // if($header && $footer){
@ -46,19 +62,9 @@ trait PdfMaker
// else { // else {
// $browser = Browsershot::html($html); // $browser = Browsershot::html($html);
// } // }
//
$browser = Browsershot::html($html); //
// // return Browsershot::html($html)
// $browser->format('A4');
// $browser->landscape();
return $browser->deviceScaleFactor(1)
->showBackground()
->deviceScaleFactor(1)
->waitUntilNetworkIdle(true)
->pdf();
// return Browsershot::html($html)
// //->showBrowserHeaderAndFooter() // //->showBrowserHeaderAndFooter()
// //->headerHtml($header) // //->headerHtml($header)
// //->footerHtml($footer) // //->footerHtml($footer)
@ -67,5 +73,6 @@ trait PdfMaker
// ->waitUntilNetworkIdle(true) ->pdf(); // ->waitUntilNetworkIdle(true) ->pdf();
// //->margins(10,10,10,10) // //->margins(10,10,10,10)
// //->savePdf('test.pdf'); // //->savePdf('test.pdf');
} //
} // $browser->format('A4');
// $browser->landscape();

View File

@ -121,5 +121,9 @@ return [
'client_id' => env('GOOGLE_CLIENT_ID', ''), 'client_id' => env('GOOGLE_CLIENT_ID', ''),
'client_secret' => env('GOOGLE_CLIENT_SECRET','') 'client_secret' => env('GOOGLE_CLIENT_SECRET','')
] ]
],
'system' => [
'node_path' => env('NODE_PATH', false),
'npm_path' => env('NPM_PATH', false)
] ]
]; ];