Merge pull request #7221 from turbo124/v5-stable

v5.3.60
This commit is contained in:
David Bomba 2022-02-20 07:14:15 +11:00 committed by GitHub
commit f817675fe6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 149364 additions and 148710 deletions

View File

@ -1 +1 @@
5.3.59 5.3.60

View File

@ -75,8 +75,10 @@ class BackupUpdate extends Command
private function handleOnDb() private function handleOnDb()
{ {
set_time_limit(0);
Backup::whereHas('activity')->whereNotNull('html_backup')->cursor()->each(function($backup){ Backup::chunk(100, function ($backups) {
foreach ($backups as $backup) {
if($backup->activity->client()->exists()){ if($backup->activity->client()->exists()){
@ -85,6 +87,7 @@ class BackupUpdate extends Command
} }
}
}); });
} }

View File

@ -115,6 +115,8 @@ class CheckData extends Command
$this->checkEntityInvitations(); $this->checkEntityInvitations();
$this->checkCompanyData(); $this->checkCompanyData();
if(Ninja::isHosted())
$this->checkAccountStatuses();
if (! $this->option('client_id')) { if (! $this->option('client_id')) {
$this->checkOAuth(); $this->checkOAuth();
@ -244,38 +246,6 @@ class CheckData extends Command
} }
} }
// // check for more than one primary contact
// $clients = DB::table('clients')
// ->leftJoin('client_contacts', function ($join) {
// $join->on('client_contacts.client_id', '=', 'clients.id')
// ->where('client_contacts.is_primary', '=', true)
// ->whereNull('client_contacts.deleted_at');
// })
// ->groupBy('clients.id')
// ->havingRaw('count(client_contacts.id) != 1');
// if ($this->option('client_id')) {
// $clients->where('clients.id', '=', $this->option('client_id'));
// }
// $clients = $clients->get(['clients.id', 'clients.user_id', 'clients.company_id']);
// // $this->logMessage($clients->count().' clients without a single primary contact');
// // if ($this->option('fix') == 'true') {
// // foreach ($clients as $client) {
// // $this->logMessage("Fixing missing primary contacts #{$client->id}");
// // $new_contact = ClientContactFactory::create($client->company_id, $client->user_id);
// // $new_contact->client_id = $client->id;
// // $new_contact->contact_key = Str::random(40);
// // $new_contact->is_primary = true;
// // $new_contact->save();
// // }
// // }
// if ($clients->count() > 0) {
// $this->isValid = false;
// }
} }
private function checkFailedJobs() private function checkFailedJobs()
@ -447,6 +417,7 @@ class CheckData extends Command
payments.id = paymentables.payment_id payments.id = paymentables.payment_id
WHERE paymentable_type = 'App\\Models\\Credit' WHERE paymentable_type = 'App\\Models\\Credit'
AND paymentables.deleted_at is NULL AND paymentables.deleted_at is NULL
AND payments.is_deleted = 0
AND payments.client_id = ?; AND payments.client_id = ?;
"), [$client->id] ); "), [$client->id] );
@ -948,6 +919,30 @@ ORDER BY clients.id;
return $type.'s'; return $type.'s';
} }
public function checkAccountStatuses()
{
Account::where('plan_expires', '<=', now()->subDays(2))->cursor()->each(function ($account){
$client = Client::on('db-ninja-01')->where('company_id', config('ninja.ninja_default_company_id'))->where('custom_value2', $account->key)->first();
if($client){
$payment = Payment::on('db-ninja-01')
->where('company_id', config('ninja.ninja_default_company_id'))
->where('client_id', $client->id)
->where('date', '>=', now()->subDays(2))
->exists();
if($payment)
$this->logMessage("I found a payment for {$account->key}");
}
});
}
} }

View File

