From 820ca43020282502af0a353c1d816b263dbdbbff Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 17 Aug 2023 10:57:06 +1000 Subject: [PATCH 1/6] Fixes for invitation resolution --- app/Console/Commands/TypeCheck.php | 2 +- .../ClientPortal/QuoteController.php | 2 +- app/Http/Controllers/SelfUpdateController.php | 18 ++++++++++++++---- phpstan.neon | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/Console/Commands/TypeCheck.php b/app/Console/Commands/TypeCheck.php index d26785b0ad4b..7a57791eb4e8 100644 --- a/app/Console/Commands/TypeCheck.php +++ b/app/Console/Commands/TypeCheck.php @@ -122,7 +122,7 @@ class TypeCheck extends Command $client->save(); }); - Company::cursor()->each(function ($company) { + Company::query()->cursor()->each(function ($company) { $this->logMessage("Checking company {$company->id}"); $company->saveSettings($company->settings, $company); }); diff --git a/app/Http/Controllers/ClientPortal/QuoteController.php b/app/Http/Controllers/ClientPortal/QuoteController.php index 6d3eb9c0335a..98750aa683b9 100644 --- a/app/Http/Controllers/ClientPortal/QuoteController.php +++ b/app/Http/Controllers/ClientPortal/QuoteController.php @@ -53,7 +53,7 @@ class QuoteController extends Controller { /* If the quote is expired, convert the status here */ - $invitation = $quote->invitations()->where('client_contact_id', auth()->user()->id)->first(); + $invitation = $quote->invitations()->where('client_contact_id', auth()->guard('contact')->user()->id)->first(); $data = [ 'quote' => $quote, diff --git a/app/Http/Controllers/SelfUpdateController.php b/app/Http/Controllers/SelfUpdateController.php index 12fd890840a6..f304482fac6b 100644 --- a/app/Http/Controllers/SelfUpdateController.php +++ b/app/Http/Controllers/SelfUpdateController.php @@ -53,7 +53,7 @@ class SelfUpdateController extends BaseController nlog('Test filesystem is writable'); - // $this->testWritable(); + $this->testWritable(); nlog('Clear cache directory'); @@ -61,12 +61,22 @@ class SelfUpdateController extends BaseController nlog('copying release file'); - if (copy($this->getDownloadUrl(), storage_path("app/{$this->filename}"))) { - nlog('Copied file from URL'); - } else { + $file_headers = @get_headers($this->getDownloadUrl()); + + if (stripos($file_headers[0], "404 Not Found") >0 || (stripos($file_headers[0], "302 Found") > 0 && stripos($file_headers[7], "404 Not Found") > 0)) { return response()->json(['message' => 'Download not yet available. Please try again shortly.'], 410); } + try { + if (copy($this->getDownloadUrl(), storage_path("app/{$this->filename}"))) { + nlog('Copied file from URL'); + } + } + catch(\Exception $e) { + nlog($e->getMessage()); + return response()->json(['message' => 'File exists on the server, however there was a problem downloading and copying to the local filesystem'], 500); + } + nlog('Finished copying'); $file = Storage::disk('local')->path($this->filename); diff --git a/phpstan.neon b/phpstan.neon index 6bc4f9205594..13799a2a91b7 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -7,13 +7,13 @@ parameters: - 'app/' excludePaths: - 'vendor/' + - 'resources/views/*' - 'app/Jobs/Ninja/*' - 'app/Models/Presenters/*' - 'app/Console/Commands/*' - 'app/DataMapper/Analytics/*' - 'app/PaymentDrivers/Authorize/*' - 'app/Utils/Traits/*' - - 'resources/views/*' universalObjectCratesClasses: - App\DataMapper\Tax\RuleInterface - App\DataMapper\FeesAndLimits From 4586d9ddf51c98dd63baf9cf23728ef01918d7af Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 17 Aug 2023 10:57:25 +1000 Subject: [PATCH 2/6] Fixes for invitation resolution --- app/Http/Controllers/ClientPortal/CreditController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/ClientPortal/CreditController.php b/app/Http/Controllers/ClientPortal/CreditController.php index 06a7ad6fa9a1..658dee0ad454 100644 --- a/app/Http/Controllers/ClientPortal/CreditController.php +++ b/app/Http/Controllers/ClientPortal/CreditController.php @@ -30,7 +30,8 @@ class CreditController extends Controller { set_time_limit(0); - $invitation = $credit->invitations()->where('client_contact_id', auth()->user()->id)->first(); + // $invitation = $credit->invitations()->where('client_contact_id', auth()->user()->id)->first(); + $invitation = $credit->invitations()->where('client_contact_id', auth()->guard('contact')->user()->id)->first(); $data = [ 'credit' => $credit, From 9ff6a1225e0b0b4a5c5fae3705927bab69ecdef7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 18 Aug 2023 19:17:30 +1000 Subject: [PATCH 3/6] Update translations --- lang/en/texts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/en/texts.php b/lang/en/texts.php index ba7b3f4085fb..bbd0700e30e2 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -3344,7 +3344,7 @@ $LANG = array( 'click_here_capital' => 'Click here', 'marked_invoice_as_paid' => 'Successfully marked invoice as sent', 'marked_invoices_as_sent' => 'Successfully marked invoices as sent', - 'marked_invoices_as_paid' => 'Successfully marked invoices as sent', + 'marked_invoices_as_paid' => 'Successfully marked invoices as paid', 'activity_57' => 'System failed to email invoice :invoice', 'custom_value3' => 'Custom Value 3', 'custom_value4' => 'Custom Value 4', From 2900db2e9061f193835cc261e7b6bc6ef04231a8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 18 Aug 2023 19:33:40 +1000 Subject: [PATCH 4/6] updated translations for react --- lang/en/texts.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lang/en/texts.php b/lang/en/texts.php index bbd0700e30e2..a96969812c96 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -3342,7 +3342,7 @@ $LANG = array( 'freq_three_years' => 'Three Years', 'military_time_help' => '24 Hour Display', 'click_here_capital' => 'Click here', - 'marked_invoice_as_paid' => 'Successfully marked invoice as sent', + 'marked_invoice_as_paid' => 'Successfully marked invoice as paid', 'marked_invoices_as_sent' => 'Successfully marked invoices as sent', 'marked_invoices_as_paid' => 'Successfully marked invoices as paid', 'activity_57' => 'System failed to email invoice :invoice', @@ -5157,6 +5157,8 @@ $LANG = array( 'unlinked_transactions' => 'Successfully unlinked :count transactions', 'unlinked_transaction' => 'Successfully unlinked transaction', 'view_dashboard_permission' => 'Allow user to access the dashboard, data is limited to available permissions', + 'marked_sent_credits' => 'Successfully marked credits sent', + ); return $LANG; From 2752a2e65194b73465c964ddac339d354fc05d92 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 18 Aug 2023 21:36:50 +1000 Subject: [PATCH 5/6] Report previews --- app/Export/CSV/CreditExport.php | 36 +++++++++++--- app/Http/Controllers/EmailController.php | 4 +- .../Reports/CreditReportController.php | 16 ++++++- .../Reports/ReportPreviewController.php | 47 +++++++++++++++++++ .../Requests/Report/ReportPreviewRequest.php | 42 +++++++++++++++++ app/Providers/AppServiceProvider.php | 5 +- app/Services/Email/Email.php | 4 +- app/Transformers/TaskTransformer.php | 1 + phpstan.neon | 10 ++-- routes/api.php | 4 +- .../Export/ReportCsvGenerationTest.php | 32 +++++++++++++ 11 files changed, 185 insertions(+), 16 deletions(-) create mode 100644 app/Http/Controllers/Reports/ReportPreviewController.php create mode 100644 app/Http/Requests/Report/ReportPreviewRequest.php diff --git a/app/Export/CSV/CreditExport.php b/app/Export/CSV/CreditExport.php index 1cadfea5b7dd..ae21d1d74618 100644 --- a/app/Export/CSV/CreditExport.php +++ b/app/Export/CSV/CreditExport.php @@ -16,6 +16,7 @@ use App\Models\Company; use App\Models\Credit; use App\Transformers\CreditTransformer; use App\Utils\Ninja; +use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Support\Facades\App; use League\Csv\Writer; @@ -80,14 +81,40 @@ class CreditExport extends BaseExport $this->credit_transformer = new CreditTransformer(); } - public function run() + public function returnJson(string $hash) { + $query = $this->init(); + + $header = $this->buildHeader(); + + $report = $query->cursor() + ->map(function ($credit) { + return $this->buildRow($credit); + })->toJson(); + } + + private function init(): Builder + { + MultiDB::setDb($this->company->db); App::forgetInstance('translator'); App::setLocale($this->company->locale()); $t = app('translator'); $t->replace(Ninja::transformTranslations($this->company->settings)); + $query = Credit::query() + ->withTrashed() + ->with('client')->where('company_id', $this->company->id) + ->where('is_deleted', 0); + + $query = $this->addDateRange($query); + + return $query; + } + + public function run() + { + $query = $this->init(); //load the CSV document from a string $this->csv = Writer::createFromString(); @@ -98,12 +125,7 @@ class CreditExport extends BaseExport //insert the header $this->csv->insertOne($this->buildHeader()); - $query = Credit::query() - ->withTrashed() - ->with('client')->where('company_id', $this->company->id) - ->where('is_deleted', 0); - - $query = $this->addDateRange($query); + $query->cursor() ->each(function ($credit) { diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php index cc60c74b1f94..fdcf887beb5a 100644 --- a/app/Http/Controllers/EmailController.php +++ b/app/Http/Controllers/EmailController.php @@ -78,7 +78,9 @@ class EmailController extends BaseController $entity_obj->service()->markSent()->save(); $mo->invitation_id = $invitation->id; - + $mo->client_id = $invitation->contact->client_id ?? null; + $mo->vendor_id = $invitation->contact->vendor_id ?? null; + Email::dispatch($mo, $invitation->company); } }); diff --git a/app/Http/Controllers/Reports/CreditReportController.php b/app/Http/Controllers/Reports/CreditReportController.php index f940f33cb190..30f77cee63ce 100644 --- a/app/Http/Controllers/Reports/CreditReportController.php +++ b/app/Http/Controllers/Reports/CreditReportController.php @@ -62,14 +62,26 @@ class CreditReportController extends BaseController */ public function __invoke(GenericReportRequest $request) { + /** @var \App\Models\User $user */ + $user = auth()->user(); + if ($request->has('send_email') && $request->get('send_email')) { - SendToAdmin::dispatch(auth()->user()->company(), $request->all(), CreditExport::class, $this->filename); + SendToAdmin::dispatch($user->company(), $request->all(), CreditExport::class, $this->filename); return response()->json(['message' => 'working...'], 200); } // expect a list of visible fields, or use the default - $export = new CreditExport(auth()->user()->company(), $request->all()); + $export = new CreditExport($user->company(), $request->all()); + + if($request->has('output') && $request->input('output') == 'json') { + + $hash = \Illuminate\Support\Str::uuid(); + + $data = $export->returnJson($hash); + + return response()->json(['message' => $hash], 200); + } $csv = $export->run(); diff --git a/app/Http/Controllers/Reports/ReportPreviewController.php b/app/Http/Controllers/Reports/ReportPreviewController.php new file mode 100644 index 000000000000..cddbbb005493 --- /dev/null +++ b/app/Http/Controllers/Reports/ReportPreviewController.php @@ -0,0 +1,47 @@ +user(); + + $report = Cache::get($hash); + + if(!$report) + return response()->json(['message' => 'Still working.....'], 409); + + if($report){ + + Cache::forget($hash); + + return response()->json($report, 200); + } + + + } +} diff --git a/app/Http/Requests/Report/ReportPreviewRequest.php b/app/Http/Requests/Report/ReportPreviewRequest.php new file mode 100644 index 000000000000..82d53002fe47 --- /dev/null +++ b/app/Http/Requests/Report/ReportPreviewRequest.php @@ -0,0 +1,42 @@ +user(); + + return $user->isAdmin() || $user->hasPermission('view_reports'); + + } + + public function rules() + { + return [ + 'hash' => 'bail|required|string', + ]; + } + + public function prepareForValidation() + { + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 6d5e145af815..089287512bfd 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -93,6 +93,7 @@ class AppServiceProvider extends ServiceProvider }); Mailer::macro('postmark_config', function (string $postmark_key) { + // @phpstan-ignore /** @phpstan-ignore-next-line **/ Mailer::setSymfonyTransport(app('mail.manager')->createSymfonyTransport([ 'transport' => 'postmark', 'token' => $postmark_key @@ -101,8 +102,10 @@ class AppServiceProvider extends ServiceProvider return $this; }); + Mailer::macro('mailgun_config', function (string $secret, string $domain, string $endpoint = 'api.mailgun.net') { - Mailer::setSymfonyTransport(app('mail.manager')->createSymfonyTransport([ + // @phpstan-ignore /** @phpstan-ignore-next-line **/ + Mailer::setSymfonyTransport(app('mail.manager')->createSymfonyTransport([ 'transport' => 'mailgun', 'secret' => $secret, 'domain' => $domain, diff --git a/app/Services/Email/Email.php b/app/Services/Email/Email.php index 4a9663ea43f4..4c114d586d31 100644 --- a/app/Services/Email/Email.php +++ b/app/Services/Email/Email.php @@ -138,7 +138,9 @@ class Email implements ShouldQueue $this->email_object->company = $this->company; - $this->email_object->client_id ? $this->email_object->settings = $this->email_object->client->getMergedSettings() : $this->email_object->settings = $this->company->settings; + $this->email_object->client_id ? $this->email_object->settings = $this->email_object->client->getMergedSettings() : $this->email_object->settings = $this->company->settings; + + $this->email_object->client_id ? nlog("client settings") : nlog("company settings "); $this->email_object->whitelabel = $this->company->account->isPaid() ? true : false; diff --git a/app/Transformers/TaskTransformer.php b/app/Transformers/TaskTransformer.php index af78d20d92eb..cd668ba6bf63 100644 --- a/app/Transformers/TaskTransformer.php +++ b/app/Transformers/TaskTransformer.php @@ -30,6 +30,7 @@ class TaskTransformer extends EntityTransformer protected $defaultIncludes = [ 'documents', + 'project', ]; /** diff --git a/phpstan.neon b/phpstan.neon index 13799a2a91b7..fffe8123c3fd 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,18 +1,22 @@ includes: - ./vendor/nunomaduro/larastan/extension.neon - ./vendor/spaze/phpstan-stripe/extension.neon + - phpstan-baseline.neon parameters: level: 2 paths: - - 'app/' + - app excludePaths: - - 'vendor/' - - 'resources/views/*' + - 'vendor/*' + - '../resources/*' + - resources/ + - resources/* - 'app/Jobs/Ninja/*' - 'app/Models/Presenters/*' - 'app/Console/Commands/*' - 'app/DataMapper/Analytics/*' - 'app/PaymentDrivers/Authorize/*' + - 'app/PaymentDrivers/AuthorizePaymentDriver.php' - 'app/Utils/Traits/*' universalObjectCratesClasses: - App\DataMapper\Tax\RuleInterface diff --git a/routes/api.php b/routes/api.php index 93a84ea8f65d..99b17d8d2242 100644 --- a/routes/api.php +++ b/routes/api.php @@ -312,7 +312,9 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale'] Route::post('reports/client_sales_report', ClientSalesReportController::class); Route::post('reports/tax_summary_report', TaxSummaryReportController::class); Route::post('reports/user_sales_report', UserSalesReportController::class); - + Route::post('reports/preview/{hash}', UserSalesReportController::class); + + Route::resource('task_schedulers', TaskSchedulerController::class); Route::post('task_schedulers/bulk', [TaskSchedulerController::class, 'bulk'])->name('task_schedulers.bulk'); diff --git a/tests/Feature/Export/ReportCsvGenerationTest.php b/tests/Feature/Export/ReportCsvGenerationTest.php index 4ae21985a610..35e56272ec1c 100644 --- a/tests/Feature/Export/ReportCsvGenerationTest.php +++ b/tests/Feature/Export/ReportCsvGenerationTest.php @@ -674,6 +674,38 @@ class ReportCsvGenerationTest extends TestCase } + public function testCreditJsonReport() + { + + // Credit::factory()->create([ + // 'user_id' => $this->user->id, + // 'company_id' => $this->company->id, + // 'client_id' => $this->client->id, + // 'amount' => 100, + // 'balance' => 50, + // 'number' => '1234', + // 'status_id' => 2, + // 'discount' => 10, + // 'po_number' => '1234', + // 'public_notes' => 'Public', + // 'private_notes' => 'Private', + // 'terms' => 'Terms', + // ]); + + // $data = [ + // 'date_range' => 'all', + // 'report_keys' => ["client.name","credit.number","credit.amount","payment.date", "payment.amount"], + // 'send_email' => false, + // ]; + + // $response = $this->withHeaders([ + // 'X-API-SECRET' => config('ninja.api_secret'), + // 'X-API-TOKEN' => $this->token, + // ])->post('/api/v1/reports/credits?output=json', $data); + + + } + public function testCreditCustomColumnsCsvGeneration() { From 10ad6e04232e53f16a8a80c548bba0b099cf7eab Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 18 Aug 2023 23:36:54 +1000 Subject: [PATCH 6/6] Report previews --- app/Export/CSV/CreditExport.php | 62 +++++++++++----- .../Reports/CreditReportController.php | 7 +- .../Reports/ReportPreviewController.php | 2 - .../Requests/Report/ReportPreviewRequest.php | 1 - app/Jobs/Report/PreviewReport.php | 51 +++++++++++++ routes/api.php | 3 +- .../Export/ReportCsvGenerationTest.php | 72 ++++++++++++------- 7 files changed, 150 insertions(+), 48 deletions(-) create mode 100644 app/Jobs/Report/PreviewReport.php diff --git a/app/Export/CSV/CreditExport.php b/app/Export/CSV/CreditExport.php index ae21d1d74618..66b24ce33f5a 100644 --- a/app/Export/CSV/CreditExport.php +++ b/app/Export/CSV/CreditExport.php @@ -11,14 +11,15 @@ namespace App\Export\CSV; -use App\Libraries\MultiDB; -use App\Models\Company; -use App\Models\Credit; -use App\Transformers\CreditTransformer; use App\Utils\Ninja; -use Illuminate\Contracts\Database\Eloquent\Builder; -use Illuminate\Support\Facades\App; +use App\Utils\Number; +use App\Models\Credit; use League\Csv\Writer; +use App\Models\Company; +use App\Libraries\MultiDB; +use Illuminate\Support\Facades\App; +use App\Transformers\CreditTransformer; +use Illuminate\Contracts\Database\Eloquent\Builder; class CreditExport extends BaseExport { @@ -81,16 +82,43 @@ class CreditExport extends BaseExport $this->credit_transformer = new CreditTransformer(); } - public function returnJson(string $hash) + public function returnJson() { $query = $this->init(); $header = $this->buildHeader(); $report = $query->cursor() - ->map(function ($credit) { - return $this->buildRow($credit); - })->toJson(); + ->map(function ($credit) { + $row = $this->buildRow($credit); + return $this->processMetaData($row, $credit); + })->toArray(); + + return array_merge([$header], $report); + } + + private function processMetaData(array $row, Credit $credit): array + { + $clean_row = []; + + foreach ($this->input['report_keys'] as $key => $value) { + + $report_keys = explode(".", $value); + + $column_key = str_replace("credit.", "", $value); + $clean_row[$key]['entity'] = $report_keys[0]; + $clean_row[$key]['id'] = $report_keys[1]; + $clean_row[$key]['hashed_id'] = $report_keys[0] == 'credit' ? null : $credit->{$report_keys[0]}->hashed_id ?? null; + $clean_row[$key]['value'] = $row[$column_key]; + + if(in_array($report_keys[1], ['amount', 'balance', 'partial', 'refunded', 'applied','unit_cost','cost','price'])) + $clean_row[$key]['display_value'] = Number::formatMoney($row[$column_key], $credit->client); + else + $clean_row[$key]['display_value'] = $row[$column_key]; + + } + + return $clean_row; } private function init(): Builder @@ -102,6 +130,10 @@ class CreditExport extends BaseExport $t = app('translator'); $t->replace(Ninja::transformTranslations($this->company->settings)); + if (count($this->input['report_keys']) == 0) { + $this->input['report_keys'] = array_values($this->entity_keys); + } + $query = Credit::query() ->withTrashed() ->with('client')->where('company_id', $this->company->id) @@ -112,23 +144,19 @@ class CreditExport extends BaseExport return $query; } - public function run() + public function run(): string { $query = $this->init(); //load the CSV document from a string $this->csv = Writer::createFromString(); - if (count($this->input['report_keys']) == 0) { - $this->input['report_keys'] = array_values($this->entity_keys); - } - //insert the header $this->csv->insertOne($this->buildHeader()); - - +// nlog($this->input['report_keys']); $query->cursor() ->each(function ($credit) { + nlog($this->buildRow($credit)); $this->csv->insertOne($this->buildRow($credit)); }); diff --git a/app/Http/Controllers/Reports/CreditReportController.php b/app/Http/Controllers/Reports/CreditReportController.php index 30f77cee63ce..5a1a952d6359 100644 --- a/app/Http/Controllers/Reports/CreditReportController.php +++ b/app/Http/Controllers/Reports/CreditReportController.php @@ -14,6 +14,7 @@ namespace App\Http\Controllers\Reports; use App\Export\CSV\CreditExport; use App\Http\Controllers\BaseController; use App\Http\Requests\Report\GenericReportRequest; +use App\Jobs\Report\PreviewReport; use App\Jobs\Report\SendToAdmin; use App\Utils\Traits\MakesHash; use Illuminate\Http\Response; @@ -72,16 +73,16 @@ class CreditReportController extends BaseController } // expect a list of visible fields, or use the default - $export = new CreditExport($user->company(), $request->all()); - if($request->has('output') && $request->input('output') == 'json') { $hash = \Illuminate\Support\Str::uuid(); - $data = $export->returnJson($hash); + PreviewReport::dispatch($user->company(), $request->all(), CreditExport::class, $hash); return response()->json(['message' => $hash], 200); } + + $export = new CreditExport($user->company(), $request->all()); $csv = $export->run(); diff --git a/app/Http/Controllers/Reports/ReportPreviewController.php b/app/Http/Controllers/Reports/ReportPreviewController.php index cddbbb005493..82f55bc2f4df 100644 --- a/app/Http/Controllers/Reports/ReportPreviewController.php +++ b/app/Http/Controllers/Reports/ReportPreviewController.php @@ -27,8 +27,6 @@ class ReportPreviewController extends BaseController public function __invoke(ReportPreviewRequest $request, ?string $hash) { - /** @var \App\Models\User $user */ - $user = auth()->user(); $report = Cache::get($hash); diff --git a/app/Http/Requests/Report/ReportPreviewRequest.php b/app/Http/Requests/Report/ReportPreviewRequest.php index 82d53002fe47..2ccefb8dc20c 100644 --- a/app/Http/Requests/Report/ReportPreviewRequest.php +++ b/app/Http/Requests/Report/ReportPreviewRequest.php @@ -32,7 +32,6 @@ class ReportPreviewRequest extends Request public function rules() { return [ - 'hash' => 'bail|required|string', ]; } diff --git a/app/Jobs/Report/PreviewReport.php b/app/Jobs/Report/PreviewReport.php new file mode 100644 index 000000000000..a5ce2b6a5d6d --- /dev/null +++ b/app/Jobs/Report/PreviewReport.php @@ -0,0 +1,51 @@ +company->db); + + /** @var \App\Export\CSV\CreditExport $export */ + $export = new $this->report_class($this->company, $this->request); + $report = $export->returnJson(); + + nlog($report); + Cache::put($this->hash, $report, 60 * 60); + } + + public function middleware() + { + return [new WithoutOverlapping("report-{$this->company->company_key}")]; + } +} diff --git a/routes/api.php b/routes/api.php index 99b17d8d2242..34e6c57c308b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -92,6 +92,7 @@ use App\Http\Controllers\Reports\InvoiceReportController; use App\Http\Controllers\Reports\PaymentReportController; use App\Http\Controllers\Reports\ProductReportController; use App\Http\Controllers\Reports\ProfitAndLossController; +use App\Http\Controllers\Reports\ReportPreviewController; use App\Http\Controllers\Reports\ActivityReportController; use App\Http\Controllers\Reports\ARDetailReportController; use App\Http\Controllers\Reports\DocumentReportController; @@ -312,7 +313,7 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale'] Route::post('reports/client_sales_report', ClientSalesReportController::class); Route::post('reports/tax_summary_report', TaxSummaryReportController::class); Route::post('reports/user_sales_report', UserSalesReportController::class); - Route::post('reports/preview/{hash}', UserSalesReportController::class); + Route::post('reports/preview/{hash}', ReportPreviewController::class); Route::resource('task_schedulers', TaskSchedulerController::class); diff --git a/tests/Feature/Export/ReportCsvGenerationTest.php b/tests/Feature/Export/ReportCsvGenerationTest.php index 35e56272ec1c..70d0fbb72501 100644 --- a/tests/Feature/Export/ReportCsvGenerationTest.php +++ b/tests/Feature/Export/ReportCsvGenerationTest.php @@ -676,33 +676,57 @@ class ReportCsvGenerationTest extends TestCase public function testCreditJsonReport() { - - // Credit::factory()->create([ - // 'user_id' => $this->user->id, - // 'company_id' => $this->company->id, - // 'client_id' => $this->client->id, - // 'amount' => 100, - // 'balance' => 50, - // 'number' => '1234', - // 'status_id' => 2, - // 'discount' => 10, - // 'po_number' => '1234', - // 'public_notes' => 'Public', - // 'private_notes' => 'Private', - // 'terms' => 'Terms', - // ]); - // $data = [ - // 'date_range' => 'all', - // 'report_keys' => ["client.name","credit.number","credit.amount","payment.date", "payment.amount"], - // 'send_email' => false, - // ]; + Credit::factory()->create([ + 'user_id' => $this->user->id, + 'company_id' => $this->company->id, + 'client_id' => $this->client->id, + 'amount' => 100, + 'balance' => 50, + 'number' => '1234', + 'status_id' => 2, + 'discount' => 10, + 'po_number' => '1234', + 'public_notes' => 'Public', + 'private_notes' => 'Private', + 'terms' => 'Terms', + ]); - // $response = $this->withHeaders([ - // 'X-API-SECRET' => config('ninja.api_secret'), - // 'X-API-TOKEN' => $this->token, - // ])->post('/api/v1/reports/credits?output=json', $data); + $data = [ + 'date_range' => 'all', + 'report_keys' => ["client.name","credit.number","credit.amount","payment.date", "payment.amount"], + 'send_email' => false, + ]; + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/reports/credits?output=json', $data); + + + $response->assertStatus(200); + + $arr = $response->json(); + + nlog($arr['message']); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/reports/preview/'.$arr['message']); + + $response->assertStatus(409); + + sleep(1); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/reports/preview/'.$arr['message']); + + $response->assertStatus(200); + + nlog($response->json()); }