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);