@ -22,8 +22,6 @@ use App\Utils\Traits\MakesHash;
use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Illuminate\View\View; use Illuminate\View\View;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
class DocumentController extends Controller class DocumentController extends Controller
{ {
@ -71,25 +69,34 @@ class DocumentController extends Controller
public function downloadMultiple(DownloadMultipleDocumentsRequest $request) public function downloadMultiple(DownloadMultipleDocumentsRequest $request)
{ {
$documents = Document::whereIn('id', $this->transformKeys($request->file_hash)) $documents = Document::whereIn('id', $this->transformKeys($request->file_hash))
->where('company_id', auth()->guard('contact')->user()->company->id) ->where('company_id', auth()->guard('contact')->user()->company_id)
->get(); ->get();
$documents->map(function ($document) { $zipFile = new \PhpZip\ZipFile();
if (auth()->guard('contact')->user()->client->id != $document->documentable->id) {
abort(401, 'Permission denied');
}
});
$options = new Archive(); try{
$options->setSendHttpHeaders(true);
$zip = new ZipStream(now() . '-documents.zip', $options);
foreach ($documents as $document) { foreach ($documents as $document) {
$zip->addFileFromPath(basename($document->diskPath()), TempFile::path($document->filePath())); $zipFile->addFile(TempFile::path($document->filePath()), $document->name);
} }
$zip->finish(); $filename = now() . '-documents.zip';
$filepath = sys_get_temp_dir() . '/' . $filename;
$zipFile->saveAsFile($filepath) // save the archive to a file
->close(); // close archive
return response()->download($filepath, $filename)->deleteFileAfterSend(true);
} }
catch(\PhpZip\Exception\ZipException $e){
// handle exception
}
finally{
$zipFile->close();
}
}
} }

View File

@ -28,8 +28,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Illuminate\View\View; use Illuminate\View\View;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class InvoiceController extends Controller class InvoiceController extends Controller
@ -198,9 +196,6 @@ class InvoiceController extends Controller
* @param array $ids * @param array $ids
* *
* @return void * @return void
* @throws \ZipStream\Exception\FileNotFoundException
* @throws \ZipStream\Exception\FileNotReadableException
* @throws \ZipStream\Exception\OverflowException
*/ */
private function downloadInvoicePDF(array $ids) private function downloadInvoicePDF(array $ids)
{ {
@ -228,21 +223,38 @@ class InvoiceController extends Controller
}, basename($file), ['Content-Type' => 'application/pdf']); }, basename($file), ['Content-Type' => 'application/pdf']);
} }
// enable output of HTTP headers return $this->buildZip($invoices);
$options = new Archive();
$options->setSendHttpHeaders(true);
// create a new zipstream object }
$zip = new ZipStream(date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.invoices')).'.zip', $options);
private function buildZip($invoices)
{
// create new archive
$zipFile = new \PhpZip\ZipFile();
try{
foreach ($invoices as $invoice) { foreach ($invoices as $invoice) {
#add it to the zip #add it to the zip
$zip->addFile(basename($invoice->pdf_file_path()), file_get_contents($invoice->pdf_file_path(null, 'url', true))); $zipFile->addFromString(basename($invoice->pdf_file_path()), file_get_contents($invoice->pdf_file_path(null, 'url', true)));
} }
// finish the zip stream $filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.invoices')).'.zip';
$zip->finish(); $filepath = sys_get_temp_dir() . '/' . $filename;
$zipFile->saveAsFile($filepath) // save the archive to a file
->close(); // close archive
return response()->download($filepath, $filename)->deleteFileAfterSend(true);
}
catch(\PhpZip\Exception\ZipException $e){
// handle exception
}
finally{
$zipFile->close();
}
} }
} }

View File

@ -28,8 +28,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Illuminate\View\View; use Illuminate\View\View;
use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
@ -140,21 +138,38 @@ class QuoteController extends Controller
}, basename($file), ['Content-Type' => 'application/pdf']); }, basename($file), ['Content-Type' => 'application/pdf']);
} }
// enable output of HTTP headers return $this->buildZip($quotes);
$options = new Archive();
$options->setSendHttpHeaders(true);
// create a new zipstream object
$zip = new ZipStream(date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.invoices')).'.zip', $options);
foreach ($quotes as $quote) {
$zip->addFile(basename($quote->pdf_file_path()), file_get_contents($quote->pdf_file_path(null, 'url', true)));
// $zip->addFileFromPath(basename($quote->pdf_file_path()), TempFile::path($quote->pdf_file_path()));
} }
// finish the zip stream private function buildZip($quotes)
$zip->finish(); {
// create new archive
$zipFile = new \PhpZip\ZipFile();
try{
foreach ($quotes as $quote) {
#add it to the zip
$zipFile->addFromString(basename($quote->pdf_file_path()), file_get_contents($quote->pdf_file_path(null, 'url', true)));
}
$filename = date('Y-m-d').'_'.str_replace(' ', '_', trans('texts.quotes')).'.zip';
$filepath = sys_get_temp_dir() . '/' . $filename;
$zipFile->saveAsFile($filepath) // save the archive to a file
->close(); // close archive
return response()->download($filepath, $filename)->deleteFileAfterSend(true);
}
catch(\PhpZip\Exception\ZipException $e){
// handle exception
}
finally{
$zipFile->close();
}
} }
protected function approve(array $ids, $process = false) protected function approve(array $ids, $process = false)

