mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
commit
e6482064eb
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.59
|
5.1.60
|
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],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
77
app/DataMapper/Analytics/Mail/EmailBounce.php
Normal file
77
app/DataMapper/Analytics/Mail/EmailBounce.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?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;
|
||||||
|
|
||||||
|
class EmailBounce
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
77
app/DataMapper/Analytics/Mail/EmailSpam.php
Normal file
77
app/DataMapper/Analytics/Mail/EmailSpam.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?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;
|
||||||
|
|
||||||
|
class EmailSpam
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
@ -14,12 +14,14 @@ namespace App\Http\Controllers;
|
|||||||
use App\Http\Requests\Activity\DownloadHistoricalEntityRequest;
|
use App\Http\Requests\Activity\DownloadHistoricalEntityRequest;
|
||||||
use App\Models\Activity;
|
use App\Models\Activity;
|
||||||
use App\Transformers\ActivityTransformer;
|
use App\Transformers\ActivityTransformer;
|
||||||
|
use App\Utils\HostedPDF\NinjaPdf;
|
||||||
|
use App\Utils\PhantomJS\Phantom;
|
||||||
use App\Utils\Traits\Pdf\PdfMaker;
|
use App\Utils\Traits\Pdf\PdfMaker;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use stdClass;
|
|
||||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
class ActivityController extends BaseController
|
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);
|
return response()->json(['message'=> ctrans('texts.no_backup_exists'), 'errors' => new stdClass], 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config('ninja.phantomjs_pdf_generation')) {
|
||||||
|
$pdf = (new Phantom)->convertHtmlToPdf($backup->html_backup);
|
||||||
|
}
|
||||||
|
elseif(config('ninja.invoiceninja_hosted_pdf_generation')){
|
||||||
|
$pdf = (new NinjaPdf())->build($backup->html_backup);
|
||||||
|
}
|
||||||
|
else {
|
||||||
$pdf = $this->makePdf(null, null, $backup->html_backup);
|
$pdf = $this->makePdf(null, null, $backup->html_backup);
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($activity->invoice_id)) {
|
if (isset($activity->invoice_id)) {
|
||||||
$filename = $activity->invoice->numberFormatter().'.pdf';
|
$filename = $activity->invoice->numberFormatter().'.pdf';
|
||||||
|
@ -395,7 +395,8 @@ class BaseController extends Controller
|
|||||||
'company' => function ($query) use ($created_at, $user) {
|
'company' => function ($query) use ($created_at, $user) {
|
||||||
$query->whereNotNull('created_at')->with('documents');
|
$query->whereNotNull('created_at')->with('documents');
|
||||||
},
|
},
|
||||||
'company.clients' => function ($query) use ($user) {
|
'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'))
|
if(!$user->hasPermission('view_client'))
|
||||||
$query->where('clients.user_id', $user->id)->orWhere('clients.assigned_user_id', $user->id);
|
$query->where('clients.user_id', $user->id)->orWhere('clients.assigned_user_id', $user->id);
|
||||||
|
@ -50,6 +50,8 @@ class InvoiceController extends Controller
|
|||||||
{
|
{
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
|
|
||||||
|
$invoice->service()->removeUnpaidGatewayFees()->save();
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'invoice' => $invoice,
|
'invoice' => $invoice,
|
||||||
];
|
];
|
||||||
|
@ -97,6 +97,10 @@ class PaymentController extends Controller
|
|||||||
$payable_invoices = collect($request->payable_invoices);
|
$payable_invoices = collect($request->payable_invoices);
|
||||||
$invoices = Invoice::whereIn('id', $this->transformKeys($payable_invoices->pluck('invoice_id')->toArray()))->get();
|
$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 */
|
/* pop non payable invoice from the $payable_invoices array */
|
||||||
|
|
||||||
$payable_invoices = $payable_invoices->filter(function ($payable_invoice) use ($invoices) {
|
$payable_invoices = $payable_invoices->filter(function ($payable_invoice) use ($invoices) {
|
||||||
|
@ -18,6 +18,7 @@ use App\Jobs\Mail\NinjaMailerJob;
|
|||||||
use App\Jobs\Mail\NinjaMailerObject;
|
use App\Jobs\Mail\NinjaMailerObject;
|
||||||
use App\Jobs\Util\StartMigration;
|
use App\Jobs\Util\StartMigration;
|
||||||
use App\Mail\ExistingMigration;
|
use App\Mail\ExistingMigration;
|
||||||
|
use App\Mail\Migration\MaxCompanies;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\CompanyToken;
|
use App\Models\CompanyToken;
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
@ -231,19 +232,51 @@ class MigrationController extends BaseController
|
|||||||
nlog($request->all());
|
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) {
|
foreach ($companies as $company) {
|
||||||
$is_valid = $request->file($company->company_index)->isValid();
|
$is_valid = $request->file($company->company_index)->isValid();
|
||||||
|
|
||||||
if (!$is_valid) {
|
if (!$is_valid) {
|
||||||
// We might want to send user something's wrong with migration or nope?
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$company_count = $user->account->companies()->count();
|
||||||
|
|
||||||
// Look for possible existing company (based on company keys).
|
// Look for possible existing company (based on company keys).
|
||||||
$existing_company = Company::whereRaw('BINARY `company_key` = ?', [$company->company_key])->first();
|
$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 = [
|
$checks = [
|
||||||
'existing_company' => $existing_company ? (bool)1 : false,
|
'existing_company' => $existing_company ? (bool)1 : false,
|
||||||
'force' => property_exists($company, 'force') ? (bool) $company->force : false,
|
'force' => property_exists($company, 'force') ? (bool) $company->force : false,
|
||||||
@ -254,9 +287,9 @@ class MigrationController extends BaseController
|
|||||||
nlog('Migrating: Existing company without force. (CASE_01)');
|
nlog('Migrating: Existing company without force. (CASE_01)');
|
||||||
|
|
||||||
$nmo = new NinjaMailerObject;
|
$nmo = new NinjaMailerObject;
|
||||||
$nmo->mailable = new ExistingMigration();
|
$nmo->mailable = new ExistingMigration($existing_company);
|
||||||
$nmo->company = $existing_company;
|
$nmo->company = $user->account->companies()->first();
|
||||||
$nmo->settings = $existing_company->settings;
|
$nmo->settings = $user->account->companies()->first();
|
||||||
$nmo->to_user = $user;
|
$nmo->to_user = $user;
|
||||||
|
|
||||||
NinjaMailerJob::dispatch($nmo);
|
NinjaMailerJob::dispatch($nmo);
|
||||||
@ -355,10 +388,7 @@ class MigrationController extends BaseController
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
return response()->json([
|
}
|
||||||
'_id' => Str::uuid(),
|
|
||||||
'method' => config('queue.default'),
|
|
||||||
'started_at' => now(),
|
|
||||||
], 200);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\DataMapper\Analytics\EmailBounce;
|
||||||
|
use App\DataMapper\Analytics\EmailSpam;
|
||||||
use App\Jobs\Util\SystemLogger;
|
use App\Jobs\Util\SystemLogger;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use App\Models\CreditInvitation;
|
use App\Models\CreditInvitation;
|
||||||
@ -19,6 +21,7 @@ use App\Models\QuoteInvitation;
|
|||||||
use App\Models\RecurringInvoiceInvitation;
|
use App\Models\RecurringInvoiceInvitation;
|
||||||
use App\Models\SystemLog;
|
use App\Models\SystemLog;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PostMarkController.
|
* Class PostMarkController.
|
||||||
@ -71,8 +74,7 @@ class PostMarkController extends BaseController
|
|||||||
|
|
||||||
if($request->header('X-API-SECURITY') && $request->header('X-API-SECURITY') == config('postmark.secret'))
|
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'));
|
MultiDB::findAndSetDbByCompanyKey($request->input('Tag'));
|
||||||
|
|
||||||
@ -157,6 +159,14 @@ class PostMarkController extends BaseController
|
|||||||
$this->invitation->email_status = 'bounced';
|
$this->invitation->email_status = 'bounced';
|
||||||
$this->invitation->save();
|
$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);
|
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->email_status = 'spam';
|
||||||
$this->invitation->save();
|
$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);
|
SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ use App\Factory\VendorFactory;
|
|||||||
use App\Http\Requests\Company\UpdateCompanyRequest;
|
use App\Http\Requests\Company\UpdateCompanyRequest;
|
||||||
use App\Http\ValidationRules\ValidCompanyGatewayFeesAndLimitsRule;
|
use App\Http\ValidationRules\ValidCompanyGatewayFeesAndLimitsRule;
|
||||||
use App\Http\ValidationRules\ValidUserForCompany;
|
use App\Http\ValidationRules\ValidUserForCompany;
|
||||||
|
use App\Jobs\Company\CreateCompanyTaskStatuses;
|
||||||
use App\Jobs\Company\CreateCompanyToken;
|
use App\Jobs\Company\CreateCompanyToken;
|
||||||
use App\Jobs\Ninja\CheckCompanyData;
|
use App\Jobs\Ninja\CheckCompanyData;
|
||||||
use App\Jobs\Ninja\CompanySizeCheck;
|
use App\Jobs\Ninja\CompanySizeCheck;
|
||||||
@ -82,10 +83,10 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
|||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Turbo124\Beacon\Facades\LightLogs;
|
use Turbo124\Beacon\Facades\LightLogs;
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
|
|
||||||
class Import implements ShouldQueue
|
class Import implements ShouldQueue
|
||||||
{
|
{
|
||||||
@ -230,6 +231,9 @@ class Import implements ShouldQueue
|
|||||||
$this->company->save();
|
$this->company->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateCompanyPaymentTerms::dispatchNow($sp035a66, $spaa9f78);
|
||||||
|
CreateCompanyTaskStatuses::dispatchNow($this->company, $this->user);
|
||||||
|
|
||||||
info('Completed🚀🚀🚀🚀🚀 at '.now());
|
info('Completed🚀🚀🚀🚀🚀 at '.now());
|
||||||
|
|
||||||
unlink($this->file_path);
|
unlink($this->file_path);
|
||||||
|
@ -109,7 +109,7 @@ class StartMigration implements ShouldQueue
|
|||||||
throw new NonExistingMigrationFile('Migration file does not exist, or it is corrupted.');
|
throw new NonExistingMigrationFile('Migration file does not exist, or it is corrupted.');
|
||||||
}
|
}
|
||||||
|
|
||||||
Import::dispatchNow($file, $this->company, $this->user)->onQueue('migration');
|
Import::dispatchNow($file, $this->company, $this->user);
|
||||||
|
|
||||||
Storage::deleteDirectory(public_path("storage/migrations/{$filename}"));
|
Storage::deleteDirectory(public_path("storage/migrations/{$filename}"));
|
||||||
|
|
||||||
|
@ -62,20 +62,20 @@ class EntityCreatedObject
|
|||||||
switch ($this->entity_type) {
|
switch ($this->entity_type) {
|
||||||
case 'invoice':
|
case 'invoice':
|
||||||
$this->template_subject = "texts.notification_invoice_created_subject";
|
$this->template_subject = "texts.notification_invoice_created_subject";
|
||||||
$this->template_body = "texts.notification_invoice_sent";
|
$this->template_body = "texts.notification_invoice_created_body";
|
||||||
break;
|
break;
|
||||||
case 'quote':
|
case 'quote':
|
||||||
$this->template_subject = "texts.notification_quote_created_subject";
|
$this->template_subject = "texts.notification_quote_created_subject";
|
||||||
$this->template_body = "texts.notification_quote_sent";
|
$this->template_body = "texts.notification_quote_created_body";
|
||||||
break;
|
break;
|
||||||
case 'credit':
|
case 'credit':
|
||||||
$this->template_subject = "texts.notification_credit_created_subject";
|
$this->template_subject = "texts.notification_credit_created_subject";
|
||||||
$this->template_body = "texts.notification_credit_sent";
|
$this->template_body = "texts.notification_credit_created_body";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$this->template_subject = "texts.notification_invoice_created_subject";
|
$this->template_subject = "texts.notification_invoice_created_subject";
|
||||||
$this->template_body = "texts.notification_invoice_sent";
|
$this->template_body = "texts.notification_invoice_created_body";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,22 @@ class ExistingMigration extends Mailable
|
|||||||
{
|
{
|
||||||
// use Queueable, SerializesModels;
|
// use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
public $company;
|
||||||
|
|
||||||
|
public $settings;
|
||||||
|
|
||||||
|
public $logo;
|
||||||
|
|
||||||
|
public $company_name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new message instance.
|
* Create a new message instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct($company)
|
||||||
{
|
{
|
||||||
//
|
$this->company = $company;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,8 +35,11 @@ class ExistingMigration extends Mailable
|
|||||||
*/
|
*/
|
||||||
public function build()
|
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');
|
->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 = [
|
protected $with = [
|
||||||
'gateway_tokens',
|
'gateway_tokens',
|
||||||
'documents'
|
'documents',
|
||||||
//'currency',
|
'contacts.company',
|
||||||
|
// 'currency',
|
||||||
// 'primary_contact',
|
// 'primary_contact',
|
||||||
// 'country',
|
// 'country',
|
||||||
// 'contacts',
|
// 'contacts',
|
||||||
|
@ -65,6 +65,7 @@ class CompanyGateway extends BaseModel
|
|||||||
'3758e7f7c6f4cecf0f4f348b9a00f456' => 304,
|
'3758e7f7c6f4cecf0f4f348b9a00f456' => 304,
|
||||||
'3b6621f970ab18887c4f6dca78d3f8bb' => 305,
|
'3b6621f970ab18887c4f6dca78d3f8bb' => 305,
|
||||||
'54faab2ab6e3223dbe848b1686490baa' => 306,
|
'54faab2ab6e3223dbe848b1686490baa' => 306,
|
||||||
|
'd14dd26a47cecc30fdd65700bfb67b34' => 301,
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $touches = [];
|
protected $touches = [];
|
||||||
@ -225,7 +226,7 @@ class CompanyGateway extends BaseModel
|
|||||||
{
|
{
|
||||||
$config = $this->getConfig();
|
$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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +85,7 @@ class Gateway extends StaticModel
|
|||||||
return [GatewayType::PAYPAL => ['refund' => true, 'token_billing' => false]]; //Paypal
|
return [GatewayType::PAYPAL => ['refund' => true, 'token_billing' => false]]; //Paypal
|
||||||
break;
|
break;
|
||||||
case 20:
|
case 20:
|
||||||
|
case 56:
|
||||||
return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true],
|
return [GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true],
|
||||||
GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable']],
|
GatewayType::BANK_TRANSFER => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable']],
|
||||||
GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false],
|
GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false],
|
||||||
|
@ -27,7 +27,8 @@ class ClientPresenter extends EntityPresenter
|
|||||||
return $this->entity->name;
|
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';
|
$contact_name = 'No Contact Set';
|
||||||
|
|
||||||
|
@ -107,35 +107,7 @@ class InvoiceMigrationRepository extends BaseRepository
|
|||||||
|
|
||||||
InvoiceInvitation::reguard();
|
InvoiceInvitation::reguard();
|
||||||
RecurringInvoiceInvitation::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');
|
$model->load('invitations');
|
||||||
|
|
||||||
/* If no invitations have been created, this is our fail safe to maintain state*/
|
/* If no invitations have been created, this is our fail safe to maintain state*/
|
||||||
@ -152,8 +124,6 @@ class InvoiceMigrationRepository extends BaseRepository
|
|||||||
if ($class->name == Invoice::class || $class->name == RecurringInvoice::class) {
|
if ($class->name == Invoice::class || $class->name == RecurringInvoice::class) {
|
||||||
if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) {
|
if (($state['finished_amount'] != $state['starting_amount']) && ($model->status_id != Invoice::STATUS_DRAFT)) {
|
||||||
|
|
||||||
// $model->ledger()->updateInvoiceBalance(($state['finished_amount'] - $state['starting_amount']));
|
|
||||||
// $model->client->service()->updateBalance(($state['finished_amount'] - $state['starting_amount']))->save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $model->design_id) {
|
if (! $model->design_id) {
|
||||||
@ -162,7 +132,7 @@ class InvoiceMigrationRepository extends BaseRepository
|
|||||||
|
|
||||||
|
|
||||||
if ($model->company->update_products) {
|
if ($model->company->update_products) {
|
||||||
UpdateOrCreateProduct::dispatchNow($model->line_items, $model, $model->company);
|
//UpdateOrCreateProduct::dispatchNow($model->line_items, $model, $model->company);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ class InvoiceService
|
|||||||
|
|
||||||
public function addGatewayFee(CompanyGateway $company_gateway, $gateway_type_id, float $amount)
|
public function addGatewayFee(CompanyGateway $company_gateway, $gateway_type_id, float $amount)
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->invoice = (new AddGatewayFee($company_gateway, $gateway_type_id, $this->invoice, $amount))->run();
|
$this->invoice = (new AddGatewayFee($company_gateway, $gateway_type_id, $this->invoice, $amount))->run();
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -14,8 +14,8 @@ return [
|
|||||||
'require_https' => env('REQUIRE_HTTPS', true),
|
'require_https' => env('REQUIRE_HTTPS', true),
|
||||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||||
'app_version' => '5.1.59',
|
'app_version' => '5.1.60',
|
||||||
'app_tag' => '5.1.59-release',
|
'app_tag' => '5.1.60-release',
|
||||||
'minimum_client_version' => '5.0.16',
|
'minimum_client_version' => '5.0.16',
|
||||||
'terms_version' => '1.0.1',
|
'terms_version' => '1.0.1',
|
||||||
'api_secret' => env('API_SECRET', false),
|
'api_secret' => env('API_SECRET', false),
|
||||||
|
@ -30,8 +30,8 @@ class StripeConnectGateway extends Migration
|
|||||||
Gateway::create($gateway);
|
Gateway::create($gateway);
|
||||||
|
|
||||||
if (Ninja::isNinja()) {
|
if (Ninja::isNinja()) {
|
||||||
Gateway::where('id', 20)->update(['visible' => 0]);
|
Gateway::whereIn('id', [20])->update(['visible' => 0]);
|
||||||
Gateway::where('id', 56)->update(['visible' => 1]);
|
Gateway::whereIn('id', [56])->update(['visible' => 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4229,12 +4229,17 @@ $LANG = array(
|
|||||||
'amount_greater_than_balance_v5' => 'The amount is greater than the invoice balance. You cannot overpay an invoice.',
|
'amount_greater_than_balance_v5' => 'The amount is greater than the invoice balance. You cannot overpay an invoice.',
|
||||||
'click_to_continue' => 'Click to continue',
|
'click_to_continue' => 'Click to continue',
|
||||||
|
|
||||||
'notification_invoice_created_subject' => 'Invoice :invoice was created to :client',
|
'notification_invoice_created_body' => 'The following invoice :invoice was created for client :client for :amount.',
|
||||||
'notification_invoice_created_subject' => 'Invoice :invoice was created for :client',
|
'notification_invoice_created_subject' => 'Invoice :invoice was created for :client',
|
||||||
'notification_quote_created_subject' => 'Quote :invoice was created to :client',
|
'notification_quote_created_body' => 'The following quote :invoice was created for client :client for :amount.',
|
||||||
'notification_quote_created_subject' => 'Quote :invoice was created for :client',
|
'notification_quote_created_subject' => 'Quote :invoice was created for :client',
|
||||||
'notification_credit_created_subject' => 'Credit :invoice was created to :client',
|
'notification_credit_created_body' => 'The following credit :invoice was created for client :client for :amount.',
|
||||||
'notification_credit_created_subject' => 'Credit :invoice was created for :client',
|
'notification_credit_created_subject' => 'Credit :invoice was created for :client',
|
||||||
|
'max_companies' => 'Maximum companies migrated',
|
||||||
|
'max_companies_desc' => 'You have reached your maximum number of companies. Delete existing companies to migrate new ones.',
|
||||||
|
'migration_already_completed' => 'Company already migrated',
|
||||||
|
'migration_already_completed_desc' => 'Looks like you already migrated <b> :company_name </b>to the V5 version of the Invoice Ninja. In case you want to start over, you can force migrate to wipe existing data.',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
@ -1,31 +1,18 @@
|
|||||||
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
|
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
|
||||||
|
|
||||||
@slot('header')
|
@slot('header')
|
||||||
@component('email.components.header')
|
@include('email.components.header', ['logo' => $logo])
|
||||||
Migration already completed
|
@endslot
|
||||||
@endcomponent
|
|
||||||
@endslot
|
|
||||||
|
|
||||||
@slot('greeting')
|
<h2>{{ctrans('texts.migration_already_completed')}}</h2>
|
||||||
Hello,
|
|
||||||
@endslot
|
|
||||||
|
|
||||||
Looks like you already migrated your data to V2 version of the Invoice Ninja. In case you want to start over, you can 'force' migrate to wipe existing data.
|
<p>{{ctrans('texts.migration_already_completed_desc', ['company_name' => $company_name])}}</p>
|
||||||
|
|
||||||
@component('email.components.button', ['url' => url('/')])
|
@if(isset($whitelabel) && !$whitelabel)
|
||||||
Visit portal
|
@slot('footer')
|
||||||
@endcomponent
|
|
||||||
|
|
||||||
|
|
||||||
@slot('signature')
|
|
||||||
Thank you, <br>
|
|
||||||
Invoice Ninja
|
|
||||||
@endslot
|
|
||||||
|
|
||||||
@slot('footer')
|
|
||||||
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja'])
|
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja'])
|
||||||
For any info, please visit InvoiceNinja.
|
For any info, please visit InvoiceNinja.
|
||||||
@endcomponent
|
@endcomponent
|
||||||
@endslot
|
@endslot
|
||||||
|
@endif
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
18
resources/views/email/migration/max_companies.blade.php
Normal file
18
resources/views/email/migration/max_companies.blade.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
@component('email.template.master', ['design' => 'light', 'settings' => $settings])
|
||||||
|
|
||||||
|
@slot('header')
|
||||||
|
@include('email.components.header', ['logo' => $logo])
|
||||||
|
@endslot
|
||||||
|
|
||||||
|
<h2>{{ctrans('texts.max_companies')}}</h2>
|
||||||
|
|
||||||
|
<p>{{ctrans('texts.max_companies_desc')}}</p>
|
||||||
|
|
||||||
|
@if(isset($whitelabel) && !$whitelabel)
|
||||||
|
@slot('footer')
|
||||||
|
@component('email.components.footer', ['url' => 'https://invoiceninja.com', 'url_text' => '© InvoiceNinja'])
|
||||||
|
For any info, please visit InvoiceNinja.
|
||||||
|
@endcomponent
|
||||||
|
@endslot
|
||||||
|
@endif
|
||||||
|
@endcomponent
|
Loading…
x
Reference in New Issue
Block a user