diff --git a/app/DataMapper/Sources/PayPalBalanceAffecting.php b/app/DataMapper/Sources/PayPalBalanceAffecting.php
index d898f4d651..11a4389e80 100644
--- a/app/DataMapper/Sources/PayPalBalanceAffecting.php
+++ b/app/DataMapper/Sources/PayPalBalanceAffecting.php
@@ -236,7 +236,7 @@ class PayPalBalanceAffecting
-// $csv = Reader::createFromString($csvFile);
+// $csv = Reader::fromString($csvFile);
// // $csvdelimiter = self::detectDelimiter($csvfile);
// $csv->setDelimiter(",");
// $stmt = new Statement();
diff --git a/app/Helpers/Cache/Atomic.php b/app/Helpers/Cache/Atomic.php
index 6f794290be..e3c38bf854 100644
--- a/app/Helpers/Cache/Atomic.php
+++ b/app/Helpers/Cache/Atomic.php
@@ -11,37 +11,42 @@
namespace App\Helpers\Cache;
+use Illuminate\Contracts\Redis\Factory as RedisFactory;
use Illuminate\Support\Facades\Cache;
-use Illuminate\Support\Facades\Redis;
class Atomic
{
- public static function set($key, $value = true, $ttl = 1): bool
+ public static function set(string $key, mixed $value = true, int $ttl = 1): bool
{
$new_ttl = now()->addSeconds($ttl);
try {
- return Redis::connection('sentinel-cache')->set($key, $value, 'EX', $ttl, 'NX') ? true : false;
+ /** @var RedisFactory $redis */
+ $redis = app('redis');
+ $result = $redis->connection('sentinel-cache')->command('set', [$key, $value, 'EX', $ttl, 'NX']);
+ return (bool) $result;
} catch (\Throwable) {
return Cache::add($key, $value, $new_ttl) ? true : false;
}
-
}
- public static function get($key)
+ public static function get(string $key): mixed
{
try {
- return Redis::connection('sentinel-cache')->get($key);
+ /** @var RedisFactory $redis */
+ $redis = app('redis');
+ return $redis->connection('sentinel-cache')->command('get', [$key]);
} catch (\Throwable) {
return Cache::get($key);
}
-
}
- public static function del($key)
+ public static function del(string $key): mixed
{
try {
- return Redis::connection('sentinel-cache')->del($key);
+ /** @var RedisFactory $redis */
+ $redis = app('redis');
+ return $redis->connection('sentinel-cache')->command('del', [$key]);
} catch (\Throwable) {
return Cache::forget($key);
}
diff --git a/app/Http/Controllers/ImportController.php b/app/Http/Controllers/ImportController.php
index c2661b64ca..cbbd3101f2 100644
--- a/app/Http/Controllers/ImportController.php
+++ b/app/Http/Controllers/ImportController.php
@@ -446,7 +446,6 @@ class ImportController extends Controller
$csv = Reader::fromString($csvfile);
- // $csv = Reader::createFromString($csvfile);
$csvdelimiter = self::detectDelimiter($csvfile);
$csv->setDelimiter($csvdelimiter);
$stmt = new Statement();
diff --git a/app/Import/Providers/BaseImport.php b/app/Import/Providers/BaseImport.php
index 913ac1fa3a..b2096e3a31 100644
--- a/app/Import/Providers/BaseImport.php
+++ b/app/Import/Providers/BaseImport.php
@@ -12,33 +12,35 @@
namespace App\Import\Providers;
+use App\Models\User;
+use App\Utils\Ninja;
+use App\Models\Quote;
+use League\Csv\Reader;
+use App\Models\Company;
+use App\Models\Invoice;
+use League\Csv\Statement;
+use App\Factory\TaskFactory;
+use App\Factory\QuoteFactory;
use App\Factory\ClientFactory;
+use Illuminate\Support\Carbon;
use App\Factory\InvoiceFactory;
use App\Factory\PaymentFactory;
-use App\Factory\QuoteFactory;
-use App\Factory\RecurringInvoiceFactory;
-use App\Factory\TaskFactory;
-use App\Http\Requests\Quote\StoreQuoteRequest;
use App\Import\ImportException;
use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject;
-use App\Mail\Import\CsvImportCompleted;
-use App\Models\Company;
-use App\Models\Invoice;
-use App\Models\Quote;
-use App\Models\User;
-use App\Repositories\ClientRepository;
-use App\Repositories\InvoiceRepository;
-use App\Repositories\PaymentRepository;
-use App\Repositories\QuoteRepository;
-use App\Repositories\RecurringInvoiceRepository;
use App\Repositories\TaskRepository;
use App\Utils\Traits\CleanLineItems;
-use Illuminate\Support\Carbon;
+use App\Repositories\QuoteRepository;
use Illuminate\Support\Facades\Cache;
+use App\Repositories\ClientRepository;
+use App\Mail\Import\CsvImportCompleted;
+use App\Repositories\InvoiceRepository;
+use App\Repositories\PaymentRepository;
+use App\Factory\RecurringInvoiceFactory;
use Illuminate\Support\Facades\Validator;
-use League\Csv\Reader;
-use League\Csv\Statement;
+use App\Http\Requests\Quote\StoreQuoteRequest;
+use App\Repositories\RecurringInvoiceRepository;
+use App\Notifications\Ninja\GenericNinjaAdminNotification;
class BaseImport
{
@@ -70,6 +72,8 @@ class BaseImport
public array $entity_count = [];
+ public bool $store_import_for_research = false;
+
public function __construct(array $request, Company $company)
{
$this->company = $company;
@@ -107,7 +111,7 @@ class BaseImport
$csv = base64_decode($base64_encoded_csv);
// $csv = mb_convert_encoding($csv, 'UTF-8', 'UTF-8');
- $csv = Reader::createFromString($csv);
+ $csv = Reader::fromString($csv);
$csvdelimiter = self::detectDelimiter($csv);
$csv->setDelimiter($csvdelimiter);
@@ -119,7 +123,8 @@ class BaseImport
// Remove Invoice Ninja headers
if (
- count($headers) &&
+ is_array($headers) &&
+ count($headers) > 0 &&
count($data) > 4 &&
$this->import_type === 'csv'
) {
@@ -320,7 +325,8 @@ class BaseImport
$entity->saveQuietly();
$count++;
}
- } catch (\Exception $ex) {
+ }
+ catch (\Exception $ex) {
if (\DB::connection(config('database.default'))->transactionLevel() > 0) {
\DB::connection(config('database.default'))->rollBack();
}
@@ -339,6 +345,20 @@ class BaseImport
nlog("Ingest {$ex->getMessage()}");
nlog($record);
+
+ $this->store_import_for_research = true;
+
+ }
+ catch(\Throwable $ex){
+ if (\DB::connection(config('database.default'))->transactionLevel() > 0) {
+ \DB::connection(config('database.default'))->rollBack();
+ }
+
+ nlog("Throwable:: Ingest {$ex->getMessage()}");
+ nlog($record);
+
+ $this->store_import_for_research = true;
+
}
}
@@ -945,6 +965,40 @@ class BaseImport
$nmo->to_user = $this->company->owner();
NinjaMailerJob::dispatch($nmo, true);
+
+ if (Ninja::isHosted() && $this->store_import_for_research) {
+
+ $content = [
+ 'company_key' => $this->company->company_key,
+ 'class_name' => class_basename($this),
+ 'hash' => $this->hash,
+ ];
+
+ $potential_imports = [
+ 'client',
+ 'product',
+ 'invoice',
+ 'payment',
+ 'vendor',
+ 'expense',
+ 'quote',
+ 'bank_transaction',
+ 'task',
+ 'recurring_invoice',
+ ];
+
+ foreach ($potential_imports as $import) {
+
+ if(Cache::has($this->hash.'-'.$import)) {
+ // store on s3
+ // Cache::put($this->hash.'-'.$import, Cache::get($this->hash.'-'.$import), 60*60*24*2);
+ }
+ }
+
+ $this->company->notification(new GenericNinjaAdminNotification($content))->ninja();
+
+
+ }
}
public function preTransform(array $data, $entity_type)
diff --git a/app/Import/Providers/Csv.php b/app/Import/Providers/Csv.php
index c935c28166..f3ebc1be3e 100644
--- a/app/Import/Providers/Csv.php
+++ b/app/Import/Providers/Csv.php
@@ -382,7 +382,6 @@ class Csv extends BaseImport implements ImportInterface
$this->entity_count['tasks'] = $task_count;
-
}
public function transform(array $data)
diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php
index cf813e7edc..94bfa1a0f2 100644
--- a/app/Utils/HtmlEngine.php
+++ b/app/Utils/HtmlEngine.php
@@ -937,11 +937,10 @@ Código seguro de verificación (CSV): {$verifactu_log->status}";
$tax_label = '';
if (collect($this->entity->line_items)->contains('tax_id', \App\Models\Product::PRODUCT_TYPE_REVERSE_TAX)) {
- $tax_label .= ctrans('texts.reverse_tax_info') . "
";
+ $tax_label .= ctrans('texts.reverse_tax_info') . "
";
}
-
- if ((int)$this->client->country_id !== (int)$this->company->settings->country_id) {
- $tax_label .= ctrans('texts.intracommunity_tax_info') . "
";
+ else if ((int)$this->client->country_id !== (int)$this->company->settings->country_id) {
+ $tax_label .= ctrans('texts.intracommunity_tax_info') . "
";
if ($this->entity_calc->getTotalTaxes() > 0) {
$tax_label = '';
diff --git a/resources/views/portal/ninja2020/subscriptions/ninja_plan.blade.php b/resources/views/portal/ninja2020/subscriptions/ninja_plan.blade.php
index 0cfa66ff82..cc9ea996d8 100644
--- a/resources/views/portal/ninja2020/subscriptions/ninja_plan.blade.php
+++ b/resources/views/portal/ninja2020/subscriptions/ninja_plan.blade.php
@@ -178,7 +178,7 @@ input:checked ~ .dot {
Enterprise Plan
- $140 + $180
yearly @@ -275,12 +275,12 @@ document.getElementById('handleProYearlyClick').addEventListener('click', functi }); const price_map = new Map(); //monthly -price_map.set('7LDdwRb1YK', '$16'); +price_map.set('7LDdwRb1YK', '$18'); price_map.set('MVyb8mdvAZ', '$32'); price_map.set('WpmbkR5azJ', '$54'); price_map.set('k8mepY2aMy', '$84'); //yearly -price_map.set('LYqaQWldnj', '$160'); +price_map.set('LYqaQWldnj', '$180'); price_map.set('kQBeX6mbyK', '$320'); price_map.set('GELe32Qd69', '$540'); price_map.set('MVyb86oevA', '$840'); diff --git a/tests/Feature/Export/ReportCsvGenerationTest.php b/tests/Feature/Export/ReportCsvGenerationTest.php index abf25cf410..687744749a 100644 --- a/tests/Feature/Export/ReportCsvGenerationTest.php +++ b/tests/Feature/Export/ReportCsvGenerationTest.php @@ -1134,7 +1134,7 @@ class ReportCsvGenerationTest extends TestCase $csv = $response->body(); - $reader = Reader::createFromString($csv); + $reader = Reader::fromString($csv); $reader->setHeaderOffset(0); $res = $reader->fetchColumnByName('Street'); @@ -1983,7 +1983,7 @@ class ReportCsvGenerationTest extends TestCase $csv = $response->body(); - $reader = Reader::createFromString($csv); + $reader = Reader::fromString($csv); $reader->setHeaderOffset(0); $res = $reader->fetchColumnByName('Contact First Name'); @@ -2014,7 +2014,7 @@ class ReportCsvGenerationTest extends TestCase private function getFirstValueByColumn($csv, $column) { - $reader = Reader::createFromString($csv); + $reader = Reader::fromString($csv); $reader->setHeaderOffset(0); $res = $reader->fetchColumnByName($column);