View File

@ -265,15 +265,16 @@ class MigrationController extends BaseController
foreach($request->all() as $input){ foreach($request->all() as $input){
if($input instanceof UploadedFile) if($input instanceof UploadedFile){
nlog('is file');
}
else else
$companies[] = json_decode($input,1); $companies[] = json_decode($input,1);
} }
} }
if (app()->environment() === 'local') { if (app()->environment() === 'local') {
nlog($request->all());
} }
try { try {

View File

@ -43,7 +43,7 @@ class InvoicesTable extends Component
$local_status = []; $local_status = [];
$query = Invoice::query() $query = Invoice::query()
->with('client.gateway_tokens','company','client.contacts') ->with('client.gateway_tokens','client.contacts')
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc') ->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('is_deleted', false); ->where('is_deleted', false);
@ -75,7 +75,7 @@ class InvoicesTable extends Component
} }
$query = $query $query = $query
->where('client_id', auth()->guard('contact')->user()->client->id) ->where('client_id', auth()->guard('contact')->user()->client_id)
->where('status_id', '<>', Invoice::STATUS_DRAFT) ->where('status_id', '<>', Invoice::STATUS_DRAFT)
->where('status_id', '<>', Invoice::STATUS_CANCELLED) ->where('status_id', '<>', Invoice::STATUS_CANCELLED)
->withTrashed() ->withTrashed()

View File

@ -36,6 +36,10 @@ class PaymentMethodsTable extends Component
->with('gateway_type') ->with('gateway_type')
->where('company_id', $this->company->id) ->where('company_id', $this->company->id)
->where('client_id', $this->client->id) ->where('client_id', $this->client->id)
->whereHas('gateway', function ($query) {
$query->where('is_deleted',0)
->where('deleted_at', NULL);
})
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc') ->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
->paginate($this->per_page); ->paginate($this->per_page);

View File

@ -33,7 +33,7 @@ class Locale
$locale = $request->input('lang'); $locale = $request->input('lang');
App::setLocale($locale); App::setLocale($locale);
} elseif (auth()->guard('contact')->user()) { } elseif (auth()->guard('contact')->user()) {
App::setLocale(auth()->guard('contact')->user()->client->locale()); App::setLocale(auth()->guard('contact')->user()->client()->setEagerLoads([])->first()->locale());
} elseif (auth()->user()) { } elseif (auth()->user()) {
try{ try{

View File

@ -39,8 +39,6 @@ class SessionDomains
} }
else{ else{
// Cookie::queue(Cookie::forget('invoice_ninja_session', '/'));
config(['session.domain' => $domain_name]); config(['session.domain' => $domain_name]);
} }

View File

@ -15,7 +15,8 @@ class ShowCreditRequest extends FormRequest
public function authorize() public function authorize()
{ {
return !$this->credit->is_deleted return !$this->credit->is_deleted
&& auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_CREDITS; && auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_CREDITS
&& auth()->guard('contact')->user()->client_id === $this->credit->client_id;
} }
/** /**

View File

@ -27,9 +27,10 @@ class ShowDocumentRequest extends FormRequest
*/ */
public function authorize() public function authorize()
{ {
return auth()->guard('contact')->user()->client_id == $this->document->documentable_id return auth()->guard('contact')->user()->client_id == $this->document->documentable_id
|| $this->document->documentable->client_id == auth()->guard('contact')->user()->client_id
|| $this->document->company_id == auth()->guard('contact')->user()->company_id; || $this->document->company_id == auth()->guard('contact')->user()->company_id;
} }
/** /**

View File

@ -23,7 +23,7 @@ class ShowInvoiceRequest extends Request
*/ */
public function authorize() : bool public function authorize() : bool
{ {
return auth()->guard('contact')->user()->client_id == $this->invoice->client_id return auth()->guard('contact')->user()->client_id === $this->invoice->client_id
&& auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_INVOICES; && auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_INVOICES;
} }
} }

View File

