mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Merge upstream/v5-develop
This commit is contained in:
commit
85822c45ac
@ -51,11 +51,13 @@ TRUSTED_PROXIES=
|
||||
|
||||
NINJA_ENVIRONMENT=selfhost
|
||||
|
||||
PHANTOMJS_PDF_GENERATION=true
|
||||
#options - snappdf / phantom / hosted_ninja
|
||||
PDF_GENERATOR=phantom
|
||||
|
||||
PHANTOMJS_KEY='a-demo-key-with-low-quota-per-ip-address'
|
||||
PHANTOMJS_SECRET=secret
|
||||
|
||||
UPDATE_SECRET=
|
||||
UPDATE_SECRET=secret
|
||||
|
||||
COMPOSER_AUTH='{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}'
|
||||
SENTRY_LARAVEL_DSN=https://cc7e8e2c678041689e53e409b7dba236@sentry.invoicing.co/5
|
90
.travis.yml
90
.travis.yml
@ -1,90 +0,0 @@
|
||||
language: php
|
||||
|
||||
sudo: true
|
||||
|
||||
dist: xenial
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- xvfb
|
||||
|
||||
# Prevent tests from taking more than 50 minutes
|
||||
group: deprecated-2017Q4
|
||||
|
||||
php:
|
||||
# - 7.3
|
||||
- 7.4
|
||||
# - nightly
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libonig-dev
|
||||
chrome: stable
|
||||
hosts:
|
||||
- www.ninja.test
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
- $HOME/.composer/cache
|
||||
|
||||
env:
|
||||
global:
|
||||
- COMPOSER_DISCARD_CHANGES=true
|
||||
- COMPOSER_NO_INTERACTION=1
|
||||
- COMPOSER_DISABLE_XDEBUG_WARN=1
|
||||
|
||||
before_install:
|
||||
# set GitHub token and update composer
|
||||
- if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi;
|
||||
- composer self-update 1.10.19 && composer -V
|
||||
# - export USE_ZEND_ALLOC=0
|
||||
- rvm use 1.9.3 --install --fuzzy
|
||||
- cp .env.travis .env
|
||||
|
||||
install:
|
||||
# install Composer dependencies
|
||||
# - rm composer.lock
|
||||
# these providers require referencing git commit's which cause Travis to fail
|
||||
# - sed -i '/mollie/d' composer.json
|
||||
# - sed -i '/2checkout/d' composer.json
|
||||
- travis_retry composer install --no-interaction
|
||||
|
||||
before_script:
|
||||
# copy configuration files
|
||||
- php artisan key:generate --no-interaction
|
||||
- sed -i '$a NINJA_DEV=true' .env
|
||||
# create the database and user
|
||||
- mysql -u root -e "create database IF NOT EXISTS ninja01;"
|
||||
- mysql -u root -e "create database IF NOT EXISTS ninja02;"
|
||||
- mysql -u root -e "GRANT ALL PRIVILEGES ON ninja01.* To 'ninja'@'localhost' IDENTIFIED BY 'ninja'; FLUSH PRIVILEGES;"
|
||||
- mysql -u root -e "GRANT ALL PRIVILEGES ON ninja02.* To 'ninja'@'localhost' IDENTIFIED BY 'ninja'; FLUSH PRIVILEGES;"
|
||||
# migrate and seed the database
|
||||
- php artisan migrate --database=db-ninja-01 --seed --no-interaction
|
||||
- php artisan migrate --database=db-ninja-02 --seed --no-interaction
|
||||
- php artisan optimize
|
||||
- npm install
|
||||
- npm run production
|
||||
# migrate and seed the database
|
||||
# Start webserver on ninja.test:8000
|
||||
# export DISPLAY=:99.0
|
||||
# sh -e /etc/init.d/xvfb start
|
||||
# sleep 3
|
||||
# ./vendor/laravel/dusk/bin/chromedriver-linux &
|
||||
- php artisan dusk:chrome-driver 80
|
||||
- php artisan serve &
|
||||
|
||||
script:
|
||||
- php ./vendor/bin/phpunit --debug --verbose --coverage-clover=coverage.xml
|
||||
#- php artisan dusk
|
||||
#- npm test
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: never
|
||||
on_failure: change
|
||||
slack:
|
||||
invoiceninja: SLraaKBDvjeRuRtY9o3Yvp1b
|
@ -1,6 +1,9 @@
|
||||
# Release notes
|
||||
|
||||
## [Unreleased (daily channel)](https://github.com/invoiceninja/invoiceninja/tree/v5-develop)
|
||||
- Add Cache-control: no-cache to prevent overaggressive caching of assets
|
||||
|
||||
## [v5.1.56-release](https://github.com/invoiceninja/invoiceninja/releases/tag/v5.1.56-release)
|
||||
## Fixed:
|
||||
- Fix User created/updated/deleted Actvity display format
|
||||
- Fix for Stripe autobill / token regression
|
||||
@ -9,7 +12,7 @@
|
||||
- Invoice / Quote / Credit created notifications
|
||||
- Logout route - deletes all auth tokens
|
||||
|
||||
## [v5.1.54-release](https://github.com/invoiceninja/invoiceninja/releases/tag/v5.1.50-release)
|
||||
## [v5.1.54-release](https://github.com/invoiceninja/invoiceninja/releases/tag/v5.1.54-release)
|
||||
## Fixed:
|
||||
- Fixes for e-mails, encoding & parsing invalid HTML
|
||||
|
||||
|
4
CODE_OF_CONDUCT.md
Normal file
4
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Invoice Ninja Code of Conduct
|
||||
|
||||
The development team has invested a tremendous amount of time and energy into this project. While we appreciate that bugs can be frustrating we ask that our community refrain from insults and snide remarks. We're happy to provide support to both our hosted and selfhosted communities but ask that feedback is always polite.
|
||||
|
@ -1 +1 @@
|
||||
5.1.55
|
||||
5.1.61
|
120
app/Console/Commands/MobileLocalization.php
Normal file
120
app/Console/Commands/MobileLocalization.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use App\Utils\CurlUtils;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class MobileLocalization extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'ninja:mobile-localization {--type=}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Generate mobile localization resources';
|
||||
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$type = strtolower($this->option('type'));
|
||||
|
||||
switch ($type) {
|
||||
case 'laravel':
|
||||
$this->laravelResources();
|
||||
break;
|
||||
default:
|
||||
$this->flutterResources();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function laravelResources()
|
||||
{
|
||||
$resources = $this->getResources();
|
||||
|
||||
foreach ($resources as $key => $val) {
|
||||
$transKey = "texts.{$key}";
|
||||
if (trans($transKey) == $transKey) {
|
||||
echo "'$key' => '$val',\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function flutterResources()
|
||||
{
|
||||
$languages = cache('languages');
|
||||
$resources = $this->getResources();
|
||||
|
||||
foreach ($languages as $language) {
|
||||
if ($language->locale == 'en') {
|
||||
continue;
|
||||
}
|
||||
|
||||
echo "'{$language->locale}': {\n";
|
||||
|
||||
foreach ($resources as $key => $val) {
|
||||
$text = trim(addslashes(trans("texts.{$key}", [], $language->locale)));
|
||||
if (substr($text, 0, 6) == 'texts.') {
|
||||
$text = $resources->$key;
|
||||
}
|
||||
|
||||
$text = str_replace(array('<b>', '</b>'), '', $text);
|
||||
$text = str_replace(array('<i>', '</i>'), '', $text);
|
||||
$text = str_replace(array('<strong>', '</strong>'), '', $text);
|
||||
|
||||
echo "'$key': '$text',\n";
|
||||
}
|
||||
|
||||
echo "},\n";
|
||||
}
|
||||
}
|
||||
|
||||
private function getResources()
|
||||
{
|
||||
$url = 'https://raw.githubusercontent.com/invoiceninja/flutter-client/develop/lib/utils/i18n.dart';
|
||||
$data = CurlUtils::get($url);
|
||||
|
||||
$start = strpos($data, 'do not remove comment') + 25;
|
||||
$end = strpos($data, '},', $start);
|
||||
$data = substr($data, $start, $end - $start - 5);
|
||||
|
||||
$data = str_replace("\n", "", $data);
|
||||
$data = str_replace("\"", "\'", $data);
|
||||
$data = str_replace("'", "\"", $data);
|
||||
|
||||
return json_decode('{' . rtrim($data, ',') . '}');
|
||||
}
|
||||
|
||||
protected function getOptions()
|
||||
{
|
||||
return [
|
||||
['type', null, InputOption::VALUE_OPTIONAL, 'Type', null],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -42,43 +42,42 @@ class PostUpdate extends Command
|
||||
{
|
||||
set_time_limit(0);
|
||||
|
||||
nlog('running post update');
|
||||
info('running post update');
|
||||
|
||||
try {
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
} catch (\Exception $e) {
|
||||
nlog("I wasn't able to migrate the data.");
|
||||
info("I wasn't able to migrate the data.");
|
||||
}
|
||||
|
||||
nlog("finished migrating");
|
||||
|
||||
exec('vendor/bin/composer install --no-dev -o');
|
||||
$output = [];
|
||||
|
||||
nlog("finished running composer install ");
|
||||
exec('vendor/bin/composer install --no-dev -o', $output);
|
||||
|
||||
info(print_r($output,1));
|
||||
info("finished running composer install ");
|
||||
|
||||
try {
|
||||
Artisan::call('optimize');
|
||||
} catch (\Exception $e) {
|
||||
nlog("I wasn't able to optimize.");
|
||||
info("I wasn't able to optimize.");
|
||||
}
|
||||
|
||||
nlog("optimized");
|
||||
info("optimized");
|
||||
|
||||
try {
|
||||
Artisan::call('view:clear');
|
||||
} catch (\Exception $e) {
|
||||
nlog("I wasn't able to clear the views.");
|
||||
info("I wasn't able to clear the views.");
|
||||
}
|
||||
|
||||
nlog("view cleared");
|
||||
|
||||
/* For the following to work, the web user (www-data) must own all the directories */
|
||||
info("view cleared");
|
||||
|
||||
VersionCheck::dispatch();
|
||||
|
||||
nlog("sent for version check");
|
||||
info("Sent for version check");
|
||||
|
||||
// echo "Done.";
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
class AccountCreated
|
||||
use Turbo124\Beacon\ExampleMetric\GenericCounter;
|
||||
|
||||
class AccountCreated extends GenericCounter
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
class AccountDeleted
|
||||
use Turbo124\Beacon\ExampleMetric\GenericCounter;
|
||||
|
||||
class AccountDeleted extends GenericCounter
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
|
72
app/DataMapper/Analytics/DbQuery.php
Normal file
72
app/DataMapper/Analytics/DbQuery.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class DbQuery extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
*
|
||||
* Monotonically incrementing counter
|
||||
*
|
||||
* - counter
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'mixed_metric';
|
||||
|
||||
/**
|
||||
* The name of the counter.
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'db.queries';
|
||||
|
||||
/**
|
||||
* The datetime of the counter measurement.
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
/**
|
||||
* The Class failure name
|
||||
* set to 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric5 = 'method';
|
||||
|
||||
public $string_metric6 = 'url';
|
||||
|
||||
public $string_metric7 = 'ip_address';
|
||||
/**
|
||||
* The counter
|
||||
* set to 1.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $int_metric1 = 1;
|
||||
|
||||
public $double_metric2 = 1;
|
||||
|
||||
public function __construct($string_metric5, $string_metric6, $int_metric1, $double_metric2, $string_metric7) {
|
||||
$this->int_metric1 = $int_metric1;
|
||||
$this->string_metric5 = $string_metric5;
|
||||
$this->string_metric6 = $string_metric6;
|
||||
$this->double_metric2 = $double_metric2;
|
||||
$this->string_metric7 = $string_metric7;
|
||||
}
|
||||
}
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
class EmailFailure
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class EmailFailure extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
class EmailInvoiceFailure
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class EmailInvoiceFailure extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
class EmailSuccess
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class EmailSuccess extends GenericMixedMetric
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
class LoginFailure
|
||||
use Turbo124\Beacon\ExampleMetric\GenericCounter;
|
||||
|
||||
class LoginFailure extends GenericCounter
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
class LoginSuccess
|
||||
use Turbo124\Beacon\ExampleMetric\GenericCounter;
|
||||
|
||||
class LoginSuccess extends GenericCounter
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
|
79
app/DataMapper/Analytics/Mail/EmailBounce.php
Normal file
79
app/DataMapper/Analytics/Mail/EmailBounce.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\Analytics\Mail;
|
||||
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class EmailBounce extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
*
|
||||
* Monotonically incrementing counter
|
||||
*
|
||||
* - counter
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'mixed_metric';
|
||||
|
||||
/**
|
||||
* The name of the counter.
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'job.bounce.email';
|
||||
|
||||
/**
|
||||
* The datetime of the counter measurement.
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
/**
|
||||
* The Class failure name
|
||||
* set to 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric5 = 'tag';
|
||||
|
||||
/**
|
||||
* The exception string
|
||||
* set to 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric6 = 'from';
|
||||
|
||||
/**
|
||||
* Company Key
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric7 = 'messageid';
|
||||
|
||||
/**
|
||||
* The counter
|
||||
* set to 1.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $int_metric1 = 1;
|
||||
|
||||
public function __construct($string_metric5,$string_metric6,$string_metric7) {
|
||||
$this->string_metric5 = $string_metric5;
|
||||
$this->string_metric6 = $string_metric6;
|
||||
$this->string_metric7 = $string_metric7;
|
||||
}
|
||||
}
|
79
app/DataMapper/Analytics/Mail/EmailSpam.php
Normal file
79
app/DataMapper/Analytics/Mail/EmailSpam.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://opensource.org/licenses/AAL
|
||||
*/
|
||||
|
||||
namespace App\DataMapper\Analytics\Mail;
|
||||
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class EmailSpam extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
*
|
||||
* Monotonically incrementing counter
|
||||
*
|
||||
* - counter
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'mixed_metric';
|
||||
|
||||
/**
|
||||
* The name of the counter.
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'job.spam.email';
|
||||
|
||||
/**
|
||||
* The datetime of the counter measurement.
|
||||
*
|
||||
* date("Y-m-d H:i:s")
|
||||
*
|
||||
* @var DateTime
|
||||
*/
|
||||
public $datetime;
|
||||
|
||||
/**
|
||||
* The Class failure name
|
||||
* set to 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric5 = 'tag';
|
||||
|
||||
/**
|
||||
* The exception string
|
||||
* set to 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric6 = 'from';
|
||||
|
||||
/**
|
||||
* Company Key
|
||||
* @var string
|
||||
*/
|
||||
public $string_metric7 = 'messageid';
|
||||
|
||||
/**
|
||||
* The counter
|
||||
* set to 1.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $int_metric1 = 1;
|
||||
|
||||
public function __construct($string_metric5,$string_metric6,$string_metric7) {
|
||||
$this->string_metric5 = $string_metric5;
|
||||
$this->string_metric6 = $string_metric6;
|
||||
$this->string_metric7 = $string_metric7;
|
||||
}
|
||||
}
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
class MigrationFailure
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class MigrationFailure extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace App\DataMapper\Analytics;
|
||||
|
||||
class SendRecurringFailure
|
||||
use Turbo124\Beacon\ExampleMetric\GenericMixedMetric;
|
||||
|
||||
class SendRecurringFailure extends GenericMixedMetric
|
||||
{
|
||||
/**
|
||||
* The type of Sample.
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Events\Product;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
|
@ -51,6 +51,7 @@ class RecurringInvoiceToInvoiceFactory
|
||||
$invoice->client_id = $client->id;
|
||||
$invoice->auto_bill_enabled = $recurring_invoice->auto_bill_enabled;
|
||||
$invoice->paid_to_date = 0;
|
||||
$invoice->design_id = $recurring_invoice->design_id;
|
||||
|
||||
return $invoice;
|
||||
}
|
||||
|
@ -14,12 +14,14 @@ namespace App\Http\Controllers;
|
||||
use App\Http\Requests\Activity\DownloadHistoricalEntityRequest;
|
||||
use App\Models\Activity;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
use App\Utils\HostedPDF\NinjaPdf;
|
||||
use App\Utils\PhantomJS\Phantom;
|
||||
use App\Utils\Traits\Pdf\PdfMaker;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use stdClass;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use stdClass;
|
||||
|
||||
class ActivityController extends BaseController
|
||||
{
|
||||
@ -139,7 +141,15 @@ class ActivityController extends BaseController
|
||||
return response()->json(['message'=> ctrans('texts.no_backup_exists'), 'errors' => new stdClass], 404);
|
||||
}
|
||||
|
||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
||||
$pdf = (new Phantom)->convertHtmlToPdf($backup->html_backup);
|
||||
}
|
||||
elseif(config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja'){
|
||||
$pdf = (new NinjaPdf())->build($backup->html_backup);
|
||||
}
|
||||
else {
|
||||
$pdf = $this->makePdf(null, null, $backup->html_backup);
|
||||
}
|
||||
|
||||
if (isset($activity->invoice_id)) {
|
||||
$filename = $activity->invoice->numberFormatter().'.pdf';
|
||||
|
@ -194,8 +194,15 @@ class LoginController extends BaseController
|
||||
}
|
||||
|
||||
$user->setCompany($user->account->default_company);
|
||||
$timeout = auth()->user()->company()->default_password_timeout / 60000;
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$timeout = $user->company()->default_password_timeout;
|
||||
|
||||
if($timeout == 0)
|
||||
$timeout = 30*60*1000*1000;
|
||||
else
|
||||
$timeout = $timeout/1000;
|
||||
|
||||
Cache::put($user->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$cu = CompanyUser::query()
|
||||
->where('user_id', auth()->user()->id);
|
||||
@ -209,7 +216,8 @@ class LoginController extends BaseController
|
||||
|
||||
});
|
||||
|
||||
return $this->listResponse($cu);
|
||||
return $this->timeConstrainedResponse($cu);
|
||||
// return $this->listResponse($cu);
|
||||
|
||||
} else {
|
||||
|
||||
@ -282,6 +290,10 @@ class LoginController extends BaseController
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if($request->has('current_company') && $request->input('current_company') == 'true')
|
||||
$cu->where("company_id", $company_token->company_id);
|
||||
|
||||
return $this->refreshResponse($cu);
|
||||
}
|
||||
|
||||
@ -328,7 +340,15 @@ class LoginController extends BaseController
|
||||
|
||||
Auth::login($existing_user, true);
|
||||
$existing_user->setCompany($existing_user->account->default_company);
|
||||
$timeout = $existing_user->company()->default_password_timeout / 60000;
|
||||
|
||||
$timeout = $existing_user->company()->default_password_timeout;
|
||||
|
||||
if($timeout == 0)
|
||||
$timeout = 30*60*1000*1000;
|
||||
else
|
||||
$timeout = $timeout/1000;
|
||||
|
||||
|
||||
Cache::put($existing_user->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$cu = CompanyUser::query()
|
||||
@ -342,7 +362,7 @@ class LoginController extends BaseController
|
||||
}
|
||||
});
|
||||
|
||||
return $this->listResponse($cu);
|
||||
return $this->timeConstrainedResponse($cu);
|
||||
|
||||
}
|
||||
}
|
||||
@ -370,7 +390,15 @@ class LoginController extends BaseController
|
||||
|
||||
auth()->user()->email_verified_at = now();
|
||||
auth()->user()->save();
|
||||
$timeout = auth()->user()->company()->default_password_timeout / 60000;
|
||||
|
||||
$timeout = auth()->user()->company()->default_password_timeout;
|
||||
|
||||
if($timeout == 0)
|
||||
$timeout = 30*60*1000*1000;
|
||||
else
|
||||
$timeout = $timeout/1000;
|
||||
|
||||
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
$cu = CompanyUser::whereUserId(auth()->user()->id);
|
||||
@ -383,7 +411,7 @@ class LoginController extends BaseController
|
||||
}
|
||||
});
|
||||
|
||||
return $this->listResponse($cu);
|
||||
return $this->timeConstrainedResponse($cu);
|
||||
}
|
||||
|
||||
return response()
|
||||
|
@ -107,10 +107,11 @@ class BaseController extends Controller
|
||||
'token',
|
||||
'company.activities',
|
||||
'company.documents',
|
||||
//'company.users.company_user',
|
||||
'company.users.company_user',
|
||||
'company.tax_rates',
|
||||
'company.groups',
|
||||
'company.payment_terms',
|
||||
'company.designs.company',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
@ -219,7 +220,7 @@ class BaseController extends Controller
|
||||
|
||||
},
|
||||
'company.company_gateways' => function ($query) use ($user) {
|
||||
$query->whereNotNull('updated_at');
|
||||
$query->whereNotNull('updated_at')->with('gateway');
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('company_gateways.user_id', $user->id);
|
||||
@ -367,6 +368,192 @@ class BaseController extends Controller
|
||||
return $this->response($this->manager->createData($resource)->toArray());
|
||||
}
|
||||
|
||||
protected function timeConstrainedResponse($query)
|
||||
{
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
if ($user->getCompany()->is_large)
|
||||
$this->manager->parseIncludes($this->mini_load);
|
||||
else
|
||||
$this->manager->parseIncludes($this->first_load);
|
||||
|
||||
$this->serializer = request()->input('serializer') ?: EntityTransformer::API_SERIALIZER_ARRAY;
|
||||
|
||||
if ($this->serializer === EntityTransformer::API_SERIALIZER_JSON) {
|
||||
$this->manager->setSerializer(new JsonApiSerializer());
|
||||
} else {
|
||||
$this->manager->setSerializer(new ArraySerializer());
|
||||
}
|
||||
|
||||
$transformer = new $this->entity_transformer($this->serializer);
|
||||
$created_at = request()->has('created_at') ? request()->input('created_at') : 0;
|
||||
|
||||
$created_at = date('Y-m-d H:i:s', $created_at);
|
||||
|
||||
$query->with(
|
||||
[
|
||||
'company' => function ($query) use ($created_at, $user) {
|
||||
$query->whereNotNull('created_at')->with('documents');
|
||||
},
|
||||
'company.clients' => function ($query) use ($created_at, $user) {
|
||||
$query->where('clients.created_at', '>=', $created_at)->with('contacts.company', 'gateway_tokens', 'documents');
|
||||
|
||||
if(!$user->hasPermission('view_client'))
|
||||
$query->where('clients.user_id', $user->id)->orWhere('clients.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.company_gateways' => function ($query) use ($user) {
|
||||
$query->whereNotNull('created_at')->with('gateway');
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('company_gateways.user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.credits'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('invitations', 'documents');
|
||||
|
||||
if(!$user->hasPermission('view_credit'))
|
||||
$query->where('credits.user_id', $user->id)->orWhere('credits.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
// 'company.designs'=> function ($query) use ($created_at, $user) {
|
||||
// $query->where('created_at', '>=', $created_at)->with('company');
|
||||
|
||||
// if(!$user->isAdmin())
|
||||
// $query->where('designs.user_id', $user->id);
|
||||
// },
|
||||
'company.documents'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
},
|
||||
'company.expenses'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('documents');
|
||||
|
||||
if(!$user->hasPermission('view_expense'))
|
||||
$query->where('expenses.user_id', $user->id)->orWhere('expenses.assigned_user_id', $user->id);
|
||||
},
|
||||
'company.groups' => function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('group_settings.user_id', $user->id);
|
||||
},
|
||||
'company.invoices'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('invitations', 'documents');
|
||||
|
||||
if(!$user->hasPermission('view_invoice'))
|
||||
$query->where('invoices.user_id', $user->id)->orWhere('invoices.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.payments'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('paymentables', 'documents');
|
||||
|
||||
if(!$user->hasPermission('view_payment'))
|
||||
$query->where('payments.user_id', $user->id)->orWhere('payments.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.payment_terms'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('payment_terms.user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.products' => function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('documents');
|
||||
|
||||
if(!$user->hasPermission('view_product'))
|
||||
$query->where('products.user_id', $user->id)->orWhere('products.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.projects'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('documents');
|
||||
|
||||
if(!$user->hasPermission('view_project'))
|
||||
$query->where('projects.user_id', $user->id)->orWhere('projects.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.quotes'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('invitations', 'documents');
|
||||
|
||||
if(!$user->hasPermission('view_quote'))
|
||||
$query->where('quotes.user_id', $user->id)->orWhere('quotes.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.recurring_invoices'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('invitations', 'documents');
|
||||
|
||||
if(!$user->hasPermission('view_recurring_invoice'))
|
||||
$query->where('recurring_invoices.user_id', $user->id)->orWhere('recurring_invoices.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.tasks'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('documents');
|
||||
|
||||
if(!$user->hasPermission('view_task'))
|
||||
$query->where('tasks.user_id', $user->id)->orWhere('tasks.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.tax_rates' => function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('tax_rates.user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.vendors'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at)->with('contacts', 'documents');
|
||||
|
||||
if(!$user->hasPermission('view_vendor'))
|
||||
$query->where('vendors.user_id', $user->id)->orWhere('vendors.assigned_user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.expense_categories'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('expense_categories.user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.task_statuses'=> function ($query) use ($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('task_statuses.user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.activities'=> function ($query) use($user) {
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('activities.user_id', $user->id);
|
||||
|
||||
},
|
||||
'company.subscriptions'=> function ($query) use($created_at, $user) {
|
||||
$query->where('created_at', '>=', $created_at);
|
||||
|
||||
if(!$user->isAdmin())
|
||||
$query->where('subscriptions.user_id', $user->id);
|
||||
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
if ($query instanceof Builder) {
|
||||
$limit = request()->input('per_page', 20);
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
$query = $paginator->getCollection();
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
} else {
|
||||
$resource = new Collection($query, $transformer, $this->entity_type);
|
||||
}
|
||||
|
||||
return $this->response($this->manager->createData($resource)->toArray());
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected function listResponse($query)
|
||||
{
|
||||
$this->buildManager();
|
||||
|
@ -282,7 +282,7 @@ class ClientController extends BaseController
|
||||
|
||||
$this->uploadLogo($request->file('company_logo'), $client->company, $client);
|
||||
|
||||
event(new ClientWasUpdated($client, $client->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new ClientWasUpdated($client, $client->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($client->fresh());
|
||||
}
|
||||
@ -380,7 +380,7 @@ class ClientController extends BaseController
|
||||
|
||||
$this->uploadLogo($request->file('company_logo'), $client->company, $client);
|
||||
|
||||
event(new ClientWasCreated($client, $client->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new ClientWasCreated($client, $client->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($client);
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ class InvoiceController extends Controller
|
||||
{
|
||||
set_time_limit(0);
|
||||
|
||||
$invoice->service()->removeUnpaidGatewayFees()->save();
|
||||
|
||||
$data = [
|
||||
'invoice' => $invoice,
|
||||
];
|
||||
@ -164,7 +166,7 @@ class InvoiceController extends Controller
|
||||
if ($invoices->count() == 1) {
|
||||
return response()->streamDownload(function () use ($invoices) {
|
||||
echo file_get_contents($invoices->first()->pdf_file_path());
|
||||
}, basename($invoices->first()->pdf_file_path()));
|
||||
}, basename($invoices->first()->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($invoices->first()->pdf_file_path()), basename($invoices->first()->pdf_file_path()));
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,10 @@ class PaymentController extends Controller
|
||||
$payable_invoices = collect($request->payable_invoices);
|
||||
$invoices = Invoice::whereIn('id', $this->transformKeys($payable_invoices->pluck('invoice_id')->toArray()))->get();
|
||||
|
||||
$invoices->each(function($invoice){
|
||||
$invoice->service()->removeUnpaidGatewayFees()->save();
|
||||
});
|
||||
|
||||
/* pop non payable invoice from the $payable_invoices array */
|
||||
|
||||
$payable_invoices = $payable_invoices->filter(function ($payable_invoice) use ($invoices) {
|
||||
|
@ -78,7 +78,7 @@ class QuoteController extends Controller
|
||||
if ($quotes->count() == 1) {
|
||||
return response()->streamDownload(function () use ($invoices) {
|
||||
echo file_get_contents($invoices->first()->pdf_file_path());
|
||||
}, basename($invoices->first()->pdf_file_path()));
|
||||
}, basename($invoices->first()->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($invoices->first()->pdf_file_path()), basename($quotes->first()->pdf_file_path()));
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ class CreditController extends BaseController
|
||||
->fillDefaults()
|
||||
->save();
|
||||
|
||||
event(new CreditWasCreated($credit, $credit->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new CreditWasCreated($credit, $credit->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($credit);
|
||||
}
|
||||
@ -378,7 +378,7 @@ class CreditController extends BaseController
|
||||
|
||||
$credit->service()->deletePdf();
|
||||
|
||||
event(new CreditWasUpdated($credit, $credit->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new CreditWasUpdated($credit, $credit->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($credit);
|
||||
}
|
||||
@ -538,7 +538,7 @@ class CreditController extends BaseController
|
||||
case 'download':
|
||||
return response()->streamDownload(function () use ($credit) {
|
||||
echo file_get_contents($credit->pdf_file_path());
|
||||
}, basename($credit->pdf_file_path()));
|
||||
}, basename($credit->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($credit->pdf_file_path()), basename($credit->pdf_file_path()));
|
||||
break;
|
||||
case 'archive':
|
||||
@ -589,7 +589,7 @@ class CreditController extends BaseController
|
||||
|
||||
$file_path = $credit->service()->getCreditPdf($invitation);
|
||||
|
||||
return response()->download($file_path);
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,7 +157,7 @@ class EmailController extends BaseController
|
||||
$this->entity_transformer = QuoteTransformer::class;
|
||||
|
||||
if ($entity_obj->invitations->count() >= 1)
|
||||
event(new QuoteWasEmailed($entity_obj->invitations->first(), $entity_obj->company, Ninja::eventVars(auth()->user()->id), 'quote'));
|
||||
event(new QuoteWasEmailed($entity_obj->invitations->first(), $entity_obj->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null), 'quote'));
|
||||
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ class EmailController extends BaseController
|
||||
$this->entity_transformer = CreditTransformer::class;
|
||||
|
||||
if ($entity_obj->invitations->count() >= 1)
|
||||
event(new CreditWasEmailed($entity_obj->invitations->first(), $entity_obj->company, Ninja::eventVars(auth()->user()->id), 'credit'));
|
||||
event(new CreditWasEmailed($entity_obj->invitations->first(), $entity_obj->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null), 'credit'));
|
||||
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ class ExpenseController extends BaseController
|
||||
|
||||
$this->uploadLogo($request->file('company_logo'), $expense->company, $expense);
|
||||
|
||||
event(new ExpenseWasUpdated($expense, $expense->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new ExpenseWasUpdated($expense, $expense->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($expense->fresh());
|
||||
}
|
||||
@ -373,7 +373,7 @@ class ExpenseController extends BaseController
|
||||
{
|
||||
$expense = $this->expense_repo->save($request->all(), ExpenseFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||
|
||||
event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($expense);
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ class InvoiceController extends BaseController
|
||||
->triggeredActions($request)
|
||||
->save();
|
||||
|
||||
event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new InvoiceWasCreated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($invoice);
|
||||
}
|
||||
@ -399,7 +399,7 @@ class InvoiceController extends BaseController
|
||||
|
||||
$invoice->service()->deletePdf();
|
||||
|
||||
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($invoice);
|
||||
}
|
||||
@ -673,7 +673,7 @@ class InvoiceController extends BaseController
|
||||
case 'download':
|
||||
return response()->streamDownload(function () use ($invoice) {
|
||||
echo file_get_contents($invoice->pdf_file_path());
|
||||
}, basename($invoice->pdf_file_path()));
|
||||
}, basename($invoice->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($invoice->pdf_file_path()), basename($invoice->pdf_file_path()));
|
||||
break;
|
||||
case 'restore':
|
||||
@ -795,7 +795,7 @@ class InvoiceController extends BaseController
|
||||
|
||||
$file_path = $invoice->service()->getInvoicePdf($contact);
|
||||
|
||||
return response()->download($file_path, basename($file_path));
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -850,7 +850,7 @@ class InvoiceController extends BaseController
|
||||
$file = public_path("storage/{$file_path}");
|
||||
|
||||
|
||||
return response()->download($file, basename($file));
|
||||
return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache']);
|
||||
} catch (\Exception $e) {
|
||||
return response(['message' => 'Oops, something went wrong. Make sure you have symlink to storage/ in public/ directory.'], 500);
|
||||
}
|
||||
|
@ -59,9 +59,11 @@ class LogoutController extends BaseController
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
CompanyToken::with('company')
|
||||
$ct = CompanyToken::with('company.tokens')
|
||||
->whereRaw('BINARY `token`= ?', [$request->header('X-API-TOKEN')])
|
||||
->company
|
||||
->first();
|
||||
|
||||
$ct->company
|
||||
->tokens()
|
||||
->where('is_system', true)
|
||||
->forceDelete();
|
||||
|
@ -18,8 +18,10 @@ use App\Jobs\Mail\NinjaMailerJob;
|
||||
use App\Jobs\Mail\NinjaMailerObject;
|
||||
use App\Jobs\Util\StartMigration;
|
||||
use App\Mail\ExistingMigration;
|
||||
use App\Mail\Migration\MaxCompanies;
|
||||
use App\Models\Company;
|
||||
use App\Models\CompanyToken;
|
||||
use App\Utils\Ninja;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
@ -231,19 +233,51 @@ class MigrationController extends BaseController
|
||||
nlog($request->all());
|
||||
}
|
||||
|
||||
try {
|
||||
return response()->json([
|
||||
'_id' => Str::uuid(),
|
||||
'method' => config('queue.default'),
|
||||
'started_at' => now(),
|
||||
], 200);
|
||||
|
||||
} finally {
|
||||
// Controller logic here
|
||||
|
||||
foreach ($companies as $company) {
|
||||
$is_valid = $request->file($company->company_index)->isValid();
|
||||
|
||||
if (!$is_valid) {
|
||||
// We might want to send user something's wrong with migration or nope?
|
||||
continue;
|
||||
}
|
||||
|
||||
$user = auth()->user();
|
||||
|
||||
$company_count = $user->account->companies()->count();
|
||||
|
||||
// Look for possible existing company (based on company keys).
|
||||
$existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company->company_key])->first();
|
||||
|
||||
if(!$existing_company && $company_count >=10) {
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new MaxCompanies($user->account->companies()->first());
|
||||
$nmo->company = $user->account->companies()->first();
|
||||
$nmo->settings = $user->account->companies()->first()->settings;
|
||||
$nmo->to_user = $user;
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
return;
|
||||
}
|
||||
elseif($existing_company && $company_count > 10 ){
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new MaxCompanies($user->account->companies()->first());
|
||||
$nmo->company = $user->account->companies()->first();
|
||||
$nmo->settings = $user->account->companies()->first()->settings;
|
||||
$nmo->to_user = $user;
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
return;
|
||||
}
|
||||
|
||||
$checks = [
|
||||
'existing_company' => $existing_company ? (bool)1 : false,
|
||||
'force' => property_exists($company, 'force') ? (bool) $company->force : false,
|
||||
@ -254,9 +288,9 @@ class MigrationController extends BaseController
|
||||
nlog('Migrating: Existing company without force. (CASE_01)');
|
||||
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new ExistingMigration();
|
||||
$nmo->company = $existing_company;
|
||||
$nmo->settings = $existing_company->settings;
|
||||
$nmo->mailable = new ExistingMigration($existing_company);
|
||||
$nmo->company = $user->account->companies()->first();
|
||||
$nmo->settings = $user->account->companies()->first();
|
||||
$nmo->to_user = $user;
|
||||
|
||||
NinjaMailerJob::dispatch($nmo);
|
||||
@ -345,20 +379,18 @@ class MigrationController extends BaseController
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// StartMigration::dispatch(base_path("storage/app/public/$migration_file"), $user, $fresh_company)->delay(now()->addSeconds(5));
|
||||
nlog("starting migration job");
|
||||
nlog($migration_file);
|
||||
|
||||
if(Ninja::isHosted())
|
||||
StartMigration::dispatch($migration_file, $user, $fresh_company)->onQueue('migration');
|
||||
else
|
||||
StartMigration::dispatch($migration_file, $user, $fresh_company);
|
||||
} catch (\Exception $e) {
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'_id' => Str::uuid(),
|
||||
'method' => config('queue.default'),
|
||||
'started_at' => now(),
|
||||
], 200);
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +208,9 @@ class PaymentController extends BaseController
|
||||
{
|
||||
$payment = $this->payment_repo->save($request->all(), PaymentFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||
|
||||
if($request->has('email_receipt') && $request->input('email_receipt') == 'true' && !$payment->client->getSetting('client_manual_payment_notification'))
|
||||
$payment->service()->sendEmail();
|
||||
|
||||
return $this->itemResponse($payment);
|
||||
}
|
||||
|
||||
@ -382,7 +385,7 @@ class PaymentController extends BaseController
|
||||
|
||||
$payment = $this->payment_repo->save($request->all(), $payment);
|
||||
|
||||
event(new PaymentWasUpdated($payment, $payment->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new PaymentWasUpdated($payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
return $this->itemResponse($payment);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\DataMapper\Analytics\EmailBounce;
|
||||
use App\DataMapper\Analytics\EmailSpam;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\CreditInvitation;
|
||||
@ -19,6 +21,7 @@ use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Models\SystemLog;
|
||||
use Illuminate\Http\Request;
|
||||
use Turbo124\Beacon\Facades\LightLogs;
|
||||
|
||||
/**
|
||||
* Class PostMarkController.
|
||||
@ -71,8 +74,7 @@ class PostMarkController extends BaseController
|
||||
|
||||
if($request->header('X-API-SECURITY') && $request->header('X-API-SECURITY') == config('postmark.secret'))
|
||||
{
|
||||
|
||||
nlog($request->all());
|
||||
// nlog($request->all());
|
||||
|
||||
MultiDB::findAndSetDbByCompanyKey($request->input('Tag'));
|
||||
|
||||
@ -157,6 +159,14 @@ class PostMarkController extends BaseController
|
||||
$this->invitation->email_status = 'bounced';
|
||||
$this->invitation->save();
|
||||
|
||||
$bounce = new EmailBounce(
|
||||
$request->input('Tag'),
|
||||
$request->input('From'),
|
||||
$request->input('MessageID')
|
||||
);
|
||||
|
||||
LightLogs::create($bounce)->batch();
|
||||
|
||||
SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client);
|
||||
}
|
||||
|
||||
@ -191,6 +201,14 @@ class PostMarkController extends BaseController
|
||||
$this->invitation->email_status = 'spam';
|
||||
$this->invitation->save();
|
||||
|
||||
$spam = new EmailSpam(
|
||||
$request->input('Tag'),
|
||||
$request->input('From'),
|
||||
$request->input('MessageID')
|
||||
);
|
||||
|
||||
LightLogs::create($bounce)->batch();
|
||||
|
||||
SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client);
|
||||
}
|
||||
|
||||
|
@ -131,18 +131,18 @@ class PreviewController extends BaseController
|
||||
}
|
||||
|
||||
//if phantom js...... inject here..
|
||||
if (config('ninja.phantomjs_pdf_generation')) {
|
||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
||||
return (new Phantom)->convertHtmlToPdf($maker->getCompiledHTML(true));
|
||||
}
|
||||
|
||||
if(config('ninja.invoiceninja_hosted_pdf_generation')){
|
||||
if(config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja'){
|
||||
return (new NinjaPdf())->build($maker->getCompiledHTML(true));
|
||||
}
|
||||
|
||||
//else
|
||||
$file_path = PreviewPdf::dispatchNow($maker->getCompiledHTML(true), auth()->user()->company());
|
||||
|
||||
return response()->download($file_path)->deleteFileAfterSend(true);
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true);
|
||||
}
|
||||
|
||||
return $this->blankEntity();
|
||||
|
@ -211,7 +211,7 @@ class QuoteController extends BaseController
|
||||
|
||||
$quote = $quote->service()->fillDefaults()->save();
|
||||
|
||||
event(new QuoteWasCreated($quote, $quote->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new QuoteWasCreated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($quote);
|
||||
}
|
||||
@ -389,7 +389,7 @@ class QuoteController extends BaseController
|
||||
|
||||
$quote->service()->deletePdf();
|
||||
|
||||
event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new QuoteWasUpdated($quote, $quote->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($quote);
|
||||
}
|
||||
@ -677,7 +677,7 @@ class QuoteController extends BaseController
|
||||
case 'download':
|
||||
return response()->streamDownload(function () use ($quote) {
|
||||
echo file_get_contents($quote->pdf_file_path());
|
||||
}, basename($quote->pdf_file_path()));
|
||||
}, basename($quote->pdf_file_path()), ['Cache-Control:' => 'no-cache']);
|
||||
//return response()->download(TempFile::path($quote->pdf_file_path()), basename($quote->pdf_file_path()));
|
||||
break;
|
||||
case 'restore':
|
||||
@ -730,7 +730,7 @@ class QuoteController extends BaseController
|
||||
|
||||
$file_path = $quote->service()->getQuotePdf($contact);
|
||||
|
||||
return response()->download($file_path);
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -490,7 +490,7 @@ class RecurringInvoiceController extends BaseController
|
||||
|
||||
$file_path = $recurring_invoice->service()->getInvoicePdf($contact);
|
||||
|
||||
return response()->download($file_path, basename($file_path));
|
||||
return response()->download($file_path, basename($file_path), ['Cache-Control:' => 'no-cache']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,15 +58,11 @@ class SelfUpdateController extends BaseController
|
||||
set_time_limit(0);
|
||||
define('STDIN', fopen('php://stdin', 'r'));
|
||||
|
||||
if (Ninja::isNinja()) {
|
||||
if (Ninja::isHosted()) {
|
||||
return response()->json(['message' => ctrans('texts.self_update_not_available')], 403);
|
||||
}
|
||||
|
||||
if(!$this->testWritable())
|
||||
throw new FilePermissionsFailure('Cannot update system because files are not writable!');
|
||||
|
||||
// Check if new version is available
|
||||
//if($updater->source()->isNewVersionAvailable()) {
|
||||
$this->testWritable();
|
||||
|
||||
// Get the new version available
|
||||
$versionAvailable = $updater->source()->getVersionAvailable();
|
||||
@ -76,7 +72,6 @@ class SelfUpdateController extends BaseController
|
||||
|
||||
$updater->source()->update($release);
|
||||
|
||||
//}
|
||||
|
||||
$cacheCompiled = base_path('bootstrap/cache/compiled.php');
|
||||
if (file_exists($cacheCompiled)) { unlink ($cacheCompiled); }
|
||||
@ -84,7 +79,6 @@ class SelfUpdateController extends BaseController
|
||||
if (file_exists($cacheServices)) { unlink ($cacheServices); }
|
||||
|
||||
Artisan::call('clear-compiled');
|
||||
Artisan::call('cache:clear');
|
||||
Artisan::call('route:clear');
|
||||
Artisan::call('view:clear');
|
||||
Artisan::call('config:clear');
|
||||
@ -105,7 +99,9 @@ class SelfUpdateController extends BaseController
|
||||
// nlog($file->getPathname());
|
||||
|
||||
if ($file->isFile() && ! $file->isWritable()) {
|
||||
throw new FilePermissionsFailure($file);
|
||||
// throw new FilePermissionsFailure($file);
|
||||
nlog("Cannot update system because {$file->getFileName()} is not writable");
|
||||
throw new FilePermissionsFailure("Cannot update system because {$file->getFileName()} is not writable");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -284,18 +284,17 @@ class SetupController extends Controller
|
||||
if (file_exists($cacheCompiled)) {
|
||||
unlink ($cacheCompiled);
|
||||
}
|
||||
|
||||
$cacheServices = base_path('bootstrap/cache/services.php');
|
||||
if (file_exists($cacheServices)) {
|
||||
unlink ($cacheServices);
|
||||
}
|
||||
|
||||
Artisan::call('clear-compiled');
|
||||
Artisan::call('cache:clear');
|
||||
Artisan::call('debugbar:clear');
|
||||
Artisan::call('route:clear');
|
||||
Artisan::call('view:clear');
|
||||
Artisan::call('config:clear');
|
||||
Cache::flush();
|
||||
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
Artisan::call('db:seed', ['--force' => true]);
|
||||
|
||||
|
@ -43,19 +43,29 @@ class StripeConnectController extends BaseController
|
||||
'country' => $request->getCompany()->country()->iso_3166_2,
|
||||
];
|
||||
|
||||
$exists = CompanyGateway::query()
|
||||
$company_gateway = CompanyGateway::query()
|
||||
->where('gateway_key', 'd14dd26a47cecc30fdd65700bfb67b34')
|
||||
->where('company_id', $request->getCompany()->id)
|
||||
->first();
|
||||
|
||||
if ($exists) {
|
||||
if ($company_gateway) {
|
||||
|
||||
$config = decrypt($company_gateway->config);
|
||||
|
||||
if(property_exists($config, 'account_id'))
|
||||
return render('gateways.stripe.connect.existing');
|
||||
|
||||
}
|
||||
|
||||
$account = Account::create($data);
|
||||
|
||||
nlog($account);
|
||||
|
||||
$link = Account::link($account->id, $token);
|
||||
|
||||
nlog($link);
|
||||
|
||||
if(!$company_gateway)
|
||||
$company_gateway = CompanyGatewayFactory::create($request->getCompany()->id, $request->getContact()->id);
|
||||
|
||||
$company_gateway->fill([
|
||||
|
@ -177,7 +177,7 @@ class SubscriptionController extends BaseController
|
||||
{
|
||||
$subscription = $this->subscription_repo->save($request->all(), SubscriptionFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||
|
||||
event(new SubscriptionWasCreated($subscription, $subscription->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new SubscriptionWasCreated($subscription, $subscription->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($subscription);
|
||||
}
|
||||
@ -352,7 +352,7 @@ class SubscriptionController extends BaseController
|
||||
|
||||
$subscription = $this->subscription_repo->save($request->all(), $subscription);
|
||||
|
||||
event(new SubscriptionWasUpdated($subscription, $subscription->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new SubscriptionWasUpdated($subscription, $subscription->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($subscription);
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ class TaskController extends BaseController
|
||||
if($task->status_order != $old_task->status_order)
|
||||
$this->task_repo->sortStatuses($old_task, $task);
|
||||
|
||||
event(new TaskWasUpdated($task, $task->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new TaskWasUpdated($task, $task->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($task->fresh());
|
||||
}
|
||||
@ -378,7 +378,7 @@ class TaskController extends BaseController
|
||||
{
|
||||
$task = $this->task_repo->save($request->all(), TaskFactory::create(auth()->user()->company()->id, auth()->user()->id));
|
||||
|
||||
event(new TaskWasCreated($task, $task->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new TaskWasCreated($task, $task->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($task);
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ class UserController extends BaseController
|
||||
|
||||
nlog("in the store method of the usercontroller class");
|
||||
|
||||
event(new UserWasCreated($user, auth()->user(), $company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new UserWasCreated($user, auth()->user(), $company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($user->fresh());
|
||||
}
|
||||
@ -401,7 +401,7 @@ class UserController extends BaseController
|
||||
$user->company_user()->update(["permissions_updated_at" => now()]);
|
||||
}
|
||||
|
||||
event(new UserWasUpdated($user, auth()->user(), auth()->user()->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new UserWasUpdated($user, auth()->user(), auth()->user()->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($user);
|
||||
}
|
||||
@ -474,7 +474,7 @@ class UserController extends BaseController
|
||||
/* If the user passes the company user we archive the company user */
|
||||
$user = $this->user_repo->delete($request->all(), $user);
|
||||
|
||||
event(new UserWasDeleted($user, auth()->user(), auth()->user()->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new UserWasDeleted($user, auth()->user(), auth()->user()->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($user->fresh());
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ class VendorController extends BaseController
|
||||
|
||||
$this->uploadLogo($request->file('company_logo'), $vendor->company, $vendor);
|
||||
|
||||
event(new VendorWasUpdated($vendor, $vendor->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new VendorWasUpdated($vendor, $vendor->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($vendor->fresh());
|
||||
}
|
||||
@ -376,7 +376,7 @@ class VendorController extends BaseController
|
||||
|
||||
$this->uploadLogo($request->file('company_logo'), $vendor->company, $vendor);
|
||||
|
||||
event(new VendorWasCreated($vendor, $vendor->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new VendorWasCreated($vendor, $vendor->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $this->itemResponse($vendor);
|
||||
}
|
||||
|
@ -40,14 +40,13 @@ class PasswordProtection
|
||||
$timeout = auth()->user()->company()->default_password_timeout;
|
||||
|
||||
if($timeout == 0)
|
||||
$timeout = null;
|
||||
$timeout = 30*60*1000*1000;
|
||||
else
|
||||
$timeout = now()->addMinutes($timeout/60000);
|
||||
$timeout = $timeout/1000;
|
||||
|
||||
if (Cache::get(auth()->user()->hashed_id.'_logged_in')) {
|
||||
|
||||
Cache::pull(auth()->user()->hashed_id.'_logged_in');
|
||||
Cache::add(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
return $next($request);
|
||||
|
||||
@ -69,12 +68,12 @@ class PasswordProtection
|
||||
//If OAuth and user also has a password set - check both
|
||||
if ($existing_user = MultiDB::hasUser($query) && auth()->user()->has_password && Hash::check(auth()->user()->password, $request->header('X-API-PASSWORD'))) {
|
||||
|
||||
Cache::add(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
return $next($request);
|
||||
}
|
||||
elseif($existing_user = MultiDB::hasUser($query) && !auth()->user()->has_password){
|
||||
|
||||
Cache::add(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@ -84,7 +83,7 @@ class PasswordProtection
|
||||
|
||||
}elseif ($request->header('X-API-PASSWORD') && Hash::check($request->header('X-API-PASSWORD'), auth()->user()->password)) {
|
||||
|
||||
Cache::add(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
Cache::put(auth()->user()->hashed_id.'_logged_in', Str::random(64), $timeout);
|
||||
|
||||
return $next($request);
|
||||
|
||||
|
@ -11,10 +11,13 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\DataMapper\Analytics\DbQuery;
|
||||
use App\Utils\Ninja;
|
||||
use Closure;
|
||||
use DB;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use Turbo124\Beacon\Facades\LightLogs;
|
||||
|
||||
/**
|
||||
* Class QueryLogging.
|
||||
@ -31,32 +34,34 @@ class QueryLogging
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$timeStart = microtime(true);
|
||||
|
||||
// Enable query logging for development
|
||||
if (config('ninja.app_env') == 'production') {
|
||||
if (!Ninja::isHosted() || !config('beacon.enabled')) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$timeStart = microtime(true);
|
||||
DB::enableQueryLog();
|
||||
|
||||
$response = $next($request);
|
||||
|
||||
if (config('ninja.app_env') != 'production') {
|
||||
|
||||
// hide requests made by debugbar
|
||||
if (strstr($request->url(), '_debugbar') === false) {
|
||||
|
||||
$queries = DB::getQueryLog();
|
||||
$count = count($queries);
|
||||
$timeEnd = microtime(true);
|
||||
$time = $timeEnd - $timeStart;
|
||||
|
||||
nlog($request->method().' - '.$request->url().": $count queries - ".$time);
|
||||
nlog($request->method().' - '.urldecode($request->url()).": $count queries - ".$time);
|
||||
// nlog($request->method().' - '.urldecode($request->fullUrl()).": $count queries - ".$time);
|
||||
|
||||
// if($count > 50)
|
||||
//nlog($queries);
|
||||
|
||||
LightLogs::create(new DbQuery($request->method(), urldecode($request->url()), $count, $time, request()->ip()))
|
||||
->batch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
@ -55,12 +55,17 @@ class StoreCompanyRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if(array_key_exists('portal_domain', $input) && strlen($input['portal_domain']) > 1)
|
||||
$input['portal_domain'] = str_replace("http:", "https:", $input['portal_domain']);
|
||||
|
||||
if (array_key_exists('google_analytics_url', $input)) {
|
||||
$input['google_analytics_key'] = $input['google_analytics_url'];
|
||||
}
|
||||
|
||||
$company_settings = CompanySettings::defaults();
|
||||
|
||||
//@todo this code doesn't make sense as we never return $company_settings anywhere
|
||||
//@deprecated???
|
||||
if (array_key_exists('settings', $input) && ! empty($input['settings'])) {
|
||||
foreach ($input['settings'] as $key => $value) {
|
||||
$company_settings->{$key} = $value;
|
||||
|
@ -59,7 +59,10 @@ class UpdateCompanyRequest extends Request
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$input = $this->all();
|
||||
// nlog($input);
|
||||
|
||||
if(array_key_exists('portal_domain', $input) && strlen($input['portal_domain']) > 1)
|
||||
$input['portal_domain'] = str_replace("http:", "https:", $input['portal_domain']);
|
||||
|
||||
if (array_key_exists('settings', $input)) {
|
||||
$input['settings'] = $this->filterSaveableSettings($input['settings']);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ class UpdateUserRequest extends Request
|
||||
*/
|
||||
public function authorize() : bool
|
||||
{
|
||||
return auth()->user()->id === $this->id || auth()->user()->isAdmin();
|
||||
return auth()->user()->id == $this->user->id || auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
public function rules()
|
||||
@ -45,9 +45,9 @@ class UpdateUserRequest extends Request
|
||||
{
|
||||
$input = $this->all();
|
||||
|
||||
if (isset($input['company_user']) && ! auth()->user()->isAdmin()) {
|
||||
unset($input['company_user']);
|
||||
}
|
||||
// if (isset($input['company_user']) && ! auth()->user()->isAdmin()) {
|
||||
// unset($input['company_user']);
|
||||
// }
|
||||
|
||||
$this->replace($input);
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ class RecurringInvoicesCron
|
||||
{
|
||||
use Dispatchable;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
|
@ -91,13 +91,21 @@ class CreateEntityPdf implements ShouldQueue
|
||||
|
||||
public function handle()
|
||||
{
|
||||
/* Set the locale*/
|
||||
App::setLocale($this->contact->preferredLocale());
|
||||
|
||||
/* Forget the singleton*/
|
||||
App::forgetInstance('translator');
|
||||
|
||||
/* Init a new copy of the translator*/
|
||||
$t = app('translator');
|
||||
|
||||
/* Set customized translations _NOW_ */
|
||||
Lang::replace(Ninja::transformTranslations($this->entity->client->getMergedSettings()));
|
||||
|
||||
$this->entity->service()->deletePdf();
|
||||
|
||||
if (config('ninja.phantomjs_pdf_generation')) {
|
||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
||||
return (new Phantom)->generate($this->invitation);
|
||||
}
|
||||
|
||||
@ -163,7 +171,7 @@ class CreateEntityPdf implements ShouldQueue
|
||||
|
||||
try {
|
||||
|
||||
if(config('ninja.invoiceninja_hosted_pdf_generation')){
|
||||
if(config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja'){
|
||||
$pdf = (new NinjaPdf())->build($maker->getCompiledHTML(true));
|
||||
}
|
||||
else {
|
||||
|
@ -60,6 +60,8 @@ class EmailEntity implements ShouldQueue
|
||||
|
||||
public $template_data; //The data to be merged into the template
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
/**
|
||||
* EmailEntity constructor.
|
||||
*
|
||||
@ -142,7 +144,7 @@ class EmailEntity implements ShouldQueue
|
||||
{
|
||||
switch ($this->entity_string) {
|
||||
case 'invoice':
|
||||
event(new InvoiceWasEmailedAndFailed($this->invitation, $this->company, $message, $this->reminder_template, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new InvoiceWasEmailedAndFailed($this->invitation, $this->company, $message, $this->reminder_template, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -75,13 +75,20 @@ class NinjaMailerJob implements ShouldQueue
|
||||
|
||||
if (strlen($this->nmo->settings->reply_to_email) > 1) {
|
||||
|
||||
$reply_to_name = strlen($this->nmo->settings->reply_to_name) > 1 ? $this->nmo->settings->reply_to_name : $this->nmo->company->present()->name();
|
||||
if(property_exists($this->nmo->settings, 'reply_to_name'))
|
||||
$reply_to_name = strlen($this->nmo->settings->reply_to_name) > 3 ? $this->nmo->settings->reply_to_name : $this->nmo->settings->reply_to_email;
|
||||
else
|
||||
$reply_to_name = $this->nmo->settings->reply_to_email;
|
||||
|
||||
$this->nmo->mailable->replyTo($this->nmo->settings->reply_to_email, $reply_to_name);
|
||||
|
||||
}
|
||||
|
||||
if (strlen($this->nmo->settings->bcc_email) > 1)
|
||||
$this->nmo->mailable->bcc($this->nmo->settings->bcc_email, $this->nmo->settings->bcc_email);
|
||||
if (strlen($this->nmo->settings->bcc_email) > 1) {
|
||||
nlog('bcc list available');
|
||||
nlog($this->nmo->settings->bcc_email);
|
||||
$this->nmo->mailable->bcc(explode(",", $this->nmo->settings->bcc_email), 'Blind Copy');
|
||||
}
|
||||
|
||||
|
||||
//send email
|
||||
|
@ -85,7 +85,10 @@ class UpdateOrCreateProduct implements ShouldQueue
|
||||
$product->notes = isset($item->notes) ? $item->notes : '';
|
||||
//$product->cost = isset($item->cost) ? $item->cost : 0; //this value shouldn't be updated.
|
||||
$product->price = isset($item->cost) ? $item->cost : 0;
|
||||
|
||||
if(!$product->id)
|
||||
$product->quantity = isset($item->quantity) ? $item->quantity : 0;
|
||||
|
||||
$product->tax_name1 = isset($item->tax_name1) ? $item->tax_name1 : '';
|
||||
$product->tax_rate1 = isset($item->tax_rate1) ? $item->tax_rate1 : 0;
|
||||
$product->tax_name2 = isset($item->tax_name2) ? $item->tax_name2 : '';
|
||||
|
@ -94,7 +94,14 @@ class SendRecurring implements ShouldQueue
|
||||
|
||||
$invoice->invitations->each(function ($invitation) use ($invoice) {
|
||||
if ($invitation->contact && strlen($invitation->contact->email) >=1) {
|
||||
|
||||
try{
|
||||
EmailEntity::dispatch($invitation, $invoice->company);
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
|
||||
nlog("Firing email for invoice {$invoice->number}");
|
||||
}
|
||||
});
|
||||
|
@ -31,6 +31,7 @@ use App\Factory\VendorFactory;
|
||||
use App\Http\Requests\Company\UpdateCompanyRequest;
|
||||
use App\Http\ValidationRules\ValidCompanyGatewayFeesAndLimitsRule;
|
||||
use App\Http\ValidationRules\ValidUserForCompany;
|
||||
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
use App\Jobs\Ninja\CheckCompanyData;
|
||||
use App\Jobs\Ninja\CompanySizeCheck;
|
||||
@ -70,6 +71,7 @@ use App\Repositories\QuoteRepository;
|
||||
use App\Repositories\UserRepository;
|
||||
use App\Repositories\VendorContactRepository;
|
||||
use App\Repositories\VendorRepository;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\CleanLineItems;
|
||||
use App\Utils\Traits\CompanyGatewayFeesAndLimitsSaver;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
@ -82,10 +84,11 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Turbo124\Beacon\Facades\LightLogs;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class Import implements ShouldQueue
|
||||
{
|
||||
@ -192,15 +195,6 @@ class Import implements ShouldQueue
|
||||
$array = json_decode(file_get_contents($this->file_path), 1);
|
||||
$data = $array['data'];
|
||||
|
||||
|
||||
// disable some functionality here:
|
||||
// 1. disable update_products
|
||||
|
||||
$update_product_state = $this->company->update_products;
|
||||
|
||||
$this->company->update_products = false;
|
||||
$this->company->save();
|
||||
|
||||
foreach ($this->available_imports as $import) {
|
||||
if (! array_key_exists($import, $data)) {
|
||||
//throw new ResourceNotAvailableForMigration("Resource {$key} is not available for migration.");
|
||||
@ -220,9 +214,7 @@ class Import implements ShouldQueue
|
||||
// $this->fixClientBalances();
|
||||
$check_data = CheckCompanyData::dispatchNow($this->company, md5(time()));
|
||||
|
||||
//reset functionality here
|
||||
$this->company->update_products = $update_product_state;
|
||||
$this->company->save();
|
||||
|
||||
|
||||
try{
|
||||
Mail::to($this->user->email, $this->user->name())
|
||||
@ -237,10 +229,13 @@ class Import implements ShouldQueue
|
||||
|
||||
//company size check
|
||||
if ($this->company->invoices()->count() > 1000 || $this->company->products()->count() > 1000 || $this->company->clients()->count() > 1000) {
|
||||
$company->is_large = true;
|
||||
$company->save();
|
||||
$this->company->is_large = true;
|
||||
$this->company->save();
|
||||
}
|
||||
|
||||
// CreateCompanyPaymentTerms::dispatchNow($sp035a66, $spaa9f78);
|
||||
CreateCompanyTaskStatuses::dispatchNow($this->company, $this->user);
|
||||
|
||||
info('Completed🚀🚀🚀🚀🚀 at '.now());
|
||||
|
||||
unlink($this->file_path);
|
||||
@ -466,6 +461,21 @@ class Import implements ShouldQueue
|
||||
$user_repository = null;
|
||||
}
|
||||
|
||||
private function checkUniqueConstraint($model, $column, $value)
|
||||
{
|
||||
$value = trim($value);
|
||||
|
||||
$model_query = (new $model())
|
||||
->query()
|
||||
->where($column, $value)
|
||||
->exists();
|
||||
|
||||
if($model_query)
|
||||
return $value.'_'. Str::random(5);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @throws Exception
|
||||
@ -483,6 +493,7 @@ class Import implements ShouldQueue
|
||||
$modified['user_id'] = $this->processUserId($resource);
|
||||
$modified['balance'] = $modified['balance'] ?: 0;
|
||||
$modified['paid_to_date'] = $modified['paid_to_date'] ?: 0;
|
||||
$modified['number'] = $this->checkUniqueConstraint(Client::class, 'number', $modified['number']);
|
||||
|
||||
unset($modified['id']);
|
||||
unset($modified['contacts']);
|
||||
@ -495,6 +506,14 @@ class Import implements ShouldQueue
|
||||
)
|
||||
);
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$client->created_at = Carbon::parse($modified['created_at']);
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$client->updated_at = Carbon::parse($modified['updated_at']);
|
||||
|
||||
$client->save(['timestamps' => false]);
|
||||
|
||||
$client->contacts()->forceDelete();
|
||||
|
||||
if (array_key_exists('contacts', $resource)) { // need to remove after importing new migration.json
|
||||
@ -568,6 +587,12 @@ class Import implements ShouldQueue
|
||||
unset($modified['id']);
|
||||
unset($modified['contacts']);
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$modified['created_at'] = Carbon::parse($modified['created_at']);
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$modified['updated_at'] = Carbon::parse($modified['updated_at']);
|
||||
|
||||
$vendor = $vendor_repository->save(
|
||||
$modified,
|
||||
VendorFactory::create(
|
||||
@ -635,6 +660,12 @@ class Import implements ShouldQueue
|
||||
$modified['company_id'] = $this->company->id;
|
||||
$modified['user_id'] = $this->processUserId($resource);
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$modified['created_at'] = Carbon::parse($modified['created_at']);
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$modified['updated_at'] = Carbon::parse($modified['updated_at']);
|
||||
|
||||
unset($modified['id']);
|
||||
|
||||
$product_repository->save(
|
||||
@ -681,6 +712,12 @@ class Import implements ShouldQueue
|
||||
$modified['company_id'] = $this->company->id;
|
||||
$modified['line_items'] = $this->cleanItems($modified['line_items']);
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$modified['created_at'] = Carbon::parse($modified['created_at']);
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$modified['updated_at'] = Carbon::parse($modified['updated_at']);
|
||||
|
||||
unset($modified['id']);
|
||||
|
||||
if (array_key_exists('invitations', $resource)) {
|
||||
@ -688,6 +725,8 @@ class Import implements ShouldQueue
|
||||
$resource['invitations'][$key]['client_contact_id'] = $this->transformId('client_contacts', $invite['client_contact_id']);
|
||||
$resource['invitations'][$key]['user_id'] = $modified['user_id'];
|
||||
$resource['invitations'][$key]['company_id'] = $this->company->id;
|
||||
$resource['invitations'][$key]['email_status'] = '';
|
||||
|
||||
unset($resource['invitations'][$key]['recurring_invoice_id']);
|
||||
unset($resource['invitations'][$key]['id']);
|
||||
|
||||
@ -752,6 +791,7 @@ class Import implements ShouldQueue
|
||||
$resource['invitations'][$key]['client_contact_id'] = $this->transformId('client_contacts', $invite['client_contact_id']);
|
||||
$resource['invitations'][$key]['user_id'] = $modified['user_id'];
|
||||
$resource['invitations'][$key]['company_id'] = $this->company->id;
|
||||
$resource['invitations'][$key]['email_status'] = '';
|
||||
unset($resource['invitations'][$key]['invoice_id']);
|
||||
unset($resource['invitations'][$key]['id']);
|
||||
}
|
||||
@ -814,6 +854,12 @@ class Import implements ShouldQueue
|
||||
$modified['user_id'] = $this->processUserId($resource);
|
||||
$modified['company_id'] = $this->company->id;
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$modified['created_at'] = Carbon::parse($modified['created_at']);
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$modified['updated_at'] = Carbon::parse($modified['updated_at']);
|
||||
|
||||
unset($modified['id']);
|
||||
|
||||
$credit = $credit_repository->save(
|
||||
@ -873,6 +919,18 @@ class Import implements ShouldQueue
|
||||
|
||||
$modified['company_id'] = $this->company->id;
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$modified['created_at'] = Carbon::parse($modified['created_at']);
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$modified['updated_at'] = Carbon::parse($modified['updated_at']);
|
||||
|
||||
if(array_key_exists('tax_rate1', $modified) && is_null($modified['tax_rate1']))
|
||||
$modified['tax_rate1'] = 0;
|
||||
|
||||
if(array_key_exists('tax_rate2', $modified) && is_null($modified['tax_rate2']))
|
||||
$modified['tax_rate2'] = 0;
|
||||
|
||||
unset($modified['id']);
|
||||
|
||||
|
||||
@ -881,6 +939,7 @@ class Import implements ShouldQueue
|
||||
$resource['invitations'][$key]['client_contact_id'] = $this->transformId('client_contacts', $invite['client_contact_id']);
|
||||
$resource['invitations'][$key]['user_id'] = $modified['user_id'];
|
||||
$resource['invitations'][$key]['company_id'] = $this->company->id;
|
||||
$resource['invitations'][$key]['email_status'] = '';
|
||||
unset($resource['invitations'][$key]['invoice_id']);
|
||||
unset($resource['invitations'][$key]['id']);
|
||||
}
|
||||
@ -894,6 +953,14 @@ class Import implements ShouldQueue
|
||||
QuoteFactory::create($this->company->id, $modified['user_id'])
|
||||
);
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$quote->created_at = $modified['created_at'];
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$quote->updated_at = $modified['updated_at'];
|
||||
|
||||
$quote->save(['timestamps' => false]);
|
||||
|
||||
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
||||
|
||||
$key = "quotes_{$resource['id']}";
|
||||
@ -960,6 +1027,14 @@ class Import implements ShouldQueue
|
||||
PaymentFactory::create($this->company->id, $modified['user_id'])
|
||||
);
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$payment->created_at = Carbon::parse($modified['created_at']);
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$payment->updated_at = Carbon::parse($modified['updated_at']);
|
||||
|
||||
$payment->save(['timestamps' => false]);
|
||||
|
||||
if (array_key_exists('company_gateway_id', $resource) && isset($resource['company_gateway_id']) && $resource['company_gateway_id'] != 'NULL') {
|
||||
$payment->company_gateway_id = $this->transformId('company_gateways', $resource['company_gateway_id']);
|
||||
$payment->save();
|
||||
@ -1182,6 +1257,11 @@ class Import implements ShouldQueue
|
||||
$modified['fees_and_limits'] = $this->cleanFeesAndLimits($modified['fees_and_limits']);
|
||||
}
|
||||
|
||||
if(Ninja::isHosted() && $modified['gateway_key'] == 'd14dd26a37cecc30fdd65700bfb55b23'){
|
||||
$modified['gateway_key'] = 'd14dd26a47cecc30fdd65700bfb67b34';
|
||||
$modified['fees_and_limits'] = [];
|
||||
}
|
||||
|
||||
$company_gateway = CompanyGateway::create($modified);
|
||||
|
||||
$key = "company_gateways_{$resource['id']}";
|
||||
@ -1322,6 +1402,16 @@ class Import implements ShouldQueue
|
||||
|
||||
$task = Task::Create($modified);
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$task->created_at = Carbon::parse($modified['created_at']);
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$task->updated_at = Carbon::parse($modified['updated_at']);
|
||||
|
||||
|
||||
|
||||
$task->save(['timestamps' => false]);
|
||||
|
||||
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
||||
|
||||
$this->ids['tasks'] = [
|
||||
@ -1402,6 +1492,16 @@ class Import implements ShouldQueue
|
||||
|
||||
$expense = Expense::Create($modified);
|
||||
|
||||
if(array_key_exists('created_at', $modified))
|
||||
$expense->created_at = Carbon::parse($modified['created_at']);
|
||||
|
||||
if(array_key_exists('updated_at', $modified))
|
||||
$expense->updated_at = Carbon::parse($modified['updated_at']);
|
||||
|
||||
|
||||
|
||||
$expense->save(['timestamps' => false]);
|
||||
|
||||
$old_user_key = array_key_exists('user_id', $resource) ?? $this->user->id;
|
||||
|
||||
$key = "expenses_{$resource['id']}";
|
||||
|
@ -23,6 +23,8 @@ class SchedulerCheck implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
@ -45,14 +47,17 @@ class SchedulerCheck implements ShouldQueue
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
} catch (\Exception $e) {
|
||||
nlog("I wasn't able to migrate the data.");
|
||||
nlog($e->getMessage());
|
||||
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
Artisan::call('optimize');
|
||||
Artisan::call('clear-compiled');
|
||||
Artisan::call('route:clear');
|
||||
Artisan::call('config:cache');
|
||||
} catch (\Exception $e) {
|
||||
nlog($e->getMessage());
|
||||
nlog("I wasn't able to optimize.");
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
@ -60,6 +65,7 @@ class SchedulerCheck implements ShouldQueue
|
||||
Artisan::call('view:clear');
|
||||
} catch (\Exception $e) {
|
||||
nlog("I wasn't able to clear the views.");
|
||||
nlog($e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,6 +91,21 @@ class StartMigration implements ShouldQueue
|
||||
$archive = $zip->open(public_path("storage/{$this->filepath}"));
|
||||
$filename = pathinfo($this->filepath, PATHINFO_FILENAME);
|
||||
|
||||
if($this->company->id == $this->company->account->default_company_id)
|
||||
{
|
||||
$new_default_company = $this->company->account->companies->first();
|
||||
|
||||
if ($new_default_company) {
|
||||
$this->company->account->default_company_id = $new_default_company->id;
|
||||
$this->company->account->save();
|
||||
}
|
||||
}
|
||||
|
||||
$update_product_flag = $this->company->update_products;
|
||||
|
||||
$this->company->update_products = false;
|
||||
$this->company->save();
|
||||
|
||||
try {
|
||||
if (! $archive) {
|
||||
throw new ProcessingMigrationArchiveFailed('Processing migration archive failed. Migration file is possibly corrupted.');
|
||||
@ -113,7 +128,16 @@ class StartMigration implements ShouldQueue
|
||||
|
||||
Storage::deleteDirectory(public_path("storage/migrations/{$filename}"));
|
||||
|
||||
} catch (NonExistingMigrationFile | ProcessingMigrationArchiveFailed | ResourceNotAvailableForMigration | MigrationValidatorFailed | ResourceDependencyMissing $e) {
|
||||
$this->company->account->default_company_id = $this->company->id;
|
||||
$this->company->account->save();
|
||||
|
||||
$this->company->update_products = $update_product_flag;
|
||||
$this->company->save();
|
||||
|
||||
} catch (NonExistingMigrationFile | ProcessingMigrationArchiveFailed | ResourceNotAvailableForMigration | MigrationValidatorFailed | ResourceDependencyMissing | \Exception $e) {
|
||||
|
||||
$this->company->update_products = $update_product_flag;
|
||||
$this->company->save();
|
||||
|
||||
Mail::to($this->user)->send(new MigrationFailed($e, $e->getMessage()));
|
||||
|
||||
|
@ -54,6 +54,9 @@ class SystemLogger implements ShouldQueue
|
||||
'type_id' => $this->type_id,
|
||||
];
|
||||
|
||||
if(!$this->log)
|
||||
return;
|
||||
|
||||
SystemLog::create($sl);
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,10 @@ class VersionCheck implements ShouldQueue
|
||||
{
|
||||
$account = Account::first();
|
||||
|
||||
if($account->plan == 'white_label' && $account->plan_expires->lt(now())){
|
||||
if(!$account)
|
||||
return;
|
||||
|
||||
if($account->plan == 'white_label' && $account->plan_expires && $account->plan_expires->lt(now())){
|
||||
$account->plan = null;
|
||||
$account->plan_expires = null;
|
||||
$account->save();
|
||||
|
@ -42,7 +42,7 @@ class CreateAccountActivity implements ShouldQueue
|
||||
if(Ninja::isHosted())
|
||||
{
|
||||
$nmo = new NinjaMailerObject;
|
||||
$nmo->mailable = new Modules\Admin\Mail\Welcome($event->user);
|
||||
$nmo->mailable = new \Modules\Admin\Mail\Welcome($event->user);
|
||||
$nmo->company = $event->company;
|
||||
$nmo->settings = $event->company->settings;
|
||||
$nmo->to_user = $event->user;
|
||||
|
@ -47,6 +47,7 @@ class InvoiceEmailActivity implements ShouldQueue
|
||||
$fields->user_id = $event->invitation->invoice->user_id;
|
||||
$fields->company_id = $event->invitation->invoice->company_id;
|
||||
$fields->client_contact_id = $event->invitation->invoice->client_contact_id;
|
||||
$fields->client_id = $event->invitation->invoice->client_id;
|
||||
$fields->activity_type_id = Activity::EMAIL_INVOICE;
|
||||
|
||||
$this->activity_repo->save($fields, $event->invitation->invoice, $event->event_vars);
|
||||
|
@ -48,6 +48,7 @@ class QuoteEmailActivity implements ShouldQueue
|
||||
$fields->user_id = $event->invitation->quote->user_id;
|
||||
$fields->company_id = $event->invitation->quote->company_id;
|
||||
$fields->client_contact_id = $event->invitation->quote->client_contact_id;
|
||||
$fields->client_id = $event->invitation->quote->client_id;
|
||||
$fields->activity_type_id = Activity::EMAIL_QUOTE;
|
||||
|
||||
$this->activity_repo->save($fields, $event->invitation->quote, $event->event_vars);
|
||||
|
@ -62,20 +62,20 @@ class EntityCreatedObject
|
||||
switch ($this->entity_type) {
|
||||
case 'invoice':
|
||||
$this->template_subject = "texts.notification_invoice_created_subject";
|
||||
$this->template_body = "texts.notification_invoice_sent";
|
||||
$this->template_body = "texts.notification_invoice_created_body";
|
||||
break;
|
||||
case 'quote':
|
||||
$this->template_subject = "texts.notification_quote_created_subject";
|
||||
$this->template_body = "texts.notification_quote_sent";
|
||||
$this->template_body = "texts.notification_quote_created_body";
|
||||
break;
|
||||
case 'credit':
|
||||
$this->template_subject = "texts.notification_credit_created_subject";
|
||||
$this->template_body = "texts.notification_credit_sent";
|
||||
$this->template_body = "texts.notification_credit_created_body";
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->template_subject = "texts.notification_invoice_created_subject";
|
||||
$this->template_body = "texts.notification_invoice_sent";
|
||||
$this->template_body = "texts.notification_invoice_created_body";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -10,14 +10,22 @@ class ExistingMigration extends Mailable
|
||||
{
|
||||
// use Queueable, SerializesModels;
|
||||
|
||||
public $company;
|
||||
|
||||
public $settings;
|
||||
|
||||
public $logo;
|
||||
|
||||
public $company_name;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct($company)
|
||||
{
|
||||
//
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -27,8 +35,11 @@ class ExistingMigration extends Mailable
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
return $this->from(config('mail.from.address'), config('mail.from.name'))
|
||||
$this->settings = $this->company->settings;
|
||||
$this->logo = $this->company->present()->logo();
|
||||
$this->company_name = $this->company->present()->name();
|
||||
|
||||
return $this->from(config('mail.from.address'), config('mail.from.name'))
|
||||
->view('email.migration.existing');
|
||||
}
|
||||
}
|
||||
|
51
app/Mail/Migration/MaxCompanies.php
Normal file
51
app/Mail/Migration/MaxCompanies.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mail\Migration;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class MaxCompanies extends Mailable
|
||||
{
|
||||
// use Queueable, SerializesModels;
|
||||
|
||||
public $company;
|
||||
|
||||
public $settings;
|
||||
|
||||
public $logo;
|
||||
|
||||
public $title;
|
||||
|
||||
public $message;
|
||||
|
||||
public $whitelabel;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($company)
|
||||
{
|
||||
$this->company = $company;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
$this->settings = $this->company->settings;
|
||||
$this->logo = $this->company->present()->logo();
|
||||
$this->title = ctrans('texts.max_companies');
|
||||
$this->message = ctrans('texts.max_companies_desc');
|
||||
$this->whitelabel = $this->company->account->isPaid();
|
||||
|
||||
return $this->from(config('mail.from.address'), config('mail.from.name'))
|
||||
->view('email.migration.max_companies');
|
||||
}
|
||||
}
|
@ -79,8 +79,9 @@ class Client extends BaseModel implements HasLocalePreference
|
||||
|
||||
protected $with = [
|
||||
'gateway_tokens',
|
||||
'documents'
|
||||
//'currency',
|
||||
'documents',
|
||||
'contacts.company',
|
||||
// 'currency',
|
||||
// 'primary_contact',
|
||||
// 'country',
|
||||
// 'contacts',
|
||||
|
@ -88,6 +88,7 @@ class Company extends BaseModel
|
||||
'oauth_password_required',
|
||||
'invoice_task_datelog',
|
||||
'default_password_timeout',
|
||||
'show_task_end_date',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
|
@ -65,6 +65,7 @@ class CompanyGateway extends BaseModel
|
||||
'3758e7f7c6f4cecf0f4f348b9a00f456' => 304,
|
||||
'3b6621f970ab18887c4f6dca78d3f8bb' => 305,
|
||||
'54faab2ab6e3223dbe848b1686490baa' => 306,
|
||||
'd14dd26a47cecc30fdd65700bfb67b34' => 301,
|
||||
];
|
||||
|
||||
protected $touches = [];
|
||||
@ -225,7 +226,7 @@ class CompanyGateway extends BaseModel
|
||||
{
|
||||
$config = $this->getConfig();
|
||||
|
||||
if ($this->gateway->provider == 'Stripe' && strpos($config->publishableKey, 'test')) {
|
||||
if ($this->gateway->provider == 'Stripe' && property_exists($config, 'publishableKey') && strpos($config->publishableKey, 'test')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -128,6 +128,11 @@ class Credit extends BaseModel
|
||||
return $this->hasManyThrough(Backup::class, Activity::class);
|
||||
}
|
||||
|
||||
public function activities()
|
||||
{
|
||||
return $this->hasMany(Activity::class)->orderBy('id', 'DESC')->take(300);
|
||||
}
|
||||
|
||||
public function company()
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
@ -255,10 +260,10 @@ class Credit extends BaseModel
|
||||
}
|
||||
|
||||
if (! $invitation) {
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
CreateEntityPdf::dispatchNow($this->invitations->first());
|
||||
} else {
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
CreateEntityPdf::dispatchNow($invitation);
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ class CreditInvitation extends BaseModel
|
||||
$storage_path = Storage::url($this->credit->client->quote_filepath().$this->credit->numberFormatter().'.pdf');
|
||||
|
||||
if (! Storage::exists($this->credit->client->credit_filepath().$this->credit->numberFormatter().'.pdf')) {
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new CreditWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
CreateEntityPdf::dispatchNow($this);
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,7 @@ class Gateway extends StaticModel
|
||||
return [GatewayType::PAYPAL => ['refund' => true, 'token_billing' => false]]; //Paypal
|
||||
break;
|
||||
case 20:
|
||||
case 56:
|
||||
return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true],
|
||||
GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable']],
|
||||
GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false],
|
||||
|
@ -204,7 +204,7 @@ class Invoice extends BaseModel
|
||||
|
||||
public function activities()
|
||||
{
|
||||
return $this->hasMany(Activity::class);
|
||||
return $this->hasMany(Activity::class)->orderBy('id', 'DESC')->take(300);
|
||||
}
|
||||
|
||||
public function history()
|
||||
@ -249,19 +249,14 @@ class Invoice extends BaseModel
|
||||
$partial_due_date = $this->partial_due_Date ? Carbon::parse($this->partial_due_date) : false;
|
||||
|
||||
if ($this->status_id == self::STATUS_SENT && $due_date && $due_date->gt(now())) {
|
||||
nlog("1 unpaid");
|
||||
return self::STATUS_UNPAID;
|
||||
} elseif ($this->status_id == self::STATUS_PARTIAL && $partial_due_date && $partial_due_date->gt(now())) {
|
||||
nlog("2 partial");
|
||||
return self::STATUS_PARTIAL;
|
||||
} elseif ($this->status_id == self::STATUS_SENT && $due_date && $due_date->lt(now())) {
|
||||
nlog("3 overdue");
|
||||
return self::STATUS_OVERDUE;
|
||||
} elseif ($this->status_id == self::STATUS_PARTIAL && $partial_due_date && $partial_due_date->lt(now())) {
|
||||
nlog("4 overdue");
|
||||
return self::STATUS_OVERDUE;
|
||||
} else {
|
||||
nlog("status id ");
|
||||
return $this->status_id;
|
||||
}
|
||||
}
|
||||
@ -400,9 +395,19 @@ class Invoice extends BaseModel
|
||||
public function pdf_file_path($invitation = null, string $type = 'url')
|
||||
{
|
||||
if (! $invitation) {
|
||||
$invitation = $this->invitations->first();
|
||||
|
||||
if($this->invitations()->exists())
|
||||
$invitation = $this->invitations()->first();
|
||||
else{
|
||||
$this->service()->createInvitations();
|
||||
$invitation = $this->invitations()->first();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!$invitation)
|
||||
throw new \Exception('Hard fail, could not create an invitation - is there a valid contact?');
|
||||
|
||||
$storage_path = Storage::$type($this->client->invoice_filepath().$this->numberFormatter().'.pdf');
|
||||
|
||||
if (! Storage::exists($this->client->invoice_filepath().$this->numberFormatter().'.pdf')) {
|
||||
|
@ -243,7 +243,7 @@ class Payment extends BaseModel
|
||||
$this->status_id = $this->refunded == $this->amount ? self::STATUS_REFUNDED : self::STATUS_PARTIALLY_REFUNDED;
|
||||
$this->save();
|
||||
|
||||
event(new PaymentWasRefunded($this, $refund_change, $this->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new PaymentWasRefunded($this, $refund_change, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -280,7 +280,7 @@ class Payment extends BaseModel
|
||||
$this->status_id = self::STATUS_CANCELLED;
|
||||
$this->save();
|
||||
|
||||
event(new PaymentWasVoided($this, $this->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new PaymentWasVoided($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
}
|
||||
|
||||
public function getLink()
|
||||
|
@ -27,7 +27,8 @@ class ClientPresenter extends EntityPresenter
|
||||
return $this->entity->name;
|
||||
}
|
||||
|
||||
$contact = $this->entity->primary_contact->first();
|
||||
//$contact = $this->entity->primary_contact->first();
|
||||
$contact = $this->entity->contacts->first();
|
||||
|
||||
$contact_name = 'No Contact Set';
|
||||
|
||||
|
@ -130,6 +130,11 @@ class Quote extends BaseModel
|
||||
return $this->hasManyThrough(Backup::class, Activity::class);
|
||||
}
|
||||
|
||||
public function activities()
|
||||
{
|
||||
return $this->hasMany(Activity::class)->orderBy('id', 'DESC')->take(300);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class)->withTrashed();
|
||||
@ -213,7 +218,7 @@ class Quote extends BaseModel
|
||||
nlog($storage_path);
|
||||
|
||||
if (! Storage::exists($this->client->quote_filepath().$this->numberFormatter().'.pdf')) {
|
||||
event(new QuoteWasUpdated($this, $this->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new QuoteWasUpdated($this, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
CreateEntityPdf::dispatchNow($invitation);
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ class QuoteInvitation extends BaseModel
|
||||
$storage_path = Storage::url($this->quote->client->quote_filepath().$this->quote->numberFormatter().'.pdf');
|
||||
|
||||
if (! Storage::exists($this->quote->client->quote_filepath().$this->quote->numberFormatter().'.pdf')) {
|
||||
event(new QuoteWasUpdated($this->quote, $this->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new QuoteWasUpdated($this->quote, $this->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
CreateEntityPdf::dispatchNow($this);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace App\Observers;
|
||||
|
||||
use App\Events\Company\CompanyDocumentsDeleted;
|
||||
use App\Models\Company;
|
||||
use App\Utils\Ninja;
|
||||
|
||||
class CompanyObserver
|
||||
{
|
||||
@ -35,7 +36,16 @@ class CompanyObserver
|
||||
*/
|
||||
public function updated(Company $company)
|
||||
{
|
||||
//
|
||||
|
||||
if(Ninja::isHosted() && $company->portal_mode == 'domain' && $company->isDirty('portal_domain'))
|
||||
{
|
||||
nlog('company observer - updated');
|
||||
nlog($company->portal_domain);
|
||||
nlog($company->getOriginal('portal_domain'));
|
||||
|
||||
//fire event to build new custom portal domain
|
||||
\Modules\Admin\Jobs\Domain\CustomDomain::dispatch($company->getOriginal('portal_domain'), $company)->onQueue('domain');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,7 +55,7 @@ class BaseRepository
|
||||
$className = $this->getEventClass($entity, 'Archived');
|
||||
|
||||
if (class_exists($className)) {
|
||||
event(new $className($entity, $entity->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new $className($entity, $entity->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ class BaseRepository
|
||||
$className = $this->getEventClass($entity, 'Restored');
|
||||
|
||||
if (class_exists($className)) {
|
||||
event(new $className($entity, $fromDeleted, $entity->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new $className($entity, $fromDeleted, $entity->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ class BaseRepository
|
||||
$className = $this->getEventClass($entity, 'Deleted');
|
||||
|
||||
if (class_exists($className) && ! ($entity instanceof Company)) {
|
||||
event(new $className($entity, $entity->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new $className($entity, $entity->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,11 +302,6 @@ class BaseRepository
|
||||
/* Perform model specific tasks */
|
||||
if ($model instanceof Invoice) {
|
||||
|
||||
nlog("in base");
|
||||
nlog($state['finished_amount']);
|
||||
nlog($state['starting_amount']);
|
||||
nlog($model->status_id);
|
||||
|
||||
if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) {
|
||||
|
||||
$model->service()->updateStatus()->save();
|
||||
|
@ -23,6 +23,7 @@ use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Repositories\BaseRepository;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\SavesDocuments;
|
||||
use Illuminate\Support\Carbon;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
@ -59,6 +60,12 @@ class InvoiceMigrationRepository extends BaseRepository
|
||||
|
||||
$tmp_data = $data;
|
||||
|
||||
if(array_key_exists('tax_rate1', $tmp_data) && is_null($tmp_data['tax_rate1']))
|
||||
$tmp_data['tax_rate1'] = 0;
|
||||
|
||||
if(array_key_exists('tax_rate2', $tmp_data) && is_null($tmp_data['tax_rate2']))
|
||||
$tmp_data['tax_rate2'] = 0;
|
||||
|
||||
/* We need to unset some variable as we sometimes unguard the model */
|
||||
|
||||
if (isset($tmp_data['invitations'])) {
|
||||
@ -71,7 +78,15 @@ class InvoiceMigrationRepository extends BaseRepository
|
||||
|
||||
$model->fill($tmp_data);
|
||||
$model->status_id = $tmp_data['status_id'];
|
||||
$model->save();
|
||||
|
||||
if($tmp_data['created_at'])
|
||||
$model->created_at = Carbon::parse($tmp_data['created_at']);
|
||||
|
||||
if($tmp_data['updated_at'])
|
||||
$model->updated_at = Carbon::parse($tmp_data['updated_at']);
|
||||
|
||||
$model->save(['timestamps' => false]);
|
||||
|
||||
|
||||
if (array_key_exists('documents', $data)) {
|
||||
$this->saveDocuments($data['documents'], $model);
|
||||
@ -107,35 +122,7 @@ class InvoiceMigrationRepository extends BaseRepository
|
||||
|
||||
InvoiceInvitation::reguard();
|
||||
RecurringInvoiceInvitation::reguard();
|
||||
/*
|
||||
if (isset($data['invitations'])) {
|
||||
$invitations = collect($data['invitations']);
|
||||
|
||||
$model->invitations->pluck('key')->diff($invitations->pluck('key'))->each(function ($invitation) use ($resource) {
|
||||
$this->getInvitation($invitation, $resource)->delete();
|
||||
});
|
||||
|
||||
foreach ($data['invitations'] as $invitation) {
|
||||
|
||||
//if no invitations are present - create one.
|
||||
if (! $this->getInvitation($invitation, $resource)) {
|
||||
if (isset($invitation['id'])) {
|
||||
unset($invitation['id']);
|
||||
}
|
||||
|
||||
//make sure we are creating an invite for a contact who belongs to the client only!
|
||||
$contact = ClientContact::find($invitation['client_contact_id']);
|
||||
|
||||
if ($contact && $model->client_id == $contact->client_id) {
|
||||
$new_invitation = $invitation_factory_class::create($model->company_id, $model->user_id);
|
||||
$new_invitation->{$lcfirst_resource_id} = $model->id;
|
||||
$new_invitation->client_contact_id = $contact->id;
|
||||
$new_invitation->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
$model->load('invitations');
|
||||
|
||||
/* If no invitations have been created, this is our fail safe to maintain state*/
|
||||
@ -152,18 +139,12 @@ class InvoiceMigrationRepository extends BaseRepository
|
||||
if ($class->name == Invoice::class || $class->name == RecurringInvoice::class) {
|
||||
if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) {
|
||||
|
||||
// $model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount']));
|
||||
// $model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save();
|
||||
}
|
||||
|
||||
if (! $model->design_id) {
|
||||
$model->design_id = $this->decodePrimaryKey($client->getSetting('invoice_design_id'));
|
||||
}
|
||||
|
||||
|
||||
if ($model->company->update_products !== false) {
|
||||
UpdateOrCreateProduct::dispatchNow($model->line_items, $model, $model->company);
|
||||
}
|
||||
}
|
||||
|
||||
if ($class->name == Credit::class) {
|
||||
|
@ -159,7 +159,7 @@ class PaymentRepository extends BaseRepository {
|
||||
if ($payment->client->getSetting('client_manual_payment_notification'))
|
||||
$payment->service()->sendEmail();
|
||||
|
||||
event( new PaymentWasCreated( $payment, $payment->company, Ninja::eventVars(auth()->user()->id) ) );
|
||||
event( new PaymentWasCreated( $payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null) ) );
|
||||
}
|
||||
|
||||
nlog("payment amount = {$payment->amount}");
|
||||
@ -209,7 +209,7 @@ class PaymentRepository extends BaseRepository {
|
||||
|
||||
$payment = $payment->service()->deletePayment();
|
||||
|
||||
event(new PaymentWasDeleted($payment, $payment->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new PaymentWasDeleted($payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
return $payment;
|
||||
//return parent::delete($payment);
|
||||
|
@ -89,11 +89,23 @@ class UserRepository extends BaseRepository
|
||||
$data['company_user']['notifications'] = CompanySettings::notificationDefaults();
|
||||
$user->companies()->attach($company->id, $data['company_user']);
|
||||
} else {
|
||||
|
||||
if(auth()->user()->isAdmin())
|
||||
{
|
||||
$cu->fill($data['company_user']);
|
||||
$cu->restore();
|
||||
$cu->tokens()->restore();
|
||||
$cu->save();
|
||||
}
|
||||
else {
|
||||
|
||||
$cu->notifications = $data['company_user']['notifications'];
|
||||
$cu->settings = $data['company_user']['settings'];
|
||||
$cu->save();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$user->with(['company_users' => function ($query) use ($company, $user) {
|
||||
$query->whereCompanyId($company->id)
|
||||
@ -123,7 +135,7 @@ class UserRepository extends BaseRepository
|
||||
$cu->forceDelete();
|
||||
}
|
||||
|
||||
event(new UserWasDeleted($user, $company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new UserWasDeleted($user, $company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
$user->delete();
|
||||
|
||||
@ -146,7 +158,7 @@ class UserRepository extends BaseRepository
|
||||
$cu->delete();
|
||||
}
|
||||
|
||||
event(new UserWasDeleted($user, auth()->user(), $company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new UserWasDeleted($user, auth()->user(), $company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
$user->is_deleted = true;
|
||||
$user->save();
|
||||
@ -164,7 +176,7 @@ class UserRepository extends BaseRepository
|
||||
|
||||
$user->delete();
|
||||
|
||||
event(new UserWasArchived($user, auth()->user(), auth()->user()->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new UserWasArchived($user, auth()->user(), auth()->user()->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
}
|
||||
|
||||
@ -189,7 +201,7 @@ class UserRepository extends BaseRepository
|
||||
|
||||
$cu->restore();
|
||||
|
||||
event(new UserWasRestored($user, auth()->user(), auth()->user()->company, Ninja::eventVars(auth()->user()->id)));
|
||||
event(new UserWasRestored($user, auth()->user(), auth()->user()->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,16 @@ class CreateInvitations extends AbstractService
|
||||
}
|
||||
});
|
||||
|
||||
if($this->invoice->invitations()->count() == 0) {
|
||||
|
||||
$contact = $this->createBlankContact();
|
||||
|
||||
$ii = InvoiceInvitationFactory::create($this->invoice->company_id, $this->invoice->user_id);
|
||||
$ii->invoice_id = $this->invoice->id;
|
||||
$ii->client_contact_id = $contact->id;
|
||||
$ii->save();
|
||||
}
|
||||
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
@ -65,5 +75,7 @@ class CreateInvitations extends AbstractService
|
||||
$new_contact->contact_key = Str::random(40);
|
||||
$new_contact->is_primary = true;
|
||||
$new_contact->save();
|
||||
|
||||
return $new_contact;
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class GenerateDeliveryNote
|
||||
|
||||
$file_path = sprintf('%s%s_delivery_note.pdf', $this->invoice->client->invoice_filepath(), $this->invoice->number);
|
||||
|
||||
if (config('ninja.phantomjs_pdf_generation')) {
|
||||
if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') {
|
||||
return (new Phantom)->generate($this->invoice->invitations->first());
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ class GenerateDeliveryNote
|
||||
|
||||
// Storage::makeDirectory($this->invoice->client->invoice_filepath(), 0775);
|
||||
|
||||
if(config('ninja.invoiceninja_hosted_pdf_generation')){
|
||||
if(config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja'){
|
||||
$pdf = (new NinjaPdf())->build($maker->getCompiledHTML(true));
|
||||
}
|
||||
else {
|
||||
|
@ -110,6 +110,7 @@ class InvoiceService
|
||||
|
||||
public function addGatewayFee(CompanyGateway $company_gateway, $gateway_type_id, float $amount)
|
||||
{
|
||||
|
||||
$this->invoice = (new AddGatewayFee($company_gateway, $gateway_type_id, $this->invoice, $amount))->run();
|
||||
|
||||
return $this;
|
||||
|
@ -112,10 +112,10 @@ class RefundPayment
|
||||
if (isset($this->refund_data['invoices'])) {
|
||||
foreach ($this->refund_data['invoices'] as $invoice) {
|
||||
$fields->invoice_id = $invoice['invoice_id'];
|
||||
$activity_repo->save($fields, $this->payment, Ninja::eventVars(auth()->user()->id));
|
||||
$activity_repo->save($fields, $this->payment, Ninja::eventVars(auth()->user() ? auth()->user()->id : null));
|
||||
}
|
||||
} else {
|
||||
$activity_repo->save($fields, $this->payment, Ninja::eventVars(auth()->user()->id));
|
||||
$activity_repo->save($fields, $this->payment, Ninja::eventVars(auth()->user() ? auth()->user()->id : null));
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@ -157,6 +157,8 @@ class CompanyTransformer extends EntityTransformer
|
||||
'oauth_password_required' => (bool)$company->oauth_password_required,
|
||||
'session_timeout' => (int)$company->session_timeout,
|
||||
'default_password_timeout' => (int) $company->default_password_timeout,
|
||||
'invoice_task_datelog' => (bool) $company->invoice_task_datelog,
|
||||
'show_task_end_date' => (bool) $company->show_task_end_date,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,12 @@ class CompanyUserTransformer extends EntityTransformer
|
||||
|
||||
public function transform(CompanyUser $company_user)
|
||||
{
|
||||
$blank_obj = new \stdClass;
|
||||
|
||||
return [
|
||||
'permissions' => $company_user->permissions ?: '',
|
||||
'notifications' => (object) $company_user->notifications,
|
||||
'settings' => (object) $company_user->settings,
|
||||
'notifications' => (object) $company_user->notifications ?: $blank_obj,
|
||||
'settings' => (object) $company_user->settings ?: $blank_obj,
|
||||
'is_owner' => (bool) $company_user->is_owner,
|
||||
'is_admin' => (bool) $company_user->is_admin,
|
||||
'is_locked' => (bool) $company_user->is_locked,
|
||||
@ -49,6 +51,7 @@ class CompanyUserTransformer extends EntityTransformer
|
||||
'archived_at' => (int) $company_user->deleted_at,
|
||||
'created_at' => (int) $company_user->created_at,
|
||||
'permissions_updated_at' => (int) $company_user->permissions_updated_at,
|
||||
//'number_years_active' => (int) $company_user->number_years_active,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ class CreditInvitationTransformer extends EntityTransformer
|
||||
'updated_at' => (int) $invitation->updated_at,
|
||||
'archived_at' => (int) $invitation->deleted_at,
|
||||
'created_at' => (int) $invitation->created_at,
|
||||
'email_status' => $invitation->email_status,
|
||||
'email_status' => $invitation->email_status ?: '',
|
||||
'email_error' => (string)$invitation->email_error,
|
||||
];
|
||||
}
|
||||
|
@ -11,10 +11,12 @@
|
||||
|
||||
namespace App\Transformers;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\Backup;
|
||||
use App\Models\Credit;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\Document;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class CreditTransformer extends EntityTransformer
|
||||
@ -31,8 +33,16 @@ class CreditTransformer extends EntityTransformer
|
||||
'history',
|
||||
// 'client',
|
||||
'documents',
|
||||
'activities',
|
||||
];
|
||||
|
||||
public function includeActivities(Credit $credit)
|
||||
{
|
||||
$transformer = new ActivityTransformer($this->serializer);
|
||||
|
||||
return $this->includeCollection($credit->activities, $transformer, Activity::class);
|
||||
}
|
||||
|
||||
public function includeHistory(Credit $credit)
|
||||
{
|
||||
$transformer = new InvoiceHistoryTransformer($this->serializer);
|
||||
|
@ -31,7 +31,7 @@ class InvoiceInvitationTransformer extends EntityTransformer
|
||||
'updated_at' => (int) $invitation->updated_at,
|
||||
'archived_at' => (int) $invitation->deleted_at,
|
||||
'created_at' => (int) $invitation->created_at,
|
||||
'email_status' => $invitation->email_status,
|
||||
'email_status' => $invitation->email_status ?: '',
|
||||
'email_error' => (string)$invitation->email_error,
|
||||
];
|
||||
}
|
||||
|
@ -11,12 +11,14 @@
|
||||
|
||||
namespace App\Transformers;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\Backup;
|
||||
use App\Models\Client;
|
||||
use App\Models\Document;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\Payment;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class InvoiceTransformer extends EntityTransformer
|
||||
@ -33,6 +35,7 @@ class InvoiceTransformer extends EntityTransformer
|
||||
'history',
|
||||
'payments',
|
||||
'client',
|
||||
'activities',
|
||||
// 'documents',
|
||||
];
|
||||
|
||||
@ -80,6 +83,14 @@ class InvoiceTransformer extends EntityTransformer
|
||||
return $this->includeCollection($invoice->documents, $transformer, Document::class);
|
||||
}
|
||||
|
||||
public function includeActivities(Invoice $invoice)
|
||||
{
|
||||
$transformer = new ActivityTransformer($this->serializer);
|
||||
|
||||
return $this->includeCollection($invoice->activities, $transformer, Activity::class);
|
||||
}
|
||||
|
||||
|
||||
public function transform(Invoice $invoice)
|
||||
{
|
||||
return [
|
||||
|
@ -31,7 +31,7 @@ class QuoteInvitationTransformer extends EntityTransformer
|
||||
'updated_at' => (int) $invitation->updated_at,
|
||||
'archived_at' => (int) $invitation->deleted_at,
|
||||
'created_at' => (int) $invitation->created_at,
|
||||
'email_status' => $invitation->email_status,
|
||||
'email_status' => $invitation->email_status ?: '',
|
||||
'email_error' => (string)$invitation->email_error,
|
||||
];
|
||||
}
|
||||
|
@ -11,10 +11,12 @@
|
||||
|
||||
namespace App\Transformers;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\Backup;
|
||||
use App\Models\Document;
|
||||
use App\Models\Quote;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class QuoteTransformer extends EntityTransformer
|
||||
@ -30,10 +32,18 @@ class QuoteTransformer extends EntityTransformer
|
||||
'invitations',
|
||||
'documents',
|
||||
'history',
|
||||
'activities',
|
||||
// 'payments',
|
||||
// 'client',
|
||||
];
|
||||
|
||||
public function includeActivities(Quote $quote)
|
||||
{
|
||||
$transformer = new ActivityTransformer($this->serializer);
|
||||
|
||||
return $this->includeCollection($quote->activities, $transformer, Activity::class);
|
||||
}
|
||||
|
||||
public function includeHistory(Quote $quote)
|
||||
{
|
||||
$transformer = new InvoiceHistoryTransformer($this->serializer);
|
||||
|
@ -31,7 +31,7 @@ class RecurringInvoiceInvitationTransformer extends EntityTransformer
|
||||
'updated_at' => (int) $invitation->updated_at,
|
||||
'archived_at' => (int) $invitation->deleted_at,
|
||||
'created_at' => (int) $invitation->created_at,
|
||||
'email_status' => $invitation->email_status,
|
||||
'email_status' => $invitation->email_status ?: '',
|
||||
'email_error' => (string)$invitation->email_error,
|
||||
];
|
||||
}
|
||||
|
@ -11,10 +11,12 @@
|
||||
|
||||
namespace App\Transformers;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\Document;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\RecurringInvoice;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Transformers\ActivityTransformer;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class RecurringInvoiceTransformer extends EntityTransformer
|
||||
@ -29,6 +31,7 @@ class RecurringInvoiceTransformer extends EntityTransformer
|
||||
protected $availableIncludes = [
|
||||
'invitations',
|
||||
'documents',
|
||||
'activities',
|
||||
// 'payments',
|
||||
// 'client',
|
||||
];
|
||||
@ -62,6 +65,13 @@ class RecurringInvoiceTransformer extends EntityTransformer
|
||||
return $this->includeItem($invoice->client, $transformer, ENTITY_CLIENT);
|
||||
}
|
||||
*/
|
||||
public function includeActivities(RecurringInvoice $invoice)
|
||||
{
|
||||
$transformer = new ActivityTransformer($this->serializer);
|
||||
|
||||
return $this->includeCollection($invoice->activities, $transformer, Activity::class);
|
||||
}
|
||||
|
||||
public function includeInvitations(RecurringInvoice $invoice)
|
||||
{
|
||||
$transformer = new RecurringInvoiceInvitationTransformer($this->serializer);
|
||||
|
@ -238,7 +238,7 @@ class HtmlEngine
|
||||
$data['$vat_number'] = ['value' => $this->client->vat_number ?: ' ', 'label' => ctrans('texts.vat_number')];
|
||||
$data['$website'] = ['value' => $this->client->present()->website() ?: ' ', 'label' => ctrans('texts.website')];
|
||||
$data['$phone'] = ['value' => $this->client->present()->phone() ?: ' ', 'label' => ctrans('texts.phone')];
|
||||
$data['$country'] = ['value' => isset($this->client->country->name) ? $this->client->country->name : '', 'label' => ctrans('texts.country')];
|
||||
$data['$country'] = ['value' => isset($this->client->country->name) ? ctrans('texts.country_' . $this->client->country->name) : '', 'label' => ctrans('texts.country')];
|
||||
$data['$email'] = ['value' => isset($this->contact) ? $this->contact->email : 'no contact email on record', 'label' => ctrans('texts.email')];
|
||||
$data['$client_name'] = ['value' => $this->entity->present()->clientName() ?: ' ', 'label' => ctrans('texts.client_name')];
|
||||
$data['$client.name'] = &$data['$client_name'];
|
||||
@ -460,7 +460,7 @@ class HtmlEngine
|
||||
$country = Country::find($this->settings->country_id);
|
||||
|
||||
if ($country) {
|
||||
return $country->name;
|
||||
return ctrans('texts.country_' . $country->name);
|
||||
}
|
||||
|
||||
return ' ';
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Utils;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
@ -69,6 +70,28 @@ class Statics
|
||||
$data = [];
|
||||
|
||||
foreach (config('ninja.cached_tables') as $name => $class) {
|
||||
|
||||
// if (!Cache::has($name)) {
|
||||
|
||||
// // check that the table exists in case the migration is pending
|
||||
// if (!Schema::hasTable((new $class())->getTable())) {
|
||||
// continue;
|
||||
// }
|
||||
// if ($name == 'payment_terms') {
|
||||
// $orderBy = 'num_days';
|
||||
// } elseif ($name == 'fonts') {
|
||||
// $orderBy = 'sort_order';
|
||||
// } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) {
|
||||
// $orderBy = 'name';
|
||||
// } else {
|
||||
// $orderBy = 'id';
|
||||
// }
|
||||
// $tableData = $class::orderBy($orderBy)->get();
|
||||
// if ($tableData->count()) {
|
||||
// Cache::forever($name, $tableData);
|
||||
// }
|
||||
// }
|
||||
|
||||
$data[$name] = Cache::get($name);
|
||||
}
|
||||
|
||||
|
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