diff --git a/app/Export/CSV/BaseExport.php b/app/Export/CSV/BaseExport.php index b9c25da20741..5691958041f2 100644 --- a/app/Export/CSV/BaseExport.php +++ b/app/Export/CSV/BaseExport.php @@ -228,6 +228,26 @@ class BaseExport 'currency_id' => 'purchase_order.currency_id', ]; + protected array $product_report_keys = [ + 'project' => 'project_id', + 'vendor' => 'vendor_id', + 'custom_value1' => 'custom_value1', + 'custom_value2' => 'custom_value2', + 'custom_value3' => 'custom_value3', + 'custom_value4' => 'custom_value4', + 'product_key' => 'product_key', + 'notes' => 'notes', + 'cost' => 'cost', + 'price' => 'price', + 'quantity' => 'quantity', + 'tax_rate1' => 'tax_rate1', + 'tax_rate2' => 'tax_rate2', + 'tax_rate3' => 'tax_rate3', + 'tax_name1' => 'tax_name1', + 'tax_name2' => 'tax_name2', + 'tax_name3' => 'tax_name3', + ]; + protected array $item_report_keys = [ "quantity" => "item.quantity", "cost" => "item.cost", @@ -881,10 +901,10 @@ class BaseExport $header = []; foreach ($this->input['report_keys'] as $value) { - + $key = array_search($value, $this->entity_keys); $original_key = $key; - + // nlog("{$key} => {$value}"); $prefix = ''; @@ -943,6 +963,11 @@ class BaseExport $key = array_search($value, $this->purchase_order_report_keys); } + if(!$key) { + $prefix = ''; + $key = array_search($value, $this->product_report_keys); + } + if(!$key) { $prefix = ''; } @@ -959,6 +984,7 @@ class BaseExport $key = str_replace('contact.', '', $key); $key = str_replace('payment.', '', $key); $key = str_replace('expense.', '', $key); + $key = str_replace('product.', '', $key); if(stripos($value, 'custom_value') !== false) { diff --git a/app/Export/CSV/ProductExport.php b/app/Export/CSV/ProductExport.php index f1a24d49b48b..a4c5bbf7535c 100644 --- a/app/Export/CSV/ProductExport.php +++ b/app/Export/CSV/ProductExport.php @@ -17,6 +17,7 @@ use App\Models\Document; use App\Models\Product; use App\Transformers\ProductTransformer; use App\Utils\Ninja; +use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Support\Facades\App; use League\Csv\Writer; @@ -28,31 +29,6 @@ class ProductExport extends BaseExport public Writer $csv; - public array $entity_keys = [ - 'project' => 'project_id', - 'vendor' => 'vendor_id', - 'custom_value1' => 'custom_value1', - 'custom_value2' => 'custom_value2', - 'custom_value3' => 'custom_value3', - 'custom_value4' => 'custom_value4', - 'product_key' => 'product_key', - 'notes' => 'notes', - 'cost' => 'cost', - 'price' => 'price', - 'quantity' => 'quantity', - 'tax_rate1' => 'tax_rate1', - 'tax_rate2' => 'tax_rate2', - 'tax_rate3' => 'tax_rate3', - 'tax_name1' => 'tax_name1', - 'tax_name2' => 'tax_name2', - 'tax_name3' => 'tax_name3', - ]; - - private array $decorate_keys = [ - 'vendor', - 'project', - ]; - public function __construct(Company $company, array $input) { $this->company = $company; @@ -60,24 +36,37 @@ class ProductExport extends BaseExport $this->entity_transformer = new ProductTransformer(); } - public function run() + public function returnJson() { + $query = $this->init(); + + $headerdisplay = $this->buildHeader(); + + $header = collect($this->input['report_keys'])->map(function ($key, $value) use($headerdisplay){ + return ['identifier' => $value, 'display_value' => $headerdisplay[$value]]; + })->toArray(); + + $report = $query->cursor() + ->map(function ($resource) { + return $this->buildRow($resource); + })->toArray(); + + return array_merge(['columns' => $header], $report); + } + + 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)); - //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); + $this->input['report_keys'] = array_values($this->product_report_keys); } - //insert the header - $this->csv->insertOne($this->buildHeader()); - $query = Product::query() ->withTrashed() ->where('company_id', $this->company->id) @@ -85,6 +74,21 @@ class ProductExport extends BaseExport $query = $this->addDateRange($query); + return $query; + + } + + public function run() + { + + $query = $this->init(); + + //load the CSV document from a string + $this->csv = Writer::createFromString(); + + //insert the header + $this->csv->insertOne($this->buildHeader()); + $query->cursor() ->each(function ($entity) { $this->csv->insertOne($this->buildRow($entity)); @@ -100,7 +104,7 @@ class ProductExport extends BaseExport $entity = []; foreach (array_values($this->input['report_keys']) as $key) { - $keyval = array_search($key, $this->entity_keys); + $keyval = array_search($key, $this->product_report_keys); if (array_key_exists($key, $transformed_entity)) { $entity[$keyval] = $transformed_entity[$key]; diff --git a/app/Http/Controllers/Reports/ProductReportController.php b/app/Http/Controllers/Reports/ProductReportController.php index dcc964677a5f..664bd51a698f 100644 --- a/app/Http/Controllers/Reports/ProductReportController.php +++ b/app/Http/Controllers/Reports/ProductReportController.php @@ -11,13 +11,14 @@ namespace App\Http\Controllers\Reports; +use App\Models\Client; +use Illuminate\Http\Response; +use App\Utils\Traits\MakesHash; +use App\Jobs\Report\SendToAdmin; use App\Export\CSV\ProductExport; +use App\Jobs\Report\PreviewReport; use App\Http\Controllers\BaseController; use App\Http\Requests\Report\GenericReportRequest; -use App\Jobs\Report\SendToAdmin; -use App\Models\Client; -use App\Utils\Traits\MakesHash; -use Illuminate\Http\Response; class ProductReportController extends BaseController { @@ -63,14 +64,27 @@ class ProductReportController 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(), ProductExport::class, $this->filename); + SendToAdmin::dispatch($user->company(), $request->all(), ProductExport::class, $this->filename); return response()->json(['message' => 'working...'], 200); } // expect a list of visible fields, or use the default - $export = new ProductExport(auth()->user()->company(), $request->all()); + if($request->has('output') && $request->input('output') == 'json') { + + $hash = \Illuminate\Support\Str::uuid(); + + PreviewReport::dispatch($user->company(), $request->all(), ProductExport::class, $hash); + + return response()->json(['message' => $hash], 200); + } + + $export = new ProductExport($user->company(), $request->all()); $csv = $export->run(); diff --git a/tests/Feature/Export/ReportCsvGenerationTest.php b/tests/Feature/Export/ReportCsvGenerationTest.php index d2b236e91d4b..1de5988f879f 100644 --- a/tests/Feature/Export/ReportCsvGenerationTest.php +++ b/tests/Feature/Export/ReportCsvGenerationTest.php @@ -527,7 +527,7 @@ class ReportCsvGenerationTest extends TestCase ])->post('/api/v1/reports/products', $data); $csv = $response->streamedContent(); - +nlog($csv); $this->assertEquals('product_key', $this->getFirstValueByColumn($csv, 'Product')); $this->assertEquals('notes', $this->getFirstValueByColumn($csv, 'Notes')); $this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Cost')); diff --git a/tests/Feature/Export/ReportPreviewTest.php b/tests/Feature/Export/ReportPreviewTest.php index df9163834c58..830174908d1e 100644 --- a/tests/Feature/Export/ReportPreviewTest.php +++ b/tests/Feature/Export/ReportPreviewTest.php @@ -23,6 +23,7 @@ use App\Export\CSV\ContactExport; use App\Export\CSV\ExpenseExport; use App\Export\CSV\InvoiceExport; use App\Export\CSV\PaymentExport; +use App\Export\CSV\ProductExport; use App\Export\CSV\ActivityExport; use App\Export\CSV\DocumentExport; use App\Jobs\Report\PreviewReport; @@ -56,6 +57,36 @@ class ReportPreviewTest extends TestCase } + public function testProductJsonExport() + { + \App\Models\Product::factory()->count(5)->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + ]); + + $data = [ + 'send_email' => false, + 'date_range' => 'all', + 'report_keys' => [], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/reports/products?output=json', $data) + ->assertStatus(200); + + $p = (new PreviewReport($this->company, $data, ProductExport::class, '123'))->handle(); + + $this->assertNull($p); + + $r = Cache::pull('123'); + + $this->assertNotNull($r); + + } + + public function testPaymentJsonExport() { \App\Models\Payment::factory()->count(5)->create([