@ -19,7 +19,7 @@ class ShowQuoteRequest extends FormRequest
{ {
public function authorize() public function authorize()
{ {
return auth()->user()->client->id === $this->quote->client_id return auth()->guard('contact')->user()->client->id === $this->quote->client_id
&& auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_QUOTES; && auth()->guard('contact')->user()->company->enabled_modules & PortalComposer::MODULE_QUOTES;
} }

View File

@ -33,8 +33,6 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
class CompanyExport implements ShouldQueue class CompanyExport implements ShouldQueue

View File

@ -74,8 +74,6 @@ use Illuminate\Support\Str;
use JsonMachine\JsonDecoder\ExtJsonDecoder; use JsonMachine\JsonDecoder\ExtJsonDecoder;
use JsonMachine\JsonMachine; use JsonMachine\JsonMachine;
use ZipArchive; use ZipArchive;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
use function GuzzleHttp\json_encode; use function GuzzleHttp\json_encode;

View File

@ -25,8 +25,6 @@ use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use ZipStream\Option\Archive;
use ZipStream\ZipStream;
use ZipArchive; use ZipArchive;
class ZipInvoices implements ShouldQueue class ZipInvoices implements ShouldQueue

View File

@ -133,8 +133,6 @@ class TemplateEmail extends Mailable
$ubl_string = CreateUbl::dispatchNow($this->invitation->invoice); $ubl_string = CreateUbl::dispatchNow($this->invitation->invoice);
nlog($ubl_string);
if($ubl_string) if($ubl_string)
$this->attachData($ubl_string, $this->invitation->invoice->getFileName('xml')); $this->attachData($ubl_string, $this->invitation->invoice->getFileName('xml'));

View File

@ -26,10 +26,10 @@ class Backup extends BaseModel
return $this->belongsTo(Activity::class); return $this->belongsTo(Activity::class);
} }
public function storeRemotely(string $html, Client $client) public function storeRemotely(?string $html, Client $client)
{ {
if(strlen($html) == 0) if(!$html || strlen($html) == 0)
return; return;
$path = $client->backup_path() . "/"; $path = $client->backup_path() . "/";

View File

@ -258,7 +258,7 @@ class BaseDriver extends AbstractPaymentDriver
$payment->client_contact_id = $client_contact_id; $payment->client_contact_id = $client_contact_id;
$payment->saveQuietly(); $payment->saveQuietly();
/* Return early if the payment is no completed or pending*/ /* Return early if the payment is not completed or pending*/
if(!in_array($status, [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING]) ) if(!in_array($status, [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING]) )
return $payment; return $payment;

View File

@ -52,7 +52,19 @@ class Verify
if($this->stripe->stripe_connect && strlen($this->stripe->company_gateway->getConfigField('account_id')) < 1) if($this->stripe->stripe_connect && strlen($this->stripe->company_gateway->getConfigField('account_id')) < 1)
throw new StripeConnectFailure('Stripe Connect has not been configured'); throw new StripeConnectFailure('Stripe Connect has not been configured');
$customers = Customer::all([], $this->stripe->stripe_connect_auth); $total_stripe_customers = 0;
$starting_after = null;
do {
$customers = Customer::all(['limit' => 100, 'starting_after' => $starting_after], $this->stripe->stripe_connect_auth);
$total_stripe_customers += count($customers->data);
$starting_after = end($customers->data)['id'];
} while($customers->has_more);
$stripe_customers = $this->stripe->company_gateway->client_gateway_tokens->map(function ($cgt){ $stripe_customers = $this->stripe->company_gateway->client_gateway_tokens->map(function ($cgt){
@ -66,7 +78,7 @@ class Verify
}); });
$data = [ $data = [
'stripe_customer_count' => count($customers), 'stripe_customer_count' => $total_stripe_customers,
'stripe_customers' => $stripe_customers, 'stripe_customers' => $stripe_customers,
]; ];

View File

@ -55,13 +55,20 @@ class ImportCustomers
if(Ninja::isHosted() && strlen($this->stripe->company_gateway->getConfigField('account_id')) < 1) if(Ninja::isHosted() && strlen($this->stripe->company_gateway->getConfigField('account_id')) < 1)
throw new StripeConnectFailure('Stripe Connect has not been configured'); throw new StripeConnectFailure('Stripe Connect has not been configured');
$customers = Customer::all([], $this->stripe->stripe_connect_auth); $starting_after = null;
do {
$customers = Customer::all(['limit' => 100, 'starting_after' => $starting_after], $this->stripe->stripe_connect_auth);
foreach($customers as $customer) foreach($customers as $customer)
{ {
$this->addCustomer($customer); $this->addCustomer($customer);
} }
$starting_after = end($customers->data)['id'];
} while($customers->has_more);
} }
private function addCustomer(Customer $customer) private function addCustomer(Customer $customer)
@ -72,7 +79,7 @@ class ImportCustomers
if(!$account->isPaidHostedClient() && Client::where('company_id', $this->stripe->company_gateway->company_id)->count() > config('ninja.quotas.free.clients')) if(!$account->isPaidHostedClient() && Client::where('company_id', $this->stripe->company_gateway->company_id)->count() > config('ninja.quotas.free.clients'))
return; return;
nlog("search Stripe for {$customer->id}"); // nlog("search Stripe for {$customer->id}");
$existing_customer_token = $this->stripe $existing_customer_token = $this->stripe
->company_gateway ->company_gateway
@ -97,7 +104,7 @@ class ImportCustomers
return; return;
} }
nlog("inserting a customer"); // nlog("inserting a customer");
//nlog($customer); //nlog($customer);
$client = ClientFactory::create($this->stripe->company_gateway->company_id, $this->stripe->company_gateway->user_id); $client = ClientFactory::create($this->stripe->company_gateway->company_id, $this->stripe->company_gateway->user_id);

