mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-23 20:00:33 -04:00
commit
b2ee7cce38
5
.github/workflows/phpunit.yml
vendored
5
.github/workflows/phpunit.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
operating-system: ['ubuntu-18.04', 'ubuntu-20.04']
|
||||
php-versions: ['7.4','8.0']
|
||||
php-versions: ['7.4','8.0','8.1']
|
||||
phpunit-versions: ['latest']
|
||||
|
||||
env:
|
||||
@ -106,7 +106,8 @@ jobs:
|
||||
vendor/bin/phpunit --testdox
|
||||
env:
|
||||
DB_PORT: ${{ job.services.mysql.ports[3306] }}
|
||||
PHP_CS_FIXER_IGNORE_ENV: true
|
||||
|
||||
- name: Run php-cs-fixer
|
||||
run: |
|
||||
vendor/bin/php-cs-fixer fix
|
||||
PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix
|
||||
|
@ -1 +1 @@
|
||||
5.3.33
|
||||
5.3.34
|
@ -46,6 +46,13 @@ class CloneQuoteToInvoiceFactory
|
||||
$invoice->date = now()->format('Y-m-d');
|
||||
$invoice->balance = 0;
|
||||
$invoice->deleted_at = null;
|
||||
$invoice->next_send_date = null;
|
||||
$invoice->reminder1_sent = null;
|
||||
$invoice->reminder2_sent = null;
|
||||
$invoice->reminder3_sent = null;
|
||||
$invoice->reminder_last_sent = null;
|
||||
$invoice->last_sent_date = null;
|
||||
$invoice->last_viewed = null;
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class ExpenseFilters extends QueryFilters
|
||||
}
|
||||
|
||||
return $this->builder->where(function ($query) use ($filter) {
|
||||
$query->where('expenses.name', 'like', '%'.$filter.'%')
|
||||
$query->where('expenses.public_notes', 'like', '%'.$filter.'%')
|
||||
->orWhere('expenses.id_number', 'like', '%'.$filter.'%')
|
||||
->orWhere('expenses.custom_value1', 'like', '%'.$filter.'%')
|
||||
->orWhere('expenses.custom_value2', 'like', '%'.$filter.'%')
|
||||
@ -94,7 +94,10 @@ class ExpenseFilters extends QueryFilters
|
||||
{
|
||||
$sort_col = explode('|', $sort);
|
||||
|
||||
if(is_array($sort_col) && in_array($sort_col[1], ['asc', 'desc']) && in_array($sort_col[0], ['public_notes', 'date', 'id_number', 'custom_value1', 'custom_value2', 'custom_value3', 'custom_value4']))
|
||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,8 +60,15 @@ class ContactForgotPasswordController extends Controller
|
||||
{
|
||||
$account_id = $request->has('account_id') ? $request->get('account_id') : 1;
|
||||
$account = Account::find($account_id);
|
||||
|
||||
if($request->has('company_key'))
|
||||
$company = Company::where('company_key', $request->input('company_key'))->first();
|
||||
else
|
||||
$company = $account->companies->first();
|
||||
|
||||
if(!$account)
|
||||
$account = Account::first();
|
||||
|
||||
return $this->render('auth.passwords.request', [
|
||||
'title' => 'Client Password Reset',
|
||||
'passwordEmailRoute' => 'client.password.email',
|
||||
@ -90,7 +97,9 @@ class ContactForgotPasswordController extends Controller
|
||||
|
||||
// $user = MultiDB::hasContact($request->input('email'));
|
||||
$company = Company::where('company_key', $request->input('company_key'))->first();
|
||||
$contact = MultiDB::findContact(['company_id' => $company->id, 'email' => $request->input('email')]);
|
||||
//$contact = MultiDB::findContact(['company_id' => $company->id, 'email' => $request->input('email')]);
|
||||
nlog(['company_id' => $company->id, 'email' => $request->input('email')]);
|
||||
$contact = ClientContact::where(['company_id' => $company->id, 'email' => $request->input('email')])->first();
|
||||
|
||||
$response = false;
|
||||
|
||||
|
@ -42,16 +42,15 @@ class ContactLoginController extends Controller
|
||||
|
||||
if($request->has('company_key')){
|
||||
MultiDB::findAndSetDbByCompanyKey($request->input('company_key'));
|
||||
|
||||
$company = Company::where('company_key', $request->input('company_key'))->first();
|
||||
|
||||
}
|
||||
|
||||
if (!$company && strpos($request->getHost(), 'invoicing.co') !== false) {
|
||||
if($company){
|
||||
$account = $company->account;
|
||||
}
|
||||
elseif (!$company && strpos($request->getHost(), 'invoicing.co') !== false) {
|
||||
$subdomain = explode('.', $request->getHost())[0];
|
||||
|
||||
MultiDB::findAndSetDbByDomain(['subdomain' => $subdomain]);
|
||||
|
||||
$company = Company::where('subdomain', $subdomain)->first();
|
||||
|
||||
} elseif(Ninja::isHosted()){
|
||||
@ -107,7 +106,7 @@ class ContactLoginController extends Controller
|
||||
|
||||
public function authenticated(Request $request, ClientContact $client)
|
||||
{
|
||||
Auth::guard('contact')->login($client, true);
|
||||
Auth::guard('contact')->loginUsingId($client->id, true);
|
||||
|
||||
event(new ContactLoggedIn($client, $client->company, Ninja::eventVars()));
|
||||
|
||||
|
@ -43,7 +43,7 @@ class ContactRegisterController extends Controller
|
||||
$client = $this->getClient($request->all());
|
||||
$client_contact = $this->getClientContact($request->all(), $client);
|
||||
|
||||
Auth::guard('contact')->login($client_contact, true);
|
||||
Auth::guard('contact')->loginUsingId($client_contact->id, true);
|
||||
|
||||
return redirect()->route('client.dashboard');
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ class BaseController extends Controller
|
||||
$query->where('expenses.user_id', $user->id)->orWhere('expenses.assigned_user_id', $user->id);
|
||||
},
|
||||
'company.groups' => function ($query) use ($updated_at, $user) {
|
||||
$query->where('updated_at', '>=', $updated_at)->with('documents');
|
||||
$query->whereNotNull('updated_at')->with('documents');
|
||||
|
||||
// if(!$user->isAdmin())
|
||||
// $query->where('group_settings.user_id', $user->id);
|
||||
@ -275,7 +275,7 @@ class BaseController extends Controller
|
||||
|
||||
},
|
||||
'company.payment_terms'=> function ($query) use ($updated_at, $user) {
|
||||
$query->where('updated_at', '>=', $updated_at);
|
||||
$query->whereNotNull('updated_at');
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('payment_terms.user_id', $user->id);
|
||||
@ -346,7 +346,6 @@ class BaseController extends Controller
|
||||
|
||||
},
|
||||
'company.subscriptions'=> function ($query) use($updated_at, $user) {
|
||||
// $query->where('updated_at', '>=', $updated_at);
|
||||
$query->whereNotNull('updated_at');
|
||||
|
||||
if(!$user->isAdmin())
|
||||
|
@ -25,7 +25,7 @@ class ContactHashLoginController extends Controller
|
||||
*/
|
||||
public function login(string $contact_key)
|
||||
{
|
||||
if(request()->has('subscription') && $request->subscription == 'true') {
|
||||
if(request()->has('subscription') && request()->subscription == 'true') {
|
||||
|
||||
$recurring_invoice = RecurringInvoice::where('client_id', auth()->guard('contact')->client->id)
|
||||
->whereNotNull('subscription_id')
|
||||
|
@ -15,6 +15,7 @@ namespace App\Http\Controllers\ClientPortal;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ClientPortal\Documents\ShowDocumentRequest;
|
||||
use App\Http\Requests\Document\DownloadMultipleDocumentsRequest;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\Document;
|
||||
use App\Utils\TempFile;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
@ -55,6 +56,8 @@ class DocumentController extends Controller
|
||||
|
||||
public function publicDownload(string $document_hash)
|
||||
{
|
||||
MultiDB::documentFindAndSetDb($document_hash);
|
||||
|
||||
$document = Document::where('hash', $document_hash)->firstOrFail();
|
||||
|
||||
$headers = [];
|
||||
|
@ -71,6 +71,8 @@ class InvitationController extends Controller
|
||||
if(!in_array($entity, ['invoice', 'credit', 'quote', 'recurring_invoice']))
|
||||
return response()->json(['message' => 'Invalid resource request']);
|
||||
|
||||
$is_silent = 'false';
|
||||
|
||||
$key = $entity.'_id';
|
||||
|
||||
$entity_obj = 'App\Models\\'.ucfirst(Str::camel($entity)).'Invitation';
|
||||
@ -92,7 +94,7 @@ class InvitationController extends Controller
|
||||
$client_contact->email = Str::random(15) . "@example.com"; $client_contact->save();
|
||||
|
||||
if (request()->has('client_hash') && request()->input('client_hash') == $invitation->contact->client->client_hash) {
|
||||
auth()->guard('contact')->login($client_contact, true);
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||
|
||||
} elseif ((bool) $invitation->contact->client->getSetting('enable_client_portal_password') !== false) {
|
||||
$this->middleware('auth:contact');
|
||||
@ -100,7 +102,7 @@ class InvitationController extends Controller
|
||||
|
||||
} else {
|
||||
nlog("else - default - login contact");
|
||||
auth()->guard('contact')->login($client_contact, true);
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||
}
|
||||
|
||||
|
||||
@ -111,8 +113,16 @@ class InvitationController extends Controller
|
||||
|
||||
$this->fireEntityViewedEvent($invitation, $entity);
|
||||
}
|
||||
else{
|
||||
$is_silent = 'true';
|
||||
|
||||
return redirect()->route('client.'.$entity.'.show', [$entity => $this->encodePrimaryKey($invitation->{$key}), 'silent' => $is_silent]);
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('client.'.$entity.'.show', [$entity => $this->encodePrimaryKey($invitation->{$key})]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function fireEntityViewedEvent($invitation, $entity_string)
|
||||
@ -191,7 +201,7 @@ class InvitationController extends Controller
|
||||
if($payment->client_id != $contact->client_id)
|
||||
abort(403, 'You are not authorized to view this resource');
|
||||
|
||||
auth()->guard('contact')->login($contact, true);
|
||||
auth()->guard('contact')->loginUsingId($contact->id, true);
|
||||
|
||||
return redirect()->route('client.payments.show', $payment->hashed_id);
|
||||
|
||||
@ -203,7 +213,7 @@ class InvitationController extends Controller
|
||||
->with('contact.client')
|
||||
->firstOrFail();
|
||||
|
||||
auth()->guard('contact')->login($invitation->contact, true);
|
||||
auth()->guard('contact')->loginUsingId($invitation->contact->id, true);
|
||||
|
||||
$invoice = $invitation->invoice;
|
||||
|
||||
|
@ -50,14 +50,17 @@ class NinjaPlanController extends Controller
|
||||
|
||||
nlog("Ninja Plan Controller - Found and set Client Contact");
|
||||
|
||||
Auth::guard('contact')->login($client_contact,true);
|
||||
Auth::guard('contact')->loginUsingId($client_contact->id,true);
|
||||
|
||||
/* Current paid users get pushed straight to subscription overview page*/
|
||||
if($account->isPaidHostedClient())
|
||||
return redirect('/client/dashboard');
|
||||
// /* Current paid users get pushed straight to subscription overview page*/
|
||||
// if($account->isPaidHostedClient())
|
||||
// return redirect('/client/dashboard');
|
||||
|
||||
// /* Users that are not paid get pushed to a custom purchase page */
|
||||
// return $this->render('subscriptions.ninja_plan', ['settings' => $client_contact->company->settings]);
|
||||
|
||||
return $this->plan();
|
||||
|
||||
/* Users that are not paid get pushed to a custom purchase page */
|
||||
return $this->render('subscriptions.ninja_plan', ['settings' => $client_contact->company->settings]);
|
||||
}
|
||||
|
||||
return redirect()->route('client.catchall');
|
||||
@ -68,6 +71,7 @@ class NinjaPlanController extends Controller
|
||||
{
|
||||
//harvest the current plan
|
||||
$data = [];
|
||||
$data['late_invoice'] = false;
|
||||
|
||||
if(MultiDB::findAndSetDbByAccountKey(Auth::guard('contact')->user()->client->custom_value2))
|
||||
{
|
||||
@ -137,8 +141,7 @@ class NinjaPlanController extends Controller
|
||||
|
||||
}
|
||||
else
|
||||
return redirect()->route('client.catchall');
|
||||
|
||||
return redirect('/client/dashboard');
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class SwitchCompanyController extends Controller
|
||||
->where('id', $this->transformKeys($contact))
|
||||
->first();
|
||||
|
||||
auth()->guard('contact')->login($client_contact, true);
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||
|
||||
return redirect('/client/dashboard');
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ class LicenseController extends BaseController
|
||||
'message' => trans('texts.invalid_white_label_license'),
|
||||
'errors' => new stdClass,
|
||||
];
|
||||
|
||||
$account = auth()->user()->account;
|
||||
$account->plan_term = Account::PLAN_TERM_YEARLY;
|
||||
$account->plan_paid = null;
|
||||
$account->plan_expires = null;
|
||||
@ -116,7 +116,7 @@ class LicenseController extends BaseController
|
||||
|
||||
return response()->json($error, 400);
|
||||
} else {
|
||||
$account = auth()->user()->company()->account;
|
||||
$account = auth()->user()->account;
|
||||
|
||||
$account->plan_term = Account::PLAN_TERM_YEARLY;
|
||||
$account->plan_paid = $data;
|
||||
@ -151,7 +151,7 @@ class LicenseController extends BaseController
|
||||
|
||||
private function checkLicense()
|
||||
{
|
||||
$account = auth()->user()->company()->account;
|
||||
$account = auth()->user()->account;
|
||||
|
||||
if($account->plan == 'white_label' && Carbon::parse($account->plan_expires)->lt(now())){
|
||||
$account->plan = null;
|
||||
|
@ -285,7 +285,7 @@ class BillingPortalPurchase extends Component
|
||||
*/
|
||||
protected function getPaymentMethods(ClientContact $contact): self
|
||||
{
|
||||
Auth::guard('contact')->login($contact, true);
|
||||
Auth::guard('contact')->loginUsingId($contact->id, true);
|
||||
|
||||
$this->contact = $contact;
|
||||
|
||||
|
@ -74,7 +74,7 @@ class DocumentsTable extends Component
|
||||
break;
|
||||
|
||||
case 'expenses':
|
||||
$this->query = $this->expenses();
|
||||
// $this->query = $this->expenses();
|
||||
break;
|
||||
|
||||
case 'invoices':
|
||||
|
@ -43,6 +43,7 @@ class InvoicesTable extends Component
|
||||
$local_status = [];
|
||||
|
||||
$query = Invoice::query()
|
||||
->with('client.gateway_tokens','company','client.contacts')
|
||||
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc')
|
||||
->where('company_id', $this->company->id)
|
||||
->where('is_deleted', false);
|
||||
@ -82,6 +83,7 @@ class InvoicesTable extends Component
|
||||
|
||||
return render('components.livewire.invoices-table', [
|
||||
'invoices' => $query,
|
||||
'gateway_available' => !empty(auth()->user()->client->service()->getPaymentMethods(0)),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class QuotesTable extends Component
|
||||
public function render()
|
||||
{
|
||||
$query = Quote::query()
|
||||
->with('client.gateway_tokens','company','client.contacts')
|
||||
->orderBy($this->sort_field, $this->sort_asc ? 'asc' : 'desc');
|
||||
|
||||
if (count($this->status) > 0) {
|
||||
@ -48,6 +49,7 @@ class QuotesTable extends Component
|
||||
->where('company_id', $this->company->id)
|
||||
->where('client_id', auth('contact')->user()->client->id)
|
||||
->where('status_id', '<>', Quote::STATUS_DRAFT)
|
||||
->where('is_deleted', 0)
|
||||
->withTrashed()
|
||||
->paginate($this->per_page);
|
||||
|
||||
|
@ -60,7 +60,7 @@ class RequiredClientInfo extends Component
|
||||
|
||||
'contact_first_name' => 'first_name',
|
||||
'contact_last_name' => 'last_name',
|
||||
// 'contact_email' => 'email',
|
||||
'contact_email' => 'email',
|
||||
// 'contact_phone' => 'phone',
|
||||
];
|
||||
|
||||
|
@ -29,7 +29,7 @@ class CheckClientExistence
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$multiple_contacts = ClientContact::query()
|
||||
->with('company','client')
|
||||
->with('client.gateway_tokens')
|
||||
->where('email', auth('contact')->user()->email)
|
||||
->whereNotNull('email')
|
||||
->where('email', '<>', '')
|
||||
@ -52,7 +52,7 @@ class CheckClientExistence
|
||||
}
|
||||
|
||||
if (count($multiple_contacts) == 1) {
|
||||
Auth::guard('contact')->login($multiple_contacts[0], true);
|
||||
Auth::guard('contact')->loginUsingId($multiple_contacts[0]->id, true);
|
||||
}
|
||||
|
||||
session()->put('multiple_contacts', $multiple_contacts);
|
||||
|
@ -52,7 +52,7 @@ class ContactKeyLogin
|
||||
if(empty($client_contact->email))
|
||||
$client_contact->email = Str::random(15) . "@example.com"; $client_contact->save();
|
||||
|
||||
auth()->guard('contact')->login($client_contact, true);
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||
|
||||
if ($request->query('redirect') && !empty($request->query('redirect'))) {
|
||||
return redirect()->to($request->query('redirect'));
|
||||
@ -70,7 +70,7 @@ class ContactKeyLogin
|
||||
if(empty($client_contact->email))
|
||||
$client_contact->email = Str::random(6) . "@example.com"; $client_contact->save();
|
||||
|
||||
auth()->guard('contact')->login($client_contact, true);
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||
|
||||
if ($request->query('next')) {
|
||||
return redirect()->to($request->query('next'));
|
||||
@ -86,7 +86,7 @@ class ContactKeyLogin
|
||||
$client_contact->email = Str::random(6) . "@example.com"; $client_contact->save();
|
||||
}
|
||||
|
||||
auth()->guard('contact')->login($client_contact, true);
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, true);
|
||||
|
||||
if ($request->query('next')) {
|
||||
return redirect($request->query('next'));
|
||||
@ -104,7 +104,7 @@ class ContactKeyLogin
|
||||
if(empty($primary_contact->email))
|
||||
$primary_contact->email = Str::random(6) . "@example.com"; $primary_contact->save();
|
||||
|
||||
auth()->guard('contact')->login($primary_contact, true);
|
||||
auth()->guard('contact')->loginUsingId($primary_contact->id, true);
|
||||
return redirect()->to('client/dashboard');
|
||||
}
|
||||
}
|
||||
@ -116,7 +116,7 @@ class ContactKeyLogin
|
||||
if(empty($primary_contact->email))
|
||||
$primary_contact->email = Str::random(6) . "@example.com"; $primary_contact->save();
|
||||
|
||||
auth()->guard('contact')->login($primary_contact, true);
|
||||
auth()->guard('contact')->loginUsingId($primary_contact->id, true);
|
||||
|
||||
return redirect()->to('client/dashboard');
|
||||
}
|
||||
|
@ -19,10 +19,11 @@ class ContactRegister
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$domain_name = $request->getHost();
|
||||
|
||||
if (strpos($request->getHost(), 'invoicing.co') !== false)
|
||||
if (strpos($domain_name, 'invoicing.co') !== false)
|
||||
{
|
||||
$subdomain = explode('.', $request->getHost())[0];
|
||||
$subdomain = explode('.', $domain_name)[0];
|
||||
|
||||
$query = [
|
||||
'subdomain' => $subdomain,
|
||||
@ -86,6 +87,6 @@ class ContactRegister
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
abort(404, 'ContactRegister Middlware');
|
||||
abort(404, 'ContactRegister Middleware');
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class ContactTokenAuth
|
||||
}
|
||||
|
||||
//stateless, don't remember the contact.
|
||||
auth()->guard('contact')->login($client_contact, false);
|
||||
auth()->guard('contact')->loginUsingId($client_contact->id, false);
|
||||
|
||||
event(new ContactLoggedIn($client_contact, $client_contact->company, Ninja::eventVars()));
|
||||
} else {
|
||||
|
@ -38,10 +38,11 @@ class SetDomainNameDb
|
||||
if(!config('ninja.db.multi_db_enabled'))
|
||||
return $next($request);
|
||||
|
||||
$domain_name = $request->getHost();
|
||||
|
||||
if (strpos($request->getHost(), 'invoicing.co') !== false)
|
||||
if (strpos($domain_name, 'invoicing.co') !== false)
|
||||
{
|
||||
$subdomain = explode('.', $request->getHost())[0];
|
||||
$subdomain = explode('.', $domain_name)[0];
|
||||
|
||||
$query = [
|
||||
'subdomain' => $subdomain,
|
||||
@ -49,7 +50,7 @@ class SetDomainNameDb
|
||||
];
|
||||
|
||||
if($company = MultiDB::findAndSetDbByDomain($query)){
|
||||
$request->request->add(['account_id' => $company->account_id]);
|
||||
$request->request->add(['account_id' => $company->account_id, 'company_key' => $company->company_key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -71,7 +72,7 @@ class SetDomainNameDb
|
||||
];
|
||||
|
||||
if($company = MultiDB::findAndSetDbByDomain($query)){
|
||||
$request->request->add(['account_id' => $company->account_id]);
|
||||
$request->request->add(['account_id' => $company->account_id, 'company_key' => $company->company_key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -86,8 +87,6 @@ class SetDomainNameDb
|
||||
|
||||
}
|
||||
|
||||
// config(['app.url' => $request->getSchemeAndHttpHost()]);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ class ShowPlanSwitchRequest extends FormRequest
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
||||
return (bool)$this->recurring_invoice->subscription->allow_plan_changes;
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,9 @@ class StoreCompanyRequest extends Request
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists('portal_domain', $input))
|
||||
$input['portal_domain'] = strtolower($input['portal_domain']);
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
}
|
||||
|
@ -68,8 +68,10 @@ class UpdateCompanyRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(Ninja::isHosted() && array_key_exists('portal_domain', $input) && strlen($input['portal_domain']) > 1)
|
||||
if(Ninja::isHosted() && array_key_exists('portal_domain', $input) && strlen($input['portal_domain']) > 1){
|
||||
$input['portal_domain'] = $this->addScheme($input['portal_domain']);
|
||||
$input['portal_domain'] = strtolower($input['portal_domain']);
|
||||
}
|
||||
|
||||
if (array_key_exists('settings', $input)) {
|
||||
$input['settings'] = $this->filterSaveableSettings($input['settings']);
|
||||
|
@ -113,7 +113,6 @@ class PortalComposer
|
||||
|
||||
$data[] = ['title' => ctrans('texts.payment_methods'), 'url' => 'client.payment_methods.index', 'icon' => 'shield'];
|
||||
$data[] = ['title' => ctrans('texts.documents'), 'url' => 'client.documents.index', 'icon' => 'download'];
|
||||
$data[] = ['title' => ctrans('texts.subscriptions'), 'url' => 'client.subscriptions.index', 'icon' => 'calendar'];
|
||||
|
||||
if (auth('contact')->user()->client->getSetting('enable_client_portal_tasks')) {
|
||||
$data[] = ['title' => ctrans('texts.tasks'), 'url' => 'client.tasks.index', 'icon' => 'clock'];
|
||||
@ -123,6 +122,8 @@ class PortalComposer
|
||||
|
||||
if(Ninja::isHosted() && auth('contact')->user()->company->id == config('ninja.ninja_default_company_id'))
|
||||
$data[] = ['title' => ctrans('texts.plan'), 'url' => 'client.plan', 'icon' => 'credit-card'];
|
||||
else
|
||||
$data[] = ['title' => ctrans('texts.subscriptions'), 'url' => 'client.subscriptions.index', 'icon' => 'calendar'];
|
||||
|
||||
|
||||
return $data;
|
||||
|
@ -62,10 +62,18 @@ class BaseTransformer
|
||||
public function getClient($client_name, $client_email) {
|
||||
$clients = $this->maps['company']->clients;
|
||||
|
||||
$clients = $clients->where( 'id_number', $client_name );
|
||||
$client_id_search = $clients->where( 'id_number', $client_name );
|
||||
|
||||
if ( $clients->count() >= 1 ) {
|
||||
return $clients->first()->id;
|
||||
if ( $client_id_search->count() >= 1 ) {
|
||||
return $client_id_search->first()->id;
|
||||
nlog("found via id number");
|
||||
}
|
||||
|
||||
$client_name_search = $clients->where( 'name', $client_name );
|
||||
|
||||
if ( $client_name_search->count() >= 1 ) {
|
||||
return $client_name_search->first()->id;
|
||||
nlog("found via name");
|
||||
}
|
||||
|
||||
if ( ! empty( $client_email ) ) {
|
||||
@ -74,8 +82,10 @@ class BaseTransformer
|
||||
|
||||
if ( $contacts->count() >= 1 ) {
|
||||
return $contacts->first()->client_id;
|
||||
nlog("found via contact");
|
||||
}
|
||||
}
|
||||
nlog("did not find client");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class InvoiceTransformer extends BaseTransformer {
|
||||
'due_date' => isset( $invoice_data['invoice.due_date'] ) ? date( 'Y-m-d', strtotime( $invoice_data['invoice.due_date'] ) ) : null,
|
||||
'terms' => $this->getString( $invoice_data, 'invoice.terms' ),
|
||||
'public_notes' => $this->getString( $invoice_data, 'invoice.public_notes' ),
|
||||
'is_sent' => $this->getString( $invoice_data, 'invoice.is_sent' ),
|
||||
// 'is_sent' => $this->getString( $invoice_data, 'invoice.is_sent' ),
|
||||
'private_notes' => $this->getString( $invoice_data, 'invoice.private_notes' ),
|
||||
'tax_name1' => $this->getString( $invoice_data, 'invoice.tax_name1' ),
|
||||
'tax_rate1' => $this->getFloat( $invoice_data, 'invoice.tax_rate1' ),
|
||||
@ -92,7 +92,7 @@ class InvoiceTransformer extends BaseTransformer {
|
||||
'amount' => $this->getFloat( $invoice_data, 'invoice.amount' ),
|
||||
],
|
||||
];
|
||||
} elseif ( isset( $transformed['amount'] ) && isset( $transformed['balance'] ) ) {
|
||||
} elseif ( isset( $transformed['amount'] ) && isset( $transformed['balance'] ) && ($transformed['amount'] != $transformed['balance'])) {
|
||||
$transformed['payments'] = [
|
||||
[
|
||||
'date' => isset( $invoice_data['payment.date'] ) ? date( 'Y-m-d', strtotime( $invoice_data['payment.date'] ) ) : date( 'y-m-d' ),
|
||||
@ -126,6 +126,8 @@ class InvoiceTransformer extends BaseTransformer {
|
||||
}
|
||||
$transformed['line_items'] = $line_items;
|
||||
|
||||
nlog($transformed);
|
||||
|
||||
return $transformed;
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ class AutoBill
|
||||
|
||||
nlog("autobill {$this->invoice->id}");
|
||||
|
||||
$this->invoice->service()->autoBill()->save();
|
||||
$this->invoice->service()->autoBill();
|
||||
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
|
@ -115,9 +115,6 @@ class CreateEntityPdf implements ShouldQueue
|
||||
/* Set customized translations _NOW_ */
|
||||
$t->replace(Ninja::transformTranslations($this->client->getMergedSettings()));
|
||||
|
||||
$translate = microtime(true);
|
||||
// nlog("Translate ". $translate - $start);
|
||||
|
||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
||||
return (new Phantom)->generate($this->invitation);
|
||||
}
|
||||
@ -142,9 +139,6 @@ class CreateEntityPdf implements ShouldQueue
|
||||
|
||||
$entity_design_id = $this->entity->design_id ? $this->entity->design_id : $this->decodePrimaryKey($this->client->getSetting($entity_design_id));
|
||||
|
||||
// if(!$this->company->account->hasFeature(Account::FEATURE_DIFFERENT_DESIGNS))
|
||||
// $entity_design_id = 2;
|
||||
|
||||
$design = Design::find($entity_design_id);
|
||||
|
||||
/* Catch all in case migration doesn't pass back a valid design */
|
||||
@ -153,9 +147,6 @@ class CreateEntityPdf implements ShouldQueue
|
||||
|
||||
$html = new HtmlEngine($this->invitation);
|
||||
|
||||
$design_time = microtime(true);
|
||||
// nlog("Design ". $design_time - $translate);
|
||||
|
||||
if ($design->is_custom) {
|
||||
$options = [
|
||||
'custom_partials' => json_decode(json_encode($design->design), true)
|
||||
@ -167,9 +158,6 @@ class CreateEntityPdf implements ShouldQueue
|
||||
|
||||
$variables = $html->generateLabelsAndValues();
|
||||
|
||||
$labels_time = microtime(true);
|
||||
// nlog("Labels ". $labels_time - $design_time);
|
||||
|
||||
$state = [
|
||||
'template' => $template->elements([
|
||||
'client' => $this->client,
|
||||
@ -192,10 +180,6 @@ class CreateEntityPdf implements ShouldQueue
|
||||
->design($template)
|
||||
->build();
|
||||
|
||||
|
||||
$template_time = microtime(true);
|
||||
// nlog("Template Build ". $template_time - $labels_time);
|
||||
|
||||
$pdf = null;
|
||||
|
||||
try {
|
||||
@ -215,10 +199,6 @@ class CreateEntityPdf implements ShouldQueue
|
||||
info($maker->getCompiledHTML());
|
||||
}
|
||||
|
||||
|
||||
$pdf_time = microtime(true);
|
||||
// nlog("PDF time " . $pdf_time - $template_time);
|
||||
|
||||
if ($pdf) {
|
||||
|
||||
try{
|
||||
|
@ -188,9 +188,9 @@ class CreateRawPdf implements ShouldQueue
|
||||
nlog(print_r($e->getMessage(), 1));
|
||||
}
|
||||
|
||||
// if (config('ninja.log_pdf_html')) {
|
||||
if (config('ninja.log_pdf_html')) {
|
||||
info($maker->getCompiledHTML());
|
||||
// }
|
||||
}
|
||||
|
||||
if ($pdf)
|
||||
return $pdf;
|
||||
|
@ -112,6 +112,9 @@ class EmailEntity implements ShouldQueue
|
||||
App::setLocale($this->invitation->contact->preferredLocale());
|
||||
$t->replace(Ninja::transformTranslations($this->settings));
|
||||
|
||||
/* Mark entity sent */
|
||||
$this->entity->service()->markSent()->save();
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new TemplateEmail($this->email_entity_builder, $this->invitation->contact, $this->invitation);
|
||||
$nmo->company = $this->company;
|
||||
@ -124,8 +127,7 @@ class EmailEntity implements ShouldQueue
|
||||
|
||||
NinjaMailerJob::dispatchNow($nmo);
|
||||
|
||||
/* Mark entity sent */
|
||||
$this->entity->service()->markSent()->save();
|
||||
|
||||
}
|
||||
|
||||
private function resolveEntityString() :string
|
||||
|
@ -332,18 +332,21 @@ class CSVImport implements ShouldQueue {
|
||||
$invoice = $invoice->service()->markViewed()->save();
|
||||
}
|
||||
|
||||
if ( $invoice->status_id === Invoice::STATUS_SENT ) {
|
||||
if( $invoice->status_id === Invoice::STATUS_DRAFT ){
|
||||
|
||||
}
|
||||
elseif ( $invoice->status_id === Invoice::STATUS_SENT ) {
|
||||
$invoice = $invoice->service()->markSent()->save();
|
||||
}
|
||||
|
||||
if ( $invoice->status_id <= Invoice::STATUS_SENT && $invoice->amount > 0 ) {
|
||||
if ( $invoice->balance < $invoice->amount ) {
|
||||
$invoice->status_id = Invoice::STATUS_PARTIAL;
|
||||
$invoice->save();
|
||||
} elseif ( $invoice->balance <= 0 ) {
|
||||
elseif ( $invoice->status_id <= Invoice::STATUS_SENT && $invoice->amount > 0 ) {
|
||||
if ( $invoice->balance <= 0 ) {
|
||||
$invoice->status_id = Invoice::STATUS_PAID;
|
||||
$invoice->save();
|
||||
}
|
||||
elseif ( $invoice->balance != $invoice->amount ) {
|
||||
$invoice->status_id = Invoice::STATUS_PARTIAL;
|
||||
$invoice->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,8 +20,10 @@ use App\Mail\Admin\EntityNotificationMailer;
|
||||
use App\Mail\Admin\PaymentFailureObject;
|
||||
use App\Models\Client;
|
||||
use App\Models\Company;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\User;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\Notifications\UserNotifies;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@ -34,7 +36,7 @@ use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class PaymentFailedMailer implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, UserNotifies;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, UserNotifies, MakesHash;
|
||||
|
||||
public ?PaymentHash $payment_hash;
|
||||
|
||||
@ -75,15 +77,17 @@ class PaymentFailedMailer implements ShouldQueue
|
||||
|
||||
$settings = $this->client->getMergedSettings();
|
||||
$amount = 0;
|
||||
$invoice = false;
|
||||
|
||||
if($this->payment_hash)
|
||||
if($this->payment_hash){
|
||||
$amount = array_sum(array_column($this->payment_hash->invoices(), 'amount')) + $this->payment_hash->fee_total;
|
||||
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
|
||||
}
|
||||
|
||||
//iterate through company_users
|
||||
$this->company->company_users->each(function ($company_user) use($amount, $settings){
|
||||
$this->company->company_users->each(function ($company_user) use($amount, $settings, $invoice){
|
||||
|
||||
//determine if this user has the right permissions
|
||||
$methods = $this->findCompanyUserNotificationType($company_user, ['payment_failure','all_notifications']);
|
||||
$methods = $this->findUserEntityNotificationType($invoice ?: $this->client, $company_user, ['payment_failure_user', 'payment_failure_all', 'payment_failure', 'all_notifications']);
|
||||
|
||||
//if mail is a method type -fire mail!!
|
||||
if (($key = array_search('mail', $methods)) !== false) {
|
||||
|
@ -80,7 +80,7 @@ class PaymentFailureMailer implements ShouldQueue
|
||||
$this->company->company_users->each(function ($company_user) {
|
||||
|
||||
//determine if this user has the right permissions
|
||||
$methods = $this->findCompanyUserNotificationType($company_user, ['payment_failure','all_notifications']);
|
||||
$methods = $this->findCompanyUserNotificationType($company_user, ['payment_failure_all','payment_failure', 'payment_failure_user', 'all_notifications']);
|
||||
|
||||
//if mail is a method type -fire mail!!
|
||||
if (($key = array_search('mail', $methods)) !== false) {
|
||||
|
@ -145,7 +145,7 @@ class SendRecurring implements ShouldQueue
|
||||
|
||||
if ($invoice->client->getSetting('auto_bill_date') == 'on_send_date' && $invoice->auto_bill_enabled) {
|
||||
nlog("attempting to autobill {$invoice->number}");
|
||||
$invoice->service()->autoBill()->save();
|
||||
$invoice->service()->autoBill();
|
||||
|
||||
}
|
||||
elseif($invoice->client->getSetting('auto_bill_date') == 'on_due_date' && $invoice->auto_bill_enabled) {
|
||||
@ -153,7 +153,7 @@ class SendRecurring implements ShouldQueue
|
||||
if($invoice->due_date && Carbon::parse($invoice->due_date)->startOfDay()->lte(now()->startOfDay())) {
|
||||
|
||||
nlog("attempting to autobill {$invoice->number}");
|
||||
$invoice->service()->autoBill()->save();
|
||||
$invoice->service()->autoBill();
|
||||
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,12 @@ class PaymentNotification implements ShouldQueue
|
||||
foreach ($payment->company->company_users as $company_user) {
|
||||
$user = $company_user->user;
|
||||
|
||||
$methods = $this->findUserEntityNotificationType($payment, $company_user, ['payment_success', 'payment_success_all', 'all_notifications']);
|
||||
$methods = $this->findUserEntityNotificationType($payment, $company_user, [
|
||||
'payment_success',
|
||||
'payment_success_all',
|
||||
'payment_success_user',
|
||||
'all_notifications']
|
||||
);
|
||||
|
||||
if (($key = array_search('mail', $methods)) !== false) {
|
||||
unset($methods[$key]);
|
||||
|
@ -69,6 +69,9 @@ class CreditEmailEngine extends BaseEmailEngine
|
||||
null,
|
||||
$this->client->locale()
|
||||
);
|
||||
|
||||
$body_template .= '<div class="center">$view_button</div>';
|
||||
|
||||
}
|
||||
|
||||
if (is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) {
|
||||
|
@ -74,6 +74,9 @@ class InvoiceEmailEngine extends BaseEmailEngine
|
||||
null,
|
||||
$this->client->locale()
|
||||
);
|
||||
|
||||
$body_template .= '<div class="center">$view_button</div>';
|
||||
|
||||
}
|
||||
|
||||
if (is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) {
|
||||
|
@ -44,6 +44,7 @@ class QuoteEmailEngine extends BaseEmailEngine
|
||||
|
||||
public function build()
|
||||
{
|
||||
|
||||
App::forgetInstance('translator');
|
||||
$t = app('translator');
|
||||
$t->replace(Ninja::transformTranslations($this->client->getMergedSettings()));
|
||||
@ -59,18 +60,22 @@ class QuoteEmailEngine extends BaseEmailEngine
|
||||
|
||||
/* Use default translations if a custom message has not been set*/
|
||||
if (iconv_strlen($body_template) == 0) {
|
||||
|
||||
$body_template = trans(
|
||||
'texts.quote_message',
|
||||
[
|
||||
'quote' => $this->quote->number,
|
||||
'company' => $this->quote->company->present()->name(),
|
||||
'amount' => Number::formatMoney($this->quote->balance, $this->client),
|
||||
'amount' => Number::formatMoney($this->quote->amount, $this->client),
|
||||
],
|
||||
null,
|
||||
$this->client->locale()
|
||||
);
|
||||
|
||||
$body_template .= '<div class="center">$view_button</div>';
|
||||
}
|
||||
|
||||
|
||||
if (is_array($this->template_data) && array_key_exists('subject', $this->template_data) && strlen($this->template_data['subject']) > 0) {
|
||||
$subject_template = $this->template_data['subject'];
|
||||
} else {
|
||||
@ -99,7 +104,6 @@ class QuoteEmailEngine extends BaseEmailEngine
|
||||
->setViewText(ctrans('texts.view_quote'))
|
||||
->setInvitation($this->invitation);
|
||||
|
||||
|
||||
if ($this->client->getSetting('pdf_email_attachment') !== false && $this->quote->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
|
||||
|
||||
if(Ninja::isHosted())
|
||||
|
@ -52,6 +52,7 @@ class TemplateEmail extends Mailable
|
||||
|
||||
public function build()
|
||||
{
|
||||
|
||||
$template_name = 'email.template.'.$this->build_email->getTemplate();
|
||||
|
||||
if ($this->build_email->getTemplate() == 'light' || $this->build_email->getTemplate() == 'dark') {
|
||||
|
@ -75,6 +75,7 @@ class Quote extends BaseModel
|
||||
'assigned_user_id',
|
||||
'exchange_rate',
|
||||
'subscription_id',
|
||||
'uses_inclusive_taxes',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
|
@ -30,6 +30,7 @@ use App\Models\GatewayType;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\PaymentType;
|
||||
use App\Models\SystemLog;
|
||||
use App\Services\Subscription\SubscriptionService;
|
||||
use App\Utils\Ninja;
|
||||
@ -262,12 +263,18 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
|
||||
event('eloquent.created: App\Models\Payment', $payment);
|
||||
|
||||
if ($this->client->getSetting('client_online_payment_notification'))
|
||||
if ($this->client->getSetting('client_online_payment_notification') && in_array($status, [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING
|
||||
]))
|
||||
$payment->service()->sendEmail();
|
||||
|
||||
//todo
|
||||
//catch any payment failures here also and fire a subsequent failure email if necessary? note only need for delayed payment forms
|
||||
//perhaps this type of functionality should be handled higher up to provide better context?
|
||||
|
||||
|
||||
event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars()));
|
||||
|
||||
if (property_exists($this->payment_hash->data, 'billing_context')) {
|
||||
if (property_exists($this->payment_hash->data, 'billing_context') && $status == Payment::STATUS_COMPLETED) {
|
||||
$billing_subscription = \App\Models\Subscription::find($this->payment_hash->data->billing_context->subscription_id);
|
||||
|
||||
// To access campaign hash => $this->payment_hash->data->billing_context->campaign;
|
||||
@ -440,7 +447,7 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
|
||||
$invoices->first()->invitations->each(function ($invitation) use ($nmo) {
|
||||
|
||||
if ($invitation->contact->email) {
|
||||
if ((bool)$invitation->contact->send_email !== false && $invitation->contact->email) {
|
||||
|
||||
$nmo->to_user = $invitation->contact;
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
|
@ -161,7 +161,8 @@ class PayPal
|
||||
SystemLog::CATEGORY_GATEWAY_RESPONSE,
|
||||
SystemLog::EVENT_GATEWAY_FAILURE,
|
||||
SystemLog::TYPE_BRAINTREE,
|
||||
$this->braintree->client
|
||||
$this->braintree->client,
|
||||
$this->braintree->client->company
|
||||
);
|
||||
|
||||
throw new PaymentFailed($response->message, 0);
|
||||
|
@ -213,10 +213,10 @@ class CreditCard implements MethodInterface
|
||||
if ($response->status == 'Declined') {
|
||||
$this->checkout->unWindGatewayFees($this->checkout->payment_hash);
|
||||
|
||||
$this->checkout->sendFailureMail($response->response_summary);
|
||||
// $this->checkout->sendFailureMail($response->response_summary);
|
||||
|
||||
//@todo - this will double up the checkout . com failed mails
|
||||
$this->checkout->clientPaymentFailureMailer($response->status);
|
||||
// $this->checkout->clientPaymentFailureMailer($response->status);
|
||||
|
||||
return $this->processUnsuccessfulPayment($response);
|
||||
}
|
||||
|
@ -84,7 +84,8 @@ trait Utilities
|
||||
|
||||
public function processUnsuccessfulPayment(Payment $_payment, $throw_exception = true)
|
||||
{
|
||||
$this->getParent()->sendFailureMail($_payment->status . " " . optional($_payment)->response_summary);
|
||||
$this->getParent()->sendFailureMail($_payment->response_summary);
|
||||
// $this->getParent()->clientPaymentFailureMailer($_payment->status);
|
||||
|
||||
$message = [
|
||||
'server_response' => $_payment,
|
||||
|
@ -160,11 +160,11 @@ class ACH implements MethodInterface
|
||||
*/
|
||||
public function paymentResponse(PaymentResponseRequest $request)
|
||||
{
|
||||
$token = ClientGatewayToken::find(
|
||||
$this->decodePrimaryKey($request->source)
|
||||
)->firstOrFail();
|
||||
// $token = ClientGatewayToken::find(
|
||||
// $this->decodePrimaryKey($request->source)
|
||||
// )->firstOrFail();
|
||||
|
||||
$this->go_cardless->ensureMandateIsReady($token);
|
||||
$this->go_cardless->ensureMandateIsReady($request->source);
|
||||
|
||||
try {
|
||||
$payment = $this->go_cardless->gateway->payments()->create([
|
||||
@ -175,7 +175,7 @@ class ACH implements MethodInterface
|
||||
'payment_hash' => $this->go_cardless->payment_hash->hash,
|
||||
],
|
||||
'links' => [
|
||||
'mandate' => $token->token,
|
||||
'mandate' => $request->source,
|
||||
],
|
||||
],
|
||||
]);
|
||||
@ -201,7 +201,6 @@ class ACH implements MethodInterface
|
||||
public function processPendingPayment(\GoCardlessPro\Resources\Payment $payment, array $data = [])
|
||||
{
|
||||
$data = [
|
||||
'payment_method' => $data['token'],
|
||||
'payment_type' => PaymentType::ACH,
|
||||
'amount' => $this->go_cardless->payment_hash->data->amount_with_fee,
|
||||
'transaction_reference' => $payment->id,
|
||||
|
@ -152,11 +152,8 @@ class DirectDebit implements MethodInterface
|
||||
|
||||
public function paymentResponse(PaymentResponseRequest $request)
|
||||
{
|
||||
$token = ClientGatewayToken::find(
|
||||
$this->decodePrimaryKey($request->source)
|
||||
)->firstOrFail();
|
||||
|
||||
$this->go_cardless->ensureMandateIsReady($token);
|
||||
$this->go_cardless->ensureMandateIsReady($request->source);
|
||||
|
||||
try {
|
||||
$payment = $this->go_cardless->gateway->payments()->create([
|
||||
@ -167,14 +164,14 @@ class DirectDebit implements MethodInterface
|
||||
'payment_hash' => $this->go_cardless->payment_hash->hash,
|
||||
],
|
||||
'links' => [
|
||||
'mandate' => $token->token,
|
||||
'mandate' => $request->source,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
|
||||
if ($payment->status === 'pending_submission') {
|
||||
return $this->processPendingPayment($payment, ['token' => $token->hashed_id]);
|
||||
return $this->processPendingPayment($payment, ['token' => $request->source]);
|
||||
}
|
||||
|
||||
return $this->processUnsuccessfulPayment($payment);
|
||||
@ -193,7 +190,6 @@ class DirectDebit implements MethodInterface
|
||||
public function processPendingPayment(\GoCardlessPro\Resources\Payment $payment, array $data = [])
|
||||
{
|
||||
$data = [
|
||||
'payment_method' => $data['token'],
|
||||
'payment_type' => PaymentType::DIRECT_DEBIT,
|
||||
'amount' => $this->go_cardless->payment_hash->data->amount_with_fee,
|
||||
'transaction_reference' => $payment->id,
|
||||
|
@ -160,11 +160,7 @@ class SEPA implements MethodInterface
|
||||
*/
|
||||
public function paymentResponse(PaymentResponseRequest $request)
|
||||
{
|
||||
$token = ClientGatewayToken::find(
|
||||
$this->decodePrimaryKey($request->source)
|
||||
)->firstOrFail();
|
||||
|
||||
$this->go_cardless->ensureMandateIsReady($token);
|
||||
$this->go_cardless->ensureMandateIsReady($request->source);
|
||||
|
||||
try {
|
||||
$payment = $this->go_cardless->gateway->payments()->create([
|
||||
@ -175,13 +171,13 @@ class SEPA implements MethodInterface
|
||||
'payment_hash' => $this->go_cardless->payment_hash->hash,
|
||||
],
|
||||
'links' => [
|
||||
'mandate' => $token->token,
|
||||
'mandate' => $request->source,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
if ($payment->status === 'pending_submission') {
|
||||
return $this->processPendingPayment($payment, ['token' => $token->hashed_id]);
|
||||
return $this->processPendingPayment($payment, ['token' => $request->source]);
|
||||
}
|
||||
|
||||
return $this->processUnsuccessfulPayment($payment);
|
||||
@ -200,7 +196,6 @@ class SEPA implements MethodInterface
|
||||
public function processPendingPayment(\GoCardlessPro\Resources\Payment $payment, array $data = [])
|
||||
{
|
||||
$data = [
|
||||
'payment_method' => $data['token'],
|
||||
'payment_type' => PaymentType::SEPA,
|
||||
'amount' => $this->go_cardless->payment_hash->data->amount_with_fee,
|
||||
'transaction_reference' => $payment->id,
|
||||
|
@ -265,10 +265,11 @@ class GoCardlessPaymentDriver extends BaseDriver
|
||||
return response()->json([], 200);
|
||||
}
|
||||
|
||||
public function ensureMandateIsReady(ClientGatewayToken $cgt)
|
||||
public function ensureMandateIsReady($token)
|
||||
{
|
||||
try {
|
||||
$mandate = $this->gateway->mandates()->get($cgt->token);
|
||||
$this->init();
|
||||
$mandate = $this->gateway->mandates()->get($token);
|
||||
|
||||
if ($mandate->status !== 'active') {
|
||||
throw new \Exception(ctrans('texts.gocardless_mandate_not_ready'));
|
||||
|
@ -86,7 +86,9 @@ class Bancontact implements MethodInterface
|
||||
'webhookUrl' => $this->mollie->company_gateway->webhookUrl(),
|
||||
'metadata' => [
|
||||
'client_id' => $this->mollie->client->hashed_id,
|
||||
'hash' => $this->mollie->payment_hash->hash
|
||||
'hash' => $this->mollie->payment_hash->hash,
|
||||
'gateway_type_id' => GatewayType::BANCONTACT,
|
||||
'payment_type_id' => PaymentType::BANCONTACT,
|
||||
],
|
||||
]);
|
||||
|
||||
|
@ -89,7 +89,9 @@ class BankTransfer implements MethodInterface
|
||||
'webhookUrl' => $this->mollie->company_gateway->webhookUrl(),
|
||||
'metadata' => [
|
||||
'client_id' => $this->mollie->client->hashed_id,
|
||||
'hash' => $this->mollie->payment_hash->hash
|
||||
'hash' => $this->mollie->payment_hash->hash,
|
||||
'gateway_type_id' => GatewayType::BANK_TRANSFER,
|
||||
'payment_type_id' => PaymentType::MOLLIE_BANK_TRANSFER,
|
||||
],
|
||||
]);
|
||||
|
||||
|
@ -114,7 +114,7 @@ class CreditCard
|
||||
'name' => $this->mollie->client->name,
|
||||
'email' => $this->mollie->client->present()->email(),
|
||||
'metadata' => [
|
||||
'id' => $this->mollie->client->hashed_id,
|
||||
'id' => $this->mollie->client->hashed_id
|
||||
],
|
||||
]);
|
||||
|
||||
|
@ -86,7 +86,9 @@ class IDEAL implements MethodInterface
|
||||
'webhookUrl' => $this->mollie->company_gateway->webhookUrl(),
|
||||
'metadata' => [
|
||||
'client_id' => $this->mollie->client->hashed_id,
|
||||
'hash' => $this->mollie->payment_hash->hash
|
||||
'hash' => $this->mollie->payment_hash->hash,
|
||||
'gateway_type_id' => GatewayType::IDEAL,
|
||||
'payment_type_id' => PaymentType::IDEAL,
|
||||
],
|
||||
]);
|
||||
|
||||
|
@ -86,7 +86,9 @@ class KBC implements MethodInterface
|
||||
'webhookUrl' => $this->mollie->company_gateway->webhookUrl(),
|
||||
'metadata' => [
|
||||
'client_id' => $this->mollie->client->hashed_id,
|
||||
'hash' => $this->mollie->payment_hash->hash
|
||||
'hash' => $this->mollie->payment_hash->hash,
|
||||
'gateway_type_id' => GatewayType::KBC,
|
||||
'payment_type_id' => PaymentType::KBC,
|
||||
],
|
||||
]);
|
||||
|
||||
|
@ -312,10 +312,31 @@ class MolliePaymentDriver extends BaseDriver
|
||||
$client = $record->client;
|
||||
}
|
||||
else{
|
||||
nlog("mollie webhook");
|
||||
nlog($payment);
|
||||
|
||||
$client = Client::withTrashed()->find($this->decodePrimaryKey($payment->metadata->client_id));
|
||||
|
||||
// sometimes if the user is not returned to the site with a response from Mollie
|
||||
// we may not have a payment record - in these cases we need to re-construct the payment
|
||||
// record from the meta data in the payment hash.
|
||||
|
||||
if($payment && property_exists($payment->metadata, 'payment_hash') && $payment->metadata->payment_hash){
|
||||
|
||||
/* Harvest Payment Hash*/
|
||||
$payment_hash = PaymentHash::where('hash', $payment->metadata->hash)->first();
|
||||
|
||||
$data = [
|
||||
'gateway_type_id' => $payment->metadata->gateway_type_id,
|
||||
'amount' => $amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total,
|
||||
'payment_type' => $payment->metadata->payment_type_id,
|
||||
'transaction_reference' => $payment->id,
|
||||
];
|
||||
|
||||
$record = $this->createPayment(
|
||||
$data,
|
||||
$codes[$payment->status]
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$message = [
|
||||
|
@ -136,6 +136,7 @@ class SquarePaymentDriver extends BaseDriver
|
||||
$amount_money->setCurrency($this->client->currency()->code);
|
||||
|
||||
$body = new \Square\Models\CreatePaymentRequest($cgt->token, \Illuminate\Support\Str::random(32), $amount_money);
|
||||
$body->setCustomerId($cgt->gateway_customer_reference);
|
||||
|
||||
/** @var ApiResponse */
|
||||
$response = $this->square->getPaymentsApi()->createPayment($body);
|
||||
|
@ -56,7 +56,6 @@ class Charge
|
||||
if($cgt->gateway_type_id == GatewayType::BANK_TRANSFER)
|
||||
return (new ACH($this->stripe))->tokenBilling($cgt, $payment_hash);
|
||||
|
||||
nlog(" DB = ".$this->stripe->client->company->db);
|
||||
$amount = array_sum(array_column($payment_hash->invoices(), 'amount')) + $payment_hash->fee_total;
|
||||
$invoice = Invoice::whereIn('id', $this->transformKeys(array_column($payment_hash->invoices(), 'invoice_id')))->withTrashed()->first();
|
||||
|
||||
@ -120,7 +119,6 @@ class Charge
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$this->stripe->processInternallyFailedPayment($this->stripe, $e);
|
||||
|
||||
SystemLogger::dispatch($data, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_STRIPE, $this->stripe->client, $this->stripe->client->company);
|
||||
|
@ -123,7 +123,7 @@ class CreditCard
|
||||
|
||||
$data = [
|
||||
'payment_method' => $this->stripe->payment_hash->data->server_response->payment_method,
|
||||
'payment_type' => PaymentType::parseCardType(strtolower($stripe_method->card->brand)),
|
||||
'payment_type' => PaymentType::parseCardType(strtolower($stripe_method->card->brand)) ?: PaymentType::CREDIT_CARD_OTHER,
|
||||
'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->server_response->amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency()),
|
||||
'transaction_reference' => optional($this->stripe->payment_hash->data->payment_intent->charges->data[0])->id,
|
||||
'gateway_type_id' => GatewayType::CREDIT_CARD,
|
||||
|
@ -436,7 +436,7 @@ class StripePaymentDriver extends BaseDriver
|
||||
|
||||
//Else create a new record
|
||||
$data['name'] = $this->client->present()->name();
|
||||
$data['phone'] = $this->client->present()->phone();
|
||||
$data['phone'] = substr($this->client->present()->phone(), 0 , 20);
|
||||
|
||||
if (filter_var($this->client->present()->email(), FILTER_VALIDATE_EMAIL)) {
|
||||
$data['email'] = $this->client->present()->email();
|
||||
|
@ -54,6 +54,37 @@ class TaskRepository extends BaseRepository
|
||||
$task->status_order = $data['status_order'];
|
||||
}
|
||||
|
||||
/*V4 override*/
|
||||
if (! empty($data['time_details'])) {
|
||||
$timeLog = [];
|
||||
foreach ($data['time_details'] as $detail) {
|
||||
$startTime = strtotime($detail['start_datetime']);
|
||||
$endTime = false;
|
||||
if (! empty($detail['end_datetime'])) {
|
||||
$endTime = strtotime($detail['end_datetime']);
|
||||
} else {
|
||||
$duration = 0;
|
||||
if (! empty($detail['duration_seconds'])) {
|
||||
$duration += $detail['duration_seconds'];
|
||||
}
|
||||
if (! empty($detail['duration_minutes'])) {
|
||||
$duration += $detail['duration_minutes'] * 60;
|
||||
}
|
||||
if (! empty($detail['duration_hours'])) {
|
||||
$duration += $detail['duration_hours'] * 60 * 60;
|
||||
}
|
||||
if ($duration) {
|
||||
$endTime = $startTime + $duration;
|
||||
}
|
||||
}
|
||||
$timeLog[] = [$startTime, $endTime];
|
||||
if (! $endTime) {
|
||||
$data['is_running'] = true;
|
||||
}
|
||||
}
|
||||
$data['time_log'] = json_encode($timeLog);
|
||||
}
|
||||
|
||||
if (isset($data['time_log'])) {
|
||||
$time_log = json_decode($data['time_log']);
|
||||
} elseif ($task->time_log) {
|
||||
|
@ -30,6 +30,7 @@ use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\Traits\Pdf\PdfMaker as PdfMakerTrait;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
|
||||
class Statement
|
||||
{
|
||||
@ -217,7 +218,7 @@ class Statement
|
||||
*
|
||||
* @return Invoice[]|\Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
protected function getInvoices(): Collection
|
||||
protected function getInvoices(): LazyCollection
|
||||
{
|
||||
return Invoice::withTrashed()
|
||||
->where('is_deleted', false)
|
||||
@ -226,7 +227,7 @@ class Statement
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL, Invoice::STATUS_PAID])
|
||||
->whereBetween('date', [$this->options['start_date'], $this->options['end_date']])
|
||||
->orderBy('number', 'ASC')
|
||||
->get();
|
||||
->cursor();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -234,7 +235,7 @@ class Statement
|
||||
*
|
||||
* @return Payment[]|\Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
protected function getPayments(): Collection
|
||||
protected function getPayments(): LazyCollection
|
||||
{
|
||||
return Payment::withTrashed()
|
||||
->with('client.country','invoices')
|
||||
@ -244,7 +245,7 @@ class Statement
|
||||
->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
||||
->whereBetween('date', [$this->options['start_date'], $this->options['end_date']])
|
||||
->orderBy('number', 'ASC')
|
||||
->get();
|
||||
->cursor();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,17 +36,6 @@ class TriggeredActions extends AbstractService
|
||||
|
||||
public function run()
|
||||
{
|
||||
// if ($this->request->has('auto_bill') && $this->request->input('auto_bill') == 'true') {
|
||||
// $this->credit = $this->credit->service()->autoBill()->save();
|
||||
// }
|
||||
|
||||
// if ($this->request->has('paid') && $this->request->input('paid') == 'true') {
|
||||
// $this->credit = $this->credit->service()->markPaid()->save();
|
||||
// }
|
||||
|
||||
// if ($this->request->has('amount_paid') && is_numeric($this->request->input('amount_paid')) ) {
|
||||
// $this->credit = $this->credit->service()->applyPaymentAmount($this->request->input('amount_paid'))->save();
|
||||
// }
|
||||
|
||||
if ($this->request->has('send_email') && $this->request->input('send_email') == 'true') {
|
||||
$this->sendEmail();
|
||||
|
@ -105,7 +105,7 @@ class AddGatewayFee extends AbstractService
|
||||
$invoice_item->quantity = 1;
|
||||
$invoice_item->cost = $gateway_fee;
|
||||
|
||||
if ($fees_and_limits = $this->company_gateway->getFeesAndLimits()) {
|
||||
if ($fees_and_limits = $this->company_gateway->getFeesAndLimits($this->gateway_type_id)) {
|
||||
$invoice_item->tax_rate1 = $fees_and_limits->fee_tax_rate1;
|
||||
$invoice_item->tax_rate2 = $fees_and_limits->fee_tax_rate2;
|
||||
$invoice_item->tax_rate3 = $fees_and_limits->fee_tax_rate3;
|
||||
|
@ -130,7 +130,7 @@ class AutoBillInvoice extends AbstractService
|
||||
info("Auto Bill payment captured for ".$this->invoice->number);
|
||||
}
|
||||
|
||||
return $this->invoice->fresh();
|
||||
// return $this->invoice->fresh();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +138,8 @@ class InvoiceService
|
||||
{
|
||||
// $this->invoice = (new UpdateBalance($this->invoice, $balance_adjustment, $is_draft))->run();
|
||||
|
||||
if ($this->invoice->is_deleted) {
|
||||
if ((bool)$this->invoice->is_deleted !== false) {
|
||||
nlog($this->invoice->number . " is deleted returning");
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -245,7 +246,7 @@ class InvoiceService
|
||||
|
||||
public function autoBill()
|
||||
{
|
||||
$this->invoice = (new AutoBillInvoice($this->invoice, $this->invoice->company->db))->run();
|
||||
(new AutoBillInvoice($this->invoice, $this->invoice->company->db))->run();
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -483,6 +484,10 @@ class InvoiceService
|
||||
if(!isset($this->invoice->exchange_rate) && $this->invoice->client->currency()->id != (int) $this->invoice->company->settings->currency_id)
|
||||
$this->invoice->exchange_rate = $this->invoice->client->currency()->exchange_rate;
|
||||
|
||||
if($settings->counter_number_applied == 'when_saved'){
|
||||
$this->invoice->service()->applyNumber()->save();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ class TriggeredActions extends AbstractService
|
||||
public function run()
|
||||
{
|
||||
if ($this->request->has('auto_bill') && $this->request->input('auto_bill') == 'true') {
|
||||
$this->invoice = $this->invoice->service()->autoBill()->save();
|
||||
$this->invoice->service()->autoBill();
|
||||
}
|
||||
|
||||
if ($this->request->has('paid') && $this->request->input('paid') == 'true') {
|
||||
|
@ -124,10 +124,10 @@ class QuoteService
|
||||
}
|
||||
|
||||
|
||||
if ($this->quote->client->getSetting('auto_archive_quote')) {
|
||||
$quote_repo = new QuoteRepository();
|
||||
$quote_repo->archive($this->quote);
|
||||
}
|
||||
// if ($this->quote->client->getSetting('auto_archive_quote')) {
|
||||
// $quote_repo = new QuoteRepository();
|
||||
// $quote_repo->archive($this->quote);
|
||||
// }
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class TriggeredActions extends AbstractService
|
||||
{
|
||||
|
||||
$reminder_template = $this->quote->calculateTemplate('quote');
|
||||
//$reminder_template = 'payment';
|
||||
// $reminder_template = 'email_template_quote';
|
||||
|
||||
$this->quote->invitations->load('contact.client.country', 'quote.client.country', 'quote.company')->each(function ($invitation) use ($reminder_template) {
|
||||
EmailEntity::dispatch($invitation, $this->quote->company, $reminder_template);
|
||||
|
@ -77,8 +77,6 @@ class SubscriptionService
|
||||
$recurring_invoice_repo = new RecurringInvoiceRepository();
|
||||
|
||||
$recurring_invoice = $recurring_invoice_repo->save([], $recurring_invoice);
|
||||
// $recurring_invoice->next_send_date = now()->format('Y-m-d');
|
||||
// $recurring_invoice->next_send_date = $recurring_invoice->nextSendDate();
|
||||
$recurring_invoice->auto_bill = $this->subscription->auto_bill;
|
||||
|
||||
/* Start the recurring service */
|
||||
@ -87,7 +85,6 @@ class SubscriptionService
|
||||
->save();
|
||||
|
||||
//execute any webhooks
|
||||
|
||||
$context = [
|
||||
'context' => 'recurring_purchase',
|
||||
'recurring_invoice' => $recurring_invoice->hashed_id,
|
||||
@ -95,6 +92,7 @@ class SubscriptionService
|
||||
'client' => $recurring_invoice->client->hashed_id,
|
||||
'subscription' => $this->subscription->hashed_id,
|
||||
'contact' => auth('contact')->user()->hashed_id,
|
||||
'account_key' => $recurring_invoice->client->custom_value2,
|
||||
];
|
||||
|
||||
$response = $this->triggerWebhook($context);
|
||||
@ -111,6 +109,7 @@ class SubscriptionService
|
||||
'invoice' => $this->encodePrimaryKey($payment_hash->fee_invoice_id),
|
||||
'client' => $invoice->client->hashed_id,
|
||||
'subscription' => $this->subscription->hashed_id,
|
||||
'account_key' => $invoice->client->custom_value2,
|
||||
];
|
||||
|
||||
//execute any webhooks
|
||||
@ -130,6 +129,7 @@ class SubscriptionService
|
||||
'contact' => $contact->hashed_id,
|
||||
'contact_email' => $contact->email,
|
||||
'client' => $contact->client->hashed_id,
|
||||
'account_key' => $contact->client->custom_value2,
|
||||
];
|
||||
|
||||
$response = $this->triggerWebhook($context);
|
||||
@ -180,6 +180,7 @@ class SubscriptionService
|
||||
'recurring_invoice' => $recurring_invoice->hashed_id,
|
||||
'client' => $recurring_invoice->client->hashed_id,
|
||||
'subscription' => $this->subscription->hashed_id,
|
||||
'account_key' => $recurring_invoice->client->custom_value2,
|
||||
];
|
||||
|
||||
//execute any webhooks
|
||||
@ -452,6 +453,7 @@ class SubscriptionService
|
||||
'client' => $new_recurring_invoice->client->hashed_id,
|
||||
'subscription' => $target_subscription->hashed_id,
|
||||
'contact' => auth('contact')->user()->hashed_id,
|
||||
'account_key' => $new_recurring_invoice->client->custom_value2,
|
||||
];
|
||||
|
||||
$response = $this->triggerWebhook($context);
|
||||
@ -572,6 +574,7 @@ class SubscriptionService
|
||||
'client' => $recurring_invoice->client->hashed_id,
|
||||
'subscription' => $this->subscription->hashed_id,
|
||||
'contact' => auth('contact')->user()->hashed_id,
|
||||
'account_key' => $recurring_invoice->client->custom_value2,
|
||||
];
|
||||
|
||||
|
||||
@ -768,8 +771,6 @@ class SubscriptionService
|
||||
$response = false;
|
||||
|
||||
$body = array_merge($context, [
|
||||
'company_key' => $this->subscription->company->company_key,
|
||||
'account_key' => $this->subscription->company->account->key,
|
||||
'db' => $this->subscription->company->db,
|
||||
]);
|
||||
|
||||
@ -921,6 +922,7 @@ class SubscriptionService
|
||||
'recurring_invoice' => $recurring_invoice->hashed_id,
|
||||
'client' => $recurring_invoice->client->hashed_id,
|
||||
'contact' => auth('contact')->user()->hashed_id,
|
||||
'account_key' => $recurring_invoice->client->custom_value2,
|
||||
];
|
||||
|
||||
$this->triggerWebhook($context);
|
||||
@ -1043,6 +1045,7 @@ class SubscriptionService
|
||||
'client' => $invoice->client->hashed_id,
|
||||
'contact' => $invoice->client->primary_contact()->first() ? $invoice->client->primary_contact()->first()->hashed_id: $invoice->client->contacts->first()->hashed_id,
|
||||
'invoice' => $invoice->hashed_id,
|
||||
'account_key' => $invoice->client->custom_value2,
|
||||
];
|
||||
|
||||
$response = $this->triggerWebhook($context);
|
||||
|
@ -11,6 +11,12 @@
|
||||
|
||||
namespace App\Utils\Traits\Notifications;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Quote;
|
||||
|
||||
/**
|
||||
* Class UserNotifies.
|
||||
*
|
||||
@ -22,53 +28,100 @@ trait UserNotifies
|
||||
{
|
||||
public function findUserNotificationTypes($invitation, $company_user, $entity_name, $required_permissions) :array
|
||||
{
|
||||
if ($company_user->company->is_disabled) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$notifiable_methods = [];
|
||||
$notifications = $company_user->notifications;
|
||||
|
||||
if ($company_user->company->is_disabled && is_array($notifications->email)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
//if a user owns this record or is assigned to it, they are attached the permission for notification.
|
||||
if ($invitation->{$entity_name}->user_id == $company_user->_user_id || $invitation->{$entity_name}->assigned_user_id == $company_user->user_id) {
|
||||
array_push($required_permissions, 'all_user_notifications');
|
||||
$required_permissions = $this->addSpecialUserPermissionForEntity($invitation->{$entity_name}, $required_permissions);
|
||||
}
|
||||
else{
|
||||
$required_permissions = $this->removeSpecialUserPermissionForEntity($invitation->{$entity_name}, $required_permissions);
|
||||
}
|
||||
|
||||
if (count(array_intersect($required_permissions, $notifications->email)) >= 1 || count(array_intersect(['all_user_notifications'], $notifications->email)) >= 1 || count(array_intersect(['all_notifications'],$notifications->email)) >= 1) {
|
||||
if (count(array_intersect($required_permissions, $notifications->email)) >= 1) {
|
||||
array_push($notifiable_methods, 'mail');
|
||||
}
|
||||
|
||||
// if(count(array_intersect($required_permissions, $notifications->slack)) >=1)
|
||||
// array_push($notifiable_methods, 'slack');
|
||||
|
||||
return $notifiable_methods;
|
||||
}
|
||||
|
||||
public function findUserEntityNotificationType($entity, $company_user, $required_permissions) :array
|
||||
public function findUserEntityNotificationType($entity, $company_user, array $required_permissions) :array
|
||||
{
|
||||
if ($company_user->company->is_disabled) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$notifiable_methods = [];
|
||||
$notifications = $company_user->notifications;
|
||||
|
||||
if (! $notifications) {
|
||||
if ($company_user->company->is_disabled || ! $notifications) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($entity->user_id == $company_user->_user_id || $entity->assigned_user_id == $company_user->user_id) {
|
||||
array_push($required_permissions, 'all_user_notifications');
|
||||
$required_permissions = $this->addSpecialUserPermissionForEntity($entity, $required_permissions);
|
||||
}
|
||||
else{
|
||||
$required_permissions = $this->removeSpecialUserPermissionForEntity($entity, $required_permissions);
|
||||
}
|
||||
|
||||
if (count(array_intersect($required_permissions, $notifications->email)) >= 1 || count(array_intersect(['all_user_notifications'], $notifications->email)) >= 1 || count(array_intersect(['all_notifications'],$notifications->email)) >= 1) {
|
||||
if (count(array_intersect($required_permissions, $notifications->email)) >= 1) {
|
||||
array_push($notifiable_methods, 'mail');
|
||||
}
|
||||
|
||||
|
||||
return $notifiable_methods;
|
||||
}
|
||||
|
||||
private function addSpecialUserPermissionForEntity($entity, array $required_permissions) :array
|
||||
{
|
||||
|
||||
array_merge($required_permissions, ["all_notifications"]);
|
||||
|
||||
switch ($entity) {
|
||||
case ($entity instanceof Payment || $entity instanceof Client): //we pass client also as this is the proxy for Payment Failures (ie, there is no payment)
|
||||
return array_merge($required_permissions, ["all_notifications","all_user_notifications","payment_failure_user","payment_success_user"]);
|
||||
break;
|
||||
case ($entity instanceof Invoice):
|
||||
return array_merge($required_permissions, ["all_notifications","all_user_notifications","invoice_created_user","invoice_sent_user","invoice_viewed_user","invoice_late_user"]);
|
||||
break;
|
||||
case ($entity instanceof Quote):
|
||||
return array_merge($required_permissions, ["all_notifications","all_user_notifications","quote_created_user","quote_sent_user","quote_viewed_user","quote_approved_user","quote_expired_user"]);
|
||||
break;
|
||||
case ($entity instanceof Credit):
|
||||
return array_merge($required_permissions, ["all_notifications","all_user_notifications","credit_created_user","credit_sent_user","credit_viewed_user"]);
|
||||
break;
|
||||
default:
|
||||
return [];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function removeSpecialUserPermissionForEntity($entity, $required_permissions)
|
||||
{
|
||||
array_merge($required_permissions, ["all_notifications"]);
|
||||
|
||||
switch ($entity) {
|
||||
case ($entity instanceof Payment || $entity instanceof Client): //we pass client also as this is the proxy for Payment Failures (ie, there is no payment)
|
||||
return array_diff($required_permissions, ["all_user_notifications","payment_failure_user","payment_success_user"]);
|
||||
break;
|
||||
case ($entity instanceof Invoice):
|
||||
return array_diff($required_permissions, ["all_user_notifications","invoice_created_user","invoice_sent_user","invoice_viewed_user","invoice_late_user"]);
|
||||
break;
|
||||
case ($entity instanceof Quote):
|
||||
return array_diff($required_permissions, ["all_user_notifications","quote_created_user","quote_sent_user","quote_viewed_user","quote_approved_user","quote_expired_user"]);
|
||||
break;
|
||||
case ($entity instanceof Credit):
|
||||
return array_diff($required_permissions, ["all_user_notifications","credit_created_user","credit_sent_user","credit_viewed_user"]);
|
||||
break;
|
||||
default:
|
||||
// code...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function findCompanyUserNotificationType($company_user, $required_permissions) :array
|
||||
{
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
],
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": "^7.4|^8.0",
|
||||
"php": "^7.4|^8",
|
||||
"ext-dom": "*",
|
||||
"ext-json": "*",
|
||||
"ext-libxml": "*",
|
||||
|
715
composer.lock
generated
715
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -14,8 +14,8 @@ return [
|
||||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||
'app_version' => '5.3.33',
|
||||
'app_tag' => '5.3.33',
|
||||
'app_version' => '5.3.34',
|
||||
'app_tag' => '5.3.34',
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'api_secret' => env('API_SECRET', ''),
|
||||
|
@ -34,6 +34,9 @@ CREATE TABLE `accounts` (
|
||||
`updated_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`is_scheduler_running` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`trial_duration` int(10) unsigned DEFAULT NULL,
|
||||
`is_onboarding` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`onboarding` mediumtext COLLATE utf8mb4_unicode_ci,
|
||||
`is_migrated` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `accounts_payment_id_index` (`payment_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
|
||||
@ -66,6 +69,8 @@ CREATE TABLE `activities` (
|
||||
`quote_id` int(10) unsigned DEFAULT NULL,
|
||||
`subscription_id` int(10) unsigned DEFAULT NULL,
|
||||
`recurring_invoice_id` int(10) unsigned DEFAULT NULL,
|
||||
`recurring_expense_id` int(10) unsigned DEFAULT NULL,
|
||||
`recurring_quote_id` int(10) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `activities_vendor_id_company_id_index` (`vendor_id`,`company_id`),
|
||||
KEY `activities_project_id_company_id_index` (`project_id`,`company_id`),
|
||||
@ -93,6 +98,7 @@ CREATE TABLE `backups` (
|
||||
`created_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`updated_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`amount` decimal(16,4) NOT NULL,
|
||||
`filename` text COLLATE utf8mb4_unicode_ci,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `backups_activity_id_foreign` (`activity_id`),
|
||||
CONSTRAINT `backups_activity_id_foreign` FOREIGN KEY (`activity_id`) REFERENCES `activities` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
@ -378,6 +384,7 @@ CREATE TABLE `companies` (
|
||||
`markdown_enabled` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`use_comma_as_decimal_place` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`report_include_drafts` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`client_registration_fields` mediumtext COLLATE utf8mb4_unicode_ci,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `companies_company_key_unique` (`company_key`),
|
||||
KEY `companies_industry_id_foreign` (`industry_id`),
|
||||
@ -1371,6 +1378,69 @@ CREATE TABLE `quotes` (
|
||||
CONSTRAINT `quotes_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `recurring_expenses`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `recurring_expenses` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`updated_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`company_id` int(10) unsigned NOT NULL,
|
||||
`vendor_id` int(10) unsigned DEFAULT NULL,
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`status_id` int(10) unsigned NOT NULL,
|
||||
`invoice_id` int(10) unsigned DEFAULT NULL,
|
||||
`client_id` int(10) unsigned DEFAULT NULL,
|
||||
`bank_id` int(10) unsigned DEFAULT NULL,
|
||||
`project_id` int(10) unsigned DEFAULT NULL,
|
||||
`payment_type_id` int(10) unsigned DEFAULT NULL,
|
||||
`recurring_expense_id` int(10) unsigned DEFAULT NULL,
|
||||
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`uses_inclusive_taxes` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`tax_name1` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`tax_name2` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`tax_name3` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`date` date DEFAULT NULL,
|
||||
`payment_date` date DEFAULT NULL,
|
||||
`should_be_invoiced` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`invoice_documents` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`transaction_id` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`custom_value1` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`custom_value2` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`custom_value3` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`custom_value4` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`category_id` int(10) unsigned DEFAULT NULL,
|
||||
`calculate_tax_by_amount` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`tax_amount1` decimal(20,6) DEFAULT NULL,
|
||||
`tax_amount2` decimal(20,6) DEFAULT NULL,
|
||||
`tax_amount3` decimal(20,6) DEFAULT NULL,
|
||||
`tax_rate1` decimal(20,6) DEFAULT NULL,
|
||||
`tax_rate2` decimal(20,6) DEFAULT NULL,
|
||||
`tax_rate3` decimal(20,6) DEFAULT NULL,
|
||||
`amount` decimal(20,6) DEFAULT NULL,
|
||||
`foreign_amount` decimal(20,6) DEFAULT NULL,
|
||||
`exchange_rate` decimal(20,6) NOT NULL DEFAULT '1.000000',
|
||||
`assigned_user_id` int(10) unsigned DEFAULT NULL,
|
||||
`number` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`invoice_currency_id` int(10) unsigned DEFAULT NULL,
|
||||
`currency_id` int(10) unsigned DEFAULT NULL,
|
||||
`private_notes` text COLLATE utf8mb4_unicode_ci,
|
||||
`public_notes` text COLLATE utf8mb4_unicode_ci,
|
||||
`transaction_reference` text COLLATE utf8mb4_unicode_ci,
|
||||
`frequency_id` int(10) unsigned NOT NULL,
|
||||
`last_sent_date` datetime DEFAULT NULL,
|
||||
`next_send_date` datetime DEFAULT NULL,
|
||||
`remaining_cycles` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `recurring_expenses_company_id_number_unique` (`company_id`,`number`),
|
||||
KEY `recurring_expenses_company_id_deleted_at_index` (`company_id`,`deleted_at`),
|
||||
KEY `recurring_expenses_user_id_foreign` (`user_id`),
|
||||
KEY `recurring_expenses_company_id_index` (`company_id`),
|
||||
CONSTRAINT `recurring_expenses_company_id_foreign` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `recurring_expenses_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `recurring_invoice_invitations`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
@ -1481,6 +1551,41 @@ CREATE TABLE `recurring_invoices` (
|
||||
CONSTRAINT `recurring_invoices_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `recurring_quote_invitations`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `recurring_quote_invitations` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`company_id` int(10) unsigned NOT NULL,
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`client_contact_id` int(10) unsigned NOT NULL,
|
||||
`recurring_quote_id` int(10) unsigned NOT NULL,
|
||||
`key` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||
`transaction_reference` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`message_id` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`email_error` mediumtext COLLATE utf8mb4_unicode_ci,
|
||||
`signature_base64` text COLLATE utf8mb4_unicode_ci,
|
||||
`signature_date` datetime DEFAULT NULL,
|
||||
`sent_date` datetime DEFAULT NULL,
|
||||
`viewed_date` datetime DEFAULT NULL,
|
||||
`opened_date` datetime DEFAULT NULL,
|
||||
`email_status` enum('delivered','bounced','spam') COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`created_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`updated_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`deleted_at` timestamp(6) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `cli_rec_q` (`client_contact_id`,`recurring_quote_id`),
|
||||
KEY `recurring_quote_invitations_user_id_foreign` (`user_id`),
|
||||
KEY `recurring_quote_invitations_company_id_foreign` (`company_id`),
|
||||
KEY `rec_co_del_q` (`deleted_at`,`recurring_quote_id`,`company_id`),
|
||||
KEY `recurring_quote_invitations_recurring_quote_id_index` (`recurring_quote_id`),
|
||||
KEY `recurring_quote_invitations_key_index` (`key`),
|
||||
CONSTRAINT `recurring_quote_invitations_client_contact_id_foreign` FOREIGN KEY (`client_contact_id`) REFERENCES `client_contacts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `recurring_quote_invitations_company_id_foreign` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `recurring_quote_invitations_recurring_quote_id_foreign` FOREIGN KEY (`recurring_quote_id`) REFERENCES `recurring_invoices` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `recurring_quote_invitations_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `recurring_quotes`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
@ -1521,13 +1626,29 @@ CREATE TABLE `recurring_quotes` (
|
||||
`balance` decimal(20,6) NOT NULL DEFAULT '0.000000',
|
||||
`last_viewed` datetime DEFAULT NULL,
|
||||
`frequency_id` int(10) unsigned NOT NULL,
|
||||
`start_date` date DEFAULT NULL,
|
||||
`last_sent_date` datetime DEFAULT NULL,
|
||||
`next_send_date` datetime DEFAULT NULL,
|
||||
`remaining_cycles` int(10) unsigned DEFAULT NULL,
|
||||
`created_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`updated_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`deleted_at` timestamp(6) NULL DEFAULT NULL,
|
||||
`auto_bill` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'off',
|
||||
`auto_bill_enabled` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`paid_to_date` decimal(20,6) NOT NULL DEFAULT '0.000000',
|
||||
`custom_surcharge1` decimal(20,6) DEFAULT NULL,
|
||||
`custom_surcharge2` decimal(20,6) DEFAULT NULL,
|
||||
`custom_surcharge3` decimal(20,6) DEFAULT NULL,
|
||||
`custom_surcharge4` decimal(20,6) DEFAULT NULL,
|
||||
`custom_surcharge_tax1` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`custom_surcharge_tax2` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`custom_surcharge_tax3` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`custom_surcharge_tax4` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`due_date_days` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
|
||||
`exchange_rate` decimal(13,6) NOT NULL DEFAULT '1.000000',
|
||||
`partial` decimal(16,4) DEFAULT NULL,
|
||||
`partial_due_date` date DEFAULT NULL,
|
||||
`subscription_id` int(10) unsigned DEFAULT NULL,
|
||||
`uses_inclusive_taxes` tinyint(1) NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `recurring_quotes_company_id_deleted_at_index` (`company_id`,`deleted_at`),
|
||||
KEY `recurring_quotes_user_id_foreign` (`user_id`),
|
||||
@ -1973,3 +2094,25 @@ INSERT INTO `migrations` VALUES (91,'2021_08_10_034407_add_more_languages',4);
|
||||
INSERT INTO `migrations` VALUES (92,'2021_08_18_220124_use_comma_as_decimal_place_companies_table',4);
|
||||
INSERT INTO `migrations` VALUES (93,'2021_08_24_115919_update_designs',4);
|
||||
INSERT INTO `migrations` VALUES (94,'2021_08_25_093105_report_include_drafts_in_companies_table',5);
|
||||
INSERT INTO `migrations` VALUES (95,'2021_08_14_054458_square_payment_driver',6);
|
||||
INSERT INTO `migrations` VALUES (96,'2021_08_23_101529_recurring_expenses_schema',6);
|
||||
INSERT INTO `migrations` VALUES (97,'2021_09_05_101209_update_braintree_gateway',6);
|
||||
INSERT INTO `migrations` VALUES (98,'2021_09_20_233053_set_square_test_mode_boolean',6);
|
||||
INSERT INTO `migrations` VALUES (99,'2021_09_23_100629_add_currencies',6);
|
||||
INSERT INTO `migrations` VALUES (100,'2021_09_24_201319_add_mollie_bank_transfer_to_payment_types',6);
|
||||
INSERT INTO `migrations` VALUES (101,'2021_09_24_211504_add_kbc_to_payment_types',6);
|
||||
INSERT INTO `migrations` VALUES (102,'2021_09_24_213858_add_bancontact_to_payment_types',6);
|
||||
INSERT INTO `migrations` VALUES (103,'2021_09_28_154647_activate_gocardless_payment_driver',6);
|
||||
INSERT INTO `migrations` VALUES (104,'2021_09_29_190258_add_required_client_registration_fields',6);
|
||||
INSERT INTO `migrations` VALUES (105,'2021_10_04_134908_add_ideal_to_payment_types',6);
|
||||
INSERT INTO `migrations` VALUES (106,'2021_10_06_044800_updated_bold_and_modern_designs',6);
|
||||
INSERT INTO `migrations` VALUES (107,'2021_10_07_141737_razorpay',6);
|
||||
INSERT INTO `migrations` VALUES (108,'2021_10_07_155410_add_hosted_page_to_payment_types',6);
|
||||
INSERT INTO `migrations` VALUES (109,'2021_10_15_00000_stripe_payment_gateways',6);
|
||||
INSERT INTO `migrations` VALUES (110,'2021_10_16_135200_add_direct_debit_to_payment_types',6);
|
||||
INSERT INTO `migrations` VALUES (111,'2021_10_19_142200_add_gateway_type_for_direct_debit',6);
|
||||
INSERT INTO `migrations` VALUES (112,'2021_10_20_005529_add_filename_to_backups_table',6);
|
||||
INSERT INTO `migrations` VALUES (113,'2021_11_08_131308_onboarding',6);
|
||||
INSERT INTO `migrations` VALUES (114,'2021_11_09_115919_update_designs',6);
|
||||
INSERT INTO `migrations` VALUES (115,'2021_11_10_184847_add_is_migrate_column_to_accounts_table',6);
|
||||
INSERT INTO `migrations` VALUES (116,'2021_11_11_163121_add_instant_bank_transfer',7);
|
||||
|
@ -44,7 +44,7 @@ class PaymentLibrariesSeeder extends Seeder
|
||||
['id' => 17, 'name' => 'Pin', 'provider' => 'Pin', 'key' => '0749cb92a6b36c88bd9ff8aabd2efcab', 'fields' => '{"secretKey":"","testMode":false}'],
|
||||
['id' => 18, 'name' => 'SagePay Direct', 'provider' => 'SagePay_Direct', 'key' => '4c8f4e5d0f353a122045eb9a60cc0f2d', 'fields' => '{"vendor":"","testMode":false,"referrerId":""}'],
|
||||
['id' => 19, 'name' => 'SecurePay DirectPost', 'provider' => 'SecurePay_DirectPost', 'key' => '8036a5aadb2bdaafb23502da8790b6a2', 'fields' => '{"merchantId":"","transactionPassword":"","testMode":false,"enable_ach":"","enable_sofort":"","enable_apple_pay":"","enable_alipay":""}'],
|
||||
['id' => 20, 'name' => 'Stripe', 'provider' => 'Stripe', 'sort_order' => 1, 'key' => 'd14dd26a37cecc30fdd65700bfb55b23', 'fields' => '{"apiKey":"", "publishableKey":""}'],
|
||||
['id' => 20, 'name' => 'Stripe', 'provider' => 'Stripe', 'sort_order' => 1, 'key' => 'd14dd26a37cecc30fdd65700bfb55b23', 'fields' => '{"publishableKey":"","apiKey":""}'],
|
||||
['id' => 21, 'name' => 'TargetPay Direct eBanking', 'provider' => 'TargetPay_Directebanking', 'key' => 'd14dd26a37cdcc30fdd65700bfb55b23', 'fields' => '{"subAccountId":""}'],
|
||||
['id' => 22, 'name' => 'TargetPay Ideal', 'provider' => 'TargetPay_Ideal', 'key' => 'ea3b328bd72d381387281c3bd83bd97c', 'fields' => '{"subAccountId":""}'],
|
||||
['id' => 23, 'name' => 'TargetPay Mr Cash', 'provider' => 'TargetPay_Mrcash', 'key' => 'a0035fc0d87c4950fb82c73e2fcb825a', 'fields' => '{"subAccountId":""}'],
|
||||
|
@ -18,7 +18,7 @@
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||
<env name="CACHE_DRIVER" value="array"/>
|
||||
<env name="CACHE_DRIVER" value="file"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||
<env name="MAIL_MAILER" value="array"/>
|
||||
|
@ -6543,6 +6543,34 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--------------------------------------------------------------------------------
|
||||
diacritic
|
||||
|
||||
Copyright (c) 2016, Agilord.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
double-conversion
|
||||
icu
|
||||
|
48
public/flutter_service_worker.js
vendored
48
public/flutter_service_worker.js
vendored
@ -3,38 +3,38 @@ const MANIFEST = 'flutter-app-manifest';
|
||||
const TEMP = 'flutter-temp-cache';
|
||||
const CACHE_NAME = 'flutter-app-cache';
|
||||
const RESOURCES = {
|
||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
||||
"version.json": "9c7b0edc83733da56c726678aacd9fd3",
|
||||
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
|
||||
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||
"favicon.ico": "51636d3a390451561744c42188ccd628",
|
||||
"main.dart.js": "40a468819694baa11ae02390609712fc",
|
||||
"/": "38d8084156eb614c31d736ce8c9bd255",
|
||||
"assets/NOTICES": "5a96be85b952e4fcd3a6965546c85b7f",
|
||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "015400679694f1f51047e46da0e1dc98",
|
||||
"assets/AssetManifest.json": "38d9aea341601f3a5c6fa7b5a1216ea5",
|
||||
"assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1",
|
||||
"version.json": "f01b70a1dd8b65dd69abd55a4fe54b83",
|
||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40",
|
||||
"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
|
||||
"icons/Icon-192.png": "bb1cf5f6982006952211c7c8404ffbed",
|
||||
"main.dart.js": "03d6faff8d468318196cd0bef8a4c9a6",
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||
"/": "c2e105029a9aed730c6480128daf2ced",
|
||||
"assets/FontManifest.json": "cf3c681641169319e61b61bd0277378f",
|
||||
"assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1",
|
||||
"assets/AssetManifest.json": "38d9aea341601f3a5c6fa7b5a1216ea5",
|
||||
"assets/assets/images/logo_light.png": "e5f46d5a78e226e7a9553d4ca6f69219",
|
||||
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
|
||||
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
|
||||
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
|
||||
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
|
||||
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
|
||||
"assets/assets/images/payment_types/dinerscard.png": "06d85186ba858c18ab7c9caa42c92024",
|
||||
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
|
||||
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
|
||||
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
|
||||
"assets/assets/images/payment_types/maestro.png": "e533b92bfb50339fdbfa79e3dfe81f08",
|
||||
"assets/assets/images/payment_types/jcb.png": "07e0942d16c5592118b72e74f2f7198c",
|
||||
"assets/assets/images/payment_types/carteblanche.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
|
||||
"assets/assets/images/payment_types/paypal.png": "8e06c094c1871376dfea1da8088c29d1",
|
||||
"assets/assets/images/payment_types/ach.png": "7433f0aff779dc98a649b7a2daf777cf",
|
||||
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
|
||||
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
|
||||
"assets/assets/images/payment_types/switch.png": "4fa11c45327f5fdc20205821b2cfd9cc",
|
||||
"assets/assets/images/payment_types/other.png": "d936e11fa3884b8c9f1bd5c914be8629",
|
||||
"assets/assets/images/payment_types/visa.png": "3ddc4a4d25c946e8ad7e6998f30fd4e3",
|
||||
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3"
|
||||
"assets/assets/images/payment_types/discover.png": "6c0a386a00307f87db7bea366cca35f5",
|
||||
"assets/assets/images/payment_types/unionpay.png": "7002f52004e0ab8cc0b7450b0208ccb2",
|
||||
"assets/assets/images/payment_types/amex.png": "c49a4247984b3732a4af50a3390aa978",
|
||||
"assets/assets/images/payment_types/mastercard.png": "6f6cdc29ee2e22e06b1ac029cb52ef71",
|
||||
"assets/assets/images/payment_types/laser.png": "b4e6e93dd35517ac429301119ff05868",
|
||||
"assets/assets/images/payment_types/solo.png": "2030c3ccaccf5d5e87916a62f5b084d6",
|
||||
"assets/assets/images/google_logo.png": "0f118259ce403274f407f5e982e681c3",
|
||||
"assets/assets/images/icon.png": "090f69e23311a4b6d851b3880ae52541",
|
||||
"assets/assets/images/logo_dark.png": "a233ed1d4d0f7414bf97a9a10f11fb0a",
|
||||
"assets/NOTICES": "4aea723d13add566ca34288c8295b0a4",
|
||||
"assets/packages/material_design_icons_flutter/lib/fonts/materialdesignicons-webfont.ttf": "015400679694f1f51047e46da0e1dc98"
|
||||
};
|
||||
|
||||
// The application shell files that are downloaded before a service worker can
|
||||
|
192483
public/main.dart.js
vendored
192483
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
212448
public/main.foss.dart.js
vendored
212448
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
190717
public/main.html.dart.js
vendored
190717
public/main.html.dart.js
vendored
File diff suppressed because one or more lines are too long
212320
public/main.next.dart.js
vendored
212320
public/main.next.dart.js
vendored
File diff suppressed because one or more lines are too long
6872
public/main.profile.dart.js
vendored
6872
public/main.profile.dart.js
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/livewire.js
vendored
2
public/vendor/livewire/livewire.js
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/livewire.js.map
vendored
2
public/vendor/livewire/livewire.js.map
vendored
File diff suppressed because one or more lines are too long
2
public/vendor/livewire/manifest.json
vendored
2
public/vendor/livewire/manifest.json
vendored
@ -1 +1 @@
|
||||
{"/livewire.js":"/livewire.js?id=21fa1dd78491a49255cd"}
|
||||
{"/livewire.js":"/livewire.js?id=ece4c4ab4b746f6f1739"}
|
@ -1 +1 @@
|
||||
{"app_name":"invoiceninja_flutter","version":"5.0.67","build_number":"67"}
|
||||
{"app_name":"invoiceninja_flutter","version":"5.0.68","build_number":"68"}
|
@ -113,7 +113,7 @@
|
||||
table-layout: fixed;
|
||||
overflow-wrap: break-word;
|
||||
margin-top: 3rem;
|
||||
margin-bottom: 200px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
[data-ref="table"]:last-child{
|
||||
@ -371,20 +371,24 @@
|
||||
$entity_images
|
||||
|
||||
<div id="footer">
|
||||
<div>
|
||||
<div style="width: 100%;">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
|
||||
<script>
|
||||
// Clear up space a bit, if [product-table, tasks-table, delivery-note-table] isn't present.
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
let tables = [
|
||||
'product-table', 'task-table', 'delivery-note-table', 'statement-invoice-table-totals', 'statement-payment-table-totals','statement-invoice-table-totals',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table', 'statement-aging-table-totals', 'statement-payment-table-totals'
|
||||
'product-table', 'task-table', 'delivery-note-table',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table-totals',
|
||||
'statement-invoice-table-totals', 'statement-payment-table-totals', 'statement-aging-table'
|
||||
];
|
||||
|
||||
tables.forEach((tableIdentifier) => {
|
||||
const el =document.getElementById(tableIdentifier);
|
||||
if(el && el.childElementCount === 0)el.remove()
|
||||
console.log(document.getElementById(tableIdentifier));
|
||||
|
||||
document.getElementById(tableIdentifier)?.childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.setProperty('display', 'none', 'important')
|
||||
: '';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -351,7 +351,7 @@ $entity_images
|
||||
|
||||
<div class="repeating-footer" id="footer">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
// Clear up space a bit, if [product-table, tasks-table, delivery-note-table] isn't present.
|
||||
@ -368,3 +368,5 @@ $entity_images
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
@ -313,7 +313,7 @@ $entity_images
|
||||
|
||||
<div class="repeating-footer" id="footer">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
// Clear up space a bit, if [product-table, tasks-table, delivery-note-table] isn't present.
|
||||
@ -321,12 +321,17 @@ $entity_images
|
||||
let tables = [
|
||||
'product-table', 'task-table', 'delivery-note-table',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table-totals',
|
||||
'statement-invoice-table-totals', 'statement-payment-table-totals', 'statement-aging-table'
|
||||
];
|
||||
|
||||
tables.forEach((tableIdentifier) => {
|
||||
document.getElementById(tableIdentifier).childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.display = 'none'
|
||||
console.log(document.getElementById(tableIdentifier));
|
||||
|
||||
document.getElementById(tableIdentifier)?.childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.setProperty('display', 'none', 'important')
|
||||
: '';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
@ -303,24 +303,29 @@
|
||||
|
||||
<div class="repeating-header" id="header"></div>
|
||||
|
||||
<div class="repeating-footer" id="footer">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
</div>
|
||||
|
||||
$entity_images
|
||||
|
||||
<div class="repeating-footer" id="footer">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
|
||||
|
||||
<script>
|
||||
// Clear up space a bit, if [product-table, tasks-table, delivery-note-table] isn't present.
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
let tables = [
|
||||
'product-table', 'task-table', 'delivery-note-table',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table-totals',
|
||||
'statement-invoice-table-totals', 'statement-payment-table-totals', 'statement-aging-table'
|
||||
];
|
||||
|
||||
tables.forEach((tableIdentifier) => {
|
||||
document.getElementById(tableIdentifier).childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.display = 'none'
|
||||
console.log(document.getElementById(tableIdentifier));
|
||||
|
||||
document.getElementById(tableIdentifier)?.childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.setProperty('display', 'none', 'important')
|
||||
: '';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
@ -313,24 +313,30 @@
|
||||
|
||||
<div class="repeating-header" id="header"></div>
|
||||
|
||||
<div class="repeating-footer" id="footer">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
</div>
|
||||
|
||||
$entity_images
|
||||
|
||||
<div class="repeating-footer" id="footer">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
|
||||
<script>
|
||||
// Clear up space a bit, if [product-table, tasks-table, delivery-note-table] isn't present.
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
let tables = [
|
||||
'product-table', 'task-table', 'delivery-note-table',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table-totals',
|
||||
'statement-invoice-table-totals', 'statement-payment-table-totals', 'statement-aging-table'
|
||||
];
|
||||
|
||||
tables.forEach((tableIdentifier) => {
|
||||
document.getElementById(tableIdentifier).childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.display = 'none'
|
||||
console.log(document.getElementById(tableIdentifier));
|
||||
|
||||
document.getElementById(tableIdentifier)?.childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.setProperty('display', 'none', 'important')
|
||||
: '';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -354,30 +354,29 @@
|
||||
|
||||
<div class="repeating-header" id="header"></div>
|
||||
|
||||
<div class="repeating-footer" id="footer">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
</div>
|
||||
|
||||
$entity_images
|
||||
|
||||
<div class="repeating-footer" id="footer">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
|
||||
<script>
|
||||
// Clear up space a bit, if [product-table, tasks-table, delivery-note-table] isn't present.
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
let tables = [
|
||||
'product-table', 'task-table', 'delivery-note-table',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table-totals',
|
||||
'statement-invoice-table-totals', 'statement-payment-table-totals', 'statement-aging-table'
|
||||
];
|
||||
|
||||
tables.forEach((tableIdentifier) => {
|
||||
document.getElementById(tableIdentifier).childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.display = 'none'
|
||||
console.log(document.getElementById(tableIdentifier));
|
||||
|
||||
document.getElementById(tableIdentifier)?.childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.setProperty('display', 'none', 'important')
|
||||
: '';
|
||||
});
|
||||
|
||||
// If we have elements in these tables, we can change label to "Statement" & hide entity details.
|
||||
if (document.querySelectorAll('#statement-payment-table > tbody, #statement-payment-table > tbody, #statement-aging-table-totals > tbody').length > 0) {
|
||||
document.querySelector('.entity-label').innerText = '$statement_label';
|
||||
document.querySelector('.entity-details-wrapper').style.display = 'none';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
||||
|
@ -348,24 +348,28 @@ $entity_images
|
||||
|
||||
<div id="footer">
|
||||
<div class="footer-content">
|
||||
<div style="width: 70%;">
|
||||
<div style="width: 90%">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
|
||||
<script>
|
||||
// Clear up space a bit, if [product-table, tasks-table, delivery-note-table] isn't present.
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
let tables = [
|
||||
'product-table', 'task-table', 'delivery-note-table', 'statement-invoice-table-totals', 'statement-payment-table-totals','statement-invoice-table-totals',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table', 'statement-aging-table-totals', 'statement-payment-table-totals'
|
||||
'product-table', 'task-table', 'delivery-note-table',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table-totals',
|
||||
'statement-invoice-table-totals', 'statement-payment-table-totals', 'statement-aging-table'
|
||||
];
|
||||
|
||||
tables.forEach((tableIdentifier) => {
|
||||
document.getElementById(tableIdentifier).childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).remove()
|
||||
console.log(document.getElementById(tableIdentifier));
|
||||
|
||||
document.getElementById(tableIdentifier)?.childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.setProperty('display', 'none', 'important')
|
||||
: '';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
<div class="footer-company-details-address-wrapper">
|
||||
<div id="company-details"></div>
|
||||
|
@ -288,11 +288,10 @@
|
||||
|
||||
<div class="repeating-header" id="header"></div>
|
||||
|
||||
$entity_images
|
||||
|
||||
<div class="repeating-footer" id="footer">
|
||||
<p data-ref="total_table-footer">$entity_footer</p>
|
||||
</div>
|
||||
|
||||
$entity_images
|
||||
|
||||
<script>
|
||||
// Clear up space a bit, if [product-table, tasks-table, delivery-note-table] isn't present.
|
||||
@ -300,12 +299,16 @@ $entity_images
|
||||
let tables = [
|
||||
'product-table', 'task-table', 'delivery-note-table',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table-totals',
|
||||
'statement-invoice-table-totals', 'statement-payment-table-totals', 'statement-aging-table'
|
||||
];
|
||||
|
||||
tables.forEach((tableIdentifier) => {
|
||||
document.getElementById(tableIdentifier).childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.display = 'none'
|
||||
console.log(document.getElementById(tableIdentifier));
|
||||
|
||||
document.getElementById(tableIdentifier)?.childElementCount === 0
|
||||
? document.getElementById(tableIdentifier).style.setProperty('display', 'none', 'important')
|
||||
: '';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user