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