View File

@ -12,6 +12,7 @@
namespace App\Providers; namespace App\Providers;
use App\Utils\CssInlinerPlugin; use App\Utils\CssInlinerPlugin;
use Illuminate\Container\Container;
use Illuminate\Mail\MailManager; use Illuminate\Mail\MailManager;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
@ -38,8 +39,18 @@ class MailCssInlinerServiceProvider extends ServiceProvider
*/ */
public function register() public function register()
{ {
$this->app->singleton(CssInlinerPlugin::class, function ($app) { // $this->app->singleton(CssInlinerPlugin::class, function ($app) {
// return new CssInlinerPlugin([]);
// });
// $this->app->singleton(CssInlinerPlugin::class, function ($app) {
// return new CssInlinerPlugin([]);
// });
$this->app->bind(CssInlinerPlugin::class, function($app) {
return new CssInlinerPlugin([]); return new CssInlinerPlugin([]);
}); });
} }
} }

View File

@ -70,25 +70,24 @@ class PaymentMethod
$transformed_ids = $this->transformKeys(explode(',', $company_gateways)); $transformed_ids = $this->transformKeys(explode(',', $company_gateways));
$this->gateways = $this->client $this->gateways =
->company CompanyGateway::with('gateway')
->company_gateways ->where('company_id', $this->client->company_id)
->whereIn('id', $transformed_ids) ->whereIn('id', $transformed_ids)
->where('is_deleted', false) ->where('is_deleted', false)
->whereNull('deleted_at') ->whereNull('deleted_at')
->where('gateway_key', '!=', '54faab2ab6e3223dbe848b1686490baa') ->where('gateway_key', '!=', '54faab2ab6e3223dbe848b1686490baa')
->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority ->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority
return array_search($model->id, $transformed_ids);// this closure sorts for us return array_search($model->id, $transformed_ids);// this closure sorts for us
}); })->get();
} else { } else {
$this->gateways = $this->client $this->gateways = CompanyGateway::with('gateway')
->company ->where('company_id', $this->client->company_id)
->company_gateways
->where('gateway_key', '!=', '54faab2ab6e3223dbe848b1686490baa') ->where('gateway_key', '!=', '54faab2ab6e3223dbe848b1686490baa')
->whereNull('deleted_at') ->whereNull('deleted_at')
->where('is_deleted', false); ->where('is_deleted', false)->get();
} }
@ -106,25 +105,23 @@ class PaymentMethod
$transformed_ids = $this->transformKeys(explode(',', $company_gateways)); $transformed_ids = $this->transformKeys(explode(',', $company_gateways));
$this->gateways = $this->client $this->gateways = CompanyGateway::with('gateway')
->company ->where('company_id', $this->client->company_id)
->company_gateways
->whereIn('id', $transformed_ids) ->whereIn('id', $transformed_ids)
->where('is_deleted', false) ->where('is_deleted', false)
->whereNull('deleted_at') ->whereNull('deleted_at')
->where('gateway_key', '54faab2ab6e3223dbe848b1686490baa') ->where('gateway_key', '54faab2ab6e3223dbe848b1686490baa')
->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority ->sortby(function ($model) use ($transformed_ids) { //company gateways are sorted in order of priority
return array_search($model->id, $transformed_ids);// this closure sorts for us return array_search($model->id, $transformed_ids);// this closure sorts for us
}); })->get();
} else { } else {
$this->gateways = $this->client $this->gateways = CompanyGateway::with('gateway')
->company ->where('company_id', $this->client->company_id)
->company_gateways
->where('gateway_key', '54faab2ab6e3223dbe848b1686490baa') ->where('gateway_key', '54faab2ab6e3223dbe848b1686490baa')
->whereNull('deleted_at') ->whereNull('deleted_at')
->where('is_deleted', false); ->where('is_deleted', false)->get();
} }

View File

@ -307,8 +307,14 @@ class AutoBillInvoice extends AbstractService
{ {
//get all client gateway tokens and set the is_default one to the first record //get all client gateway tokens and set the is_default one to the first record
$gateway_tokens = $this->client->gateway_tokens()->orderBy('is_default', 'DESC')->get(); $gateway_tokens = $this->client
// $gateway_tokens = $this->client->gateway_tokens; ->gateway_tokens()
->whereHas('gateway', function ($query) {
$query->where('is_deleted',0)
->where('deleted_at', NULL);
})->orderBy('is_default', 'DESC')
->get();
$filtered_gateways = $gateway_tokens->filter(function ($gateway_token) use($amount) { $filtered_gateways = $gateway_tokens->filter(function ($gateway_token) use($amount) {

View File

@ -87,23 +87,6 @@ class UpdateInvoicePayment
$this->payment->applied += $paid_amount; $this->payment->applied += $paid_amount;
// $invoice->service() //caution what if we amount paid was less than partial - we wipe it!
// ->clearPartial()
// ->updateBalance($paid_amount * -1)
// ->updatePaidToDate($paid_amount)
// ->updateStatus()
// ->save();
// $invoice->refresh();
// $invoice->service()
// ->touchPdf(true)
// ->workFlow()
// ->save();
}); });
/* Remove the event updater from within the loop to prevent race conditions */ /* Remove the event updater from within the loop to prevent race conditions */

View File

@ -262,7 +262,9 @@ class Helpers
} }
} }
return $value; $x = str_replace(["\n", "<br>"], ["\r", "<br>"], $value);
return $x;
} }
/** /**

View File

@ -165,7 +165,7 @@ class HtmlEngine
$data['$entity'] = ['value' => '', 'label' => ctrans('texts.quote')]; $data['$entity'] = ['value' => '', 'label' => ctrans('texts.quote')];
$data['$number'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.quote_number')]; $data['$number'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.quote_number')];
$data['$number_short'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.quote_number_short')]; $data['$number_short'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.quote_number_short')];
$data['$entity.terms'] = ['value' => $this->entity->terms ?: '', 'label' => ctrans('texts.quote_terms')]; $data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms), $this->client) ?: '', 'label' => ctrans('texts.quote_terms')];
$data['$terms'] = &$data['$entity.terms']; $data['$terms'] = &$data['$entity.terms'];
$data['$view_link'] = ['value' => '<a class="button" href="'.$this->invitation->getLink().'">'.ctrans('texts.view_quote').'</a>', 'label' => ctrans('texts.view_quote')]; $data['$view_link'] = ['value' => '<a class="button" href="'.$this->invitation->getLink().'">'.ctrans('texts.view_quote').'</a>', 'label' => ctrans('texts.view_quote')];
$data['$viewLink'] = &$data['$view_link']; $data['$viewLink'] = &$data['$view_link'];
@ -180,7 +180,7 @@ class HtmlEngine
$data['$entity'] = ['value' => '', 'label' => ctrans('texts.credit')]; $data['$entity'] = ['value' => '', 'label' => ctrans('texts.credit')];
$data['$number'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.credit_number')]; $data['$number'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.credit_number')];
$data['$number_short'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.credit_number_short')]; $data['$number_short'] = ['value' => $this->entity->number ?: '', 'label' => ctrans('texts.credit_number_short')];
$data['$entity.terms'] = ['value' => $this->entity->terms ?: '', 'label' => ctrans('texts.credit_terms')]; $data['$entity.terms'] = ['value' => Helpers::processReservedKeywords(\nl2br($this->entity->terms), $this->client) ?: '', 'label' => ctrans('texts.credit_terms')];
$data['$terms'] = &$data['$entity.terms']; $data['$terms'] = &$data['$entity.terms'];
$data['$view_link'] = ['value' => '<a class="button" href="'.$this->invitation->getLink().'">'.ctrans('texts.view_credit').'</a>', 'label' => ctrans('texts.view_credit')]; $data['$view_link'] = ['value' => '<a class="button" href="'.$this->invitation->getLink().'">'.ctrans('texts.view_credit').'</a>', 'label' => ctrans('texts.view_credit')];
$data['$viewButton'] = &$data['$view_link']; $data['$viewButton'] = &$data['$view_link'];

View File

@ -65,8 +65,8 @@
"league/fractal": "^0.17.0", "league/fractal": "^0.17.0",
"league/omnipay": "^3.1", "league/omnipay": "^3.1",
"livewire/livewire": "^2.6", "livewire/livewire": "^2.6",
"maennchen/zipstream-php": "^1.2",
"mollie/mollie-api-php": "^2.36", "mollie/mollie-api-php": "^2.36",
"nelexa/zip": "^4.0",
"nwidart/laravel-modules": "^8.0", "nwidart/laravel-modules": "^8.0",
"omnipay/paypal": "^3.0", "omnipay/paypal": "^3.0",
"payfast/payfast-php-sdk": "^1.1", "payfast/payfast-php-sdk": "^1.1",

75
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "f430e1dc06c72464f547ba0bb71226cf", "content-hash": "ebb191c91f4011a448605a0fd725faff",
"packages": [ "packages": [
{ {
"name": "apimatic/jsonmapper", "name": "apimatic/jsonmapper",
@ -5582,6 +5582,79 @@
], ],
"time": "2021-07-05T08:18:36+00:00" "time": "2021-07-05T08:18:36+00:00"
}, },
{
"name": "nelexa/zip",
"version": "4.0.1",
"source": {
"type": "git",
"url": "https://github.com/Ne-Lexa/php-zip.git",
"reference": "a18f80db509b1b6e9798e2745dc100759107f50c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Ne-Lexa/php-zip/zipball/a18f80db509b1b6e9798e2745dc100759107f50c",
"reference": "a18f80db509b1b6e9798e2745dc100759107f50c",
"shasum": ""
},
"require": {
"ext-zlib": "*",
"php": "^7.4 || ^8.0",
"psr/http-message": "*",
"symfony/finder": "*"
},
"require-dev": {
"ext-bz2": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-iconv": "*",
"ext-openssl": "*",
"ext-xml": "*",
"friendsofphp/php-cs-fixer": "^3.4.0",
"guzzlehttp/psr7": "^1.6",
"phpunit/phpunit": "^9",
"symfony/http-foundation": "*",
"symfony/var-dumper": "*",
"vimeo/psalm": "^4.6"
},
"suggest": {
"ext-bz2": "Needed to support BZIP2 compression",
"ext-fileinfo": "Needed to get mime-type file",
"ext-iconv": "Needed to support convert zip entry name to requested character encoding",
"ext-openssl": "Needed to support encrypt zip entries or use ext-mcrypt"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpZip\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ne-Lexa",
"email": "alexey@nelexa.ru",
"role": "Developer"
}
],
"description": "PhpZip is a php-library for extended work with ZIP-archives. Open, create, update, delete, extract and get info tool. Supports appending to existing ZIP files, WinZip AES encryption, Traditional PKWARE Encryption, BZIP2 compression, external file attributes and ZIP64 extensions. Alternative ZipArchive. It does not require php-zip extension.",
"homepage": "https://github.com/Ne-Lexa/php-zip",
"keywords": [
"archive",
"extract",
"unzip",
"winzip",
"zip",
"ziparchive"
],
"support": {
"issues": "https://github.com/Ne-Lexa/php-zip/issues",
"source": "https://github.com/Ne-Lexa/php-zip/tree/4.0.1"
},
"time": "2021-12-12T09:50:45+00:00"
},
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
"version": "2.56.0", "version": "2.56.0",

View File

@ -14,8 +14,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true), 'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => '5.3.59', 'app_version' => '5.3.60',
'app_tag' => '5.3.59', 'app_tag' => '5.3.60',
'minimum_client_version' => '5.0.16', 'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1', 'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', ''), 'api_secret' => env('API_SECRET', ''),

View File

@ -28,11 +28,11 @@ const RESOURCES = {
"assets/NOTICES": "9a4bf0423a5e265f38c4df37f7a0a913", "assets/NOTICES": "9a4bf0423a5e265f38c4df37f7a0a913",
"assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1", "assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1",
"favicon.ico": "51636d3a390451561744c42188ccd628", "favicon.ico": "51636d3a390451561744c42188ccd628",
"/": "8fe22e7edac61053293766668b8032a6", "/": "0c9a98bf00406e79990693094969f3be",
"version.json": "a00481850d5c63ba5df4e22636643438", "version.json": "a00481850d5c63ba5df4e22636643438",
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35", "icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed", "icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
"main.dart.js": "16d305d3a123a71d0430ef6628c741b3", "main.dart.js": "b1de67644e0f666d4674fa21e80da5d1",
"favicon.png": "dca91c54388f52eded692718d5a98b8b", "favicon.png": "dca91c54388f52eded692718d5a98b8b",
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40", "manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
"canvaskit/profiling/canvaskit.js": "ae2949af4efc61d28a4a80fffa1db900", "canvaskit/profiling/canvaskit.js": "ae2949af4efc61d28a4a80fffa1db900",

66139
public/main.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

82535
public/main.foss.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

65647
public/main.html.dart.js vendored

File diff suppressed because one or more lines are too long

82107
public/main.next.dart.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,7 @@ const appendToElement = (parent, value) => {
_temp.hidden = true; _temp.hidden = true;
_parent.append(_temp); _parent.append(_temp);
}; };
window.appendToElement = appendToElement; window.appendToElement = appendToElement;

View File

@ -1,5 +1,5 @@
@php @php
$mobile = stripos($_SERVER['HTTP_USER_AGENT'], 'Android') || stripos($_SERVER['HTTP_USER_AGENT'], 'iPhone') || stripos($_SERVER['HTTP_USER_AGENT'], 'iPod') || stripos($_SERVER['HTTP_USER_AGENT'], 'iPad'); $mobile = stripos(request()->server('HTTP_USER_AGENT'), 'Android') || stripos(request()->server('HTTP_USER_AGENT'), 'iPhone') || stripos(request()->server('HTTP_USER_AGENT'), 'iPod') || stripos(request()->server('HTTP_USER_AGENT'), 'iPad');
@endphp @endphp
@push('head') @push('head')

View File

@ -1,7 +1,4 @@
@php @php
// $token_billing = $gateway instanceof \App\Models\CompanyGateway
// ? $gateway->token_billing !== 'always'
// : $gateway->company_gateway->token_billing !== 'always';
$gateway_instance = $gateway instanceof \App\Models\CompanyGateway ? $gateway : $gateway->company_gateway; $gateway_instance = $gateway instanceof \App\Models\CompanyGateway ? $gateway : $gateway->company_gateway;
$token_billing = true; $token_billing = true;
@ -9,7 +6,7 @@
$checked_on = ''; $checked_on = '';
$checked_off = 'checked'; $checked_off = 'checked';
if($gateway_instance->token_billing == 'off' || $gateway_instance->token_billing == 'always'){ if($gateway_instance->token_billing == 'off'){
$token_billing = false; $token_billing = false;
$token_billing_string = 'false'; $token_billing_string = 'false';
} }

View File

@ -1,5 +1,17 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'Credit card', 'card_title' => 'Credit card']) @extends('portal.ninja2020.layout.payments', ['gateway_title' => 'Credit card', 'card_title' => 'Credit card'])
@php
$gateway_instance = $gateway instanceof \App\Models\CompanyGateway ? $gateway : $gateway->company_gateway;
$token_billing_string = 'true';
if($gateway_instance->token_billing == 'off' || $gateway_instance->token_billing == 'optin'){
$token_billing_string = 'false';
}
@endphp
@section('gateway_head') @section('gateway_head')
@if($gateway->company_gateway->getConfigField('account_id')) @if($gateway->company_gateway->getConfigField('account_id'))
<meta name="stripe-account-id" content="{{ $gateway->company_gateway->getConfigField('account_id') }}"> <meta name="stripe-account-id" content="{{ $gateway->company_gateway->getConfigField('account_id') }}">
@ -18,7 +30,7 @@
<form action="{{ route('client.payments.response') }}" method="post" id="server-response"> <form action="{{ route('client.payments.response') }}" method="post" id="server-response">
@csrf @csrf
<input type="hidden" name="gateway_response"> <input type="hidden" name="gateway_response">
<input type="hidden" name="store_card"> <input type="hidden" name="store_card" value="{{ $token_billing_string }}">
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}"> <input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
<input type="hidden" name="company_gateway_id" value="{{ $gateway->getCompanyGatewayId() }}"> <input type="hidden" name="company_gateway_id" value="{{ $gateway->getCompanyGatewayId() }}">

View File

@ -105,18 +105,5 @@
var clipboard = new ClipboardJS('.btn'); var clipboard = new ClipboardJS('.btn');
// clipboard.on('success', function(e) {
// console.info('Action:', e.action);
// console.info('Text:', e.text);
// console.info('Trigger:', e.trigger);
// e.clearSelection();
// });
// clipboard.on('error', function(e) {
// console.error('Action:', e.action);
// console.error('Trigger:', e.trigger);
// });
</script> </script>
@endsection @endsection