mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 14:57:32 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			1864 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1864 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * Invoice Ninja (https://invoiceninja.com).
 | |
|  *
 | |
|  * @link https://github.com/invoiceninja/invoiceninja source repository
 | |
|  *
 | |
|  * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | |
|  *
 | |
|  * @license https://www.elastic.co/licensing/elastic-license
 | |
|  */
 | |
| 
 | |
| namespace Tests\Feature\Export;
 | |
| 
 | |
| use Tests\TestCase;
 | |
| use App\Models\User;
 | |
| use App\Models\Client;
 | |
| use App\Models\Credit;
 | |
| use League\Csv\Reader;
 | |
| use App\Models\Account;
 | |
| use App\Models\Company;
 | |
| use App\Models\Expense;
 | |
| use App\Models\Invoice;
 | |
| use Tests\MockAccountData;
 | |
| use App\Models\CompanyToken;
 | |
| use App\Models\ClientContact;
 | |
| use App\Export\CSV\TaskExport;
 | |
| use App\Utils\Traits\MakesHash;
 | |
| use App\Export\CSV\VendorExport;
 | |
| use App\Export\CSV\ProductExport;
 | |
| use App\DataMapper\CompanySettings;
 | |
| use App\Export\CSV\PaymentExport;
 | |
| use App\Factory\CompanyUserFactory;
 | |
| use App\Factory\InvoiceItemFactory;
 | |
| use App\Services\Report\ARDetailReport;
 | |
| use Illuminate\Routing\Middleware\ThrottleRequests;
 | |
| 
 | |
| /**
 | |
|  * @test
 | |
|  */
 | |
| class ReportCsvGenerationTest extends TestCase
 | |
| {
 | |
|     use MakesHash;
 | |
| 
 | |
|     public $faker;
 | |
| 
 | |
|     protected function setUp() :void
 | |
|     {
 | |
|         parent::setUp();
 | |
| 
 | |
|         $this->faker = \Faker\Factory::create();
 | |
| 
 | |
|         $this->withoutMiddleware(
 | |
|             ThrottleRequests::class
 | |
|         );
 | |
| 
 | |
|         $this->withoutExceptionHandling();
 | |
| 
 | |
|         $this->buildData();
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public $company;
 | |
| 
 | |
|     public $user;
 | |
| 
 | |
|     public $payload;
 | |
| 
 | |
|     public $account;
 | |
| 
 | |
|     public $client;
 | |
| 
 | |
|     public $token;
 | |
| 
 | |
|     public $cu;
 | |
| 
 | |
|     private $all_client_report_keys =  [
 | |
|         "client.name",
 | |
|         "client.user",
 | |
|         "client.assigned_user",
 | |
|         "client.balance",
 | |
|         "client.address1",
 | |
|         "client.address2",
 | |
|         "client.city",
 | |
|         "client.country_id",
 | |
|         "client.currency_id",
 | |
|         "client.custom_value1",
 | |
|         "client.custom_value2",
 | |
|         "client.custom_value3",
 | |
|         "client.custom_value4",
 | |
|         "client.industry_id",
 | |
|         "client.id_number",
 | |
|         "client.paid_to_date",
 | |
|         "client.payment_terms",
 | |
|         "client.phone",
 | |
|         "client.postal_code",
 | |
|         "client.private_notes",
 | |
|         "client.public_notes",
 | |
|         "client.size_id",
 | |
|         "client.shipping_address1",
 | |
|         "client.shipping_address2",
 | |
|         "client.shipping_city",
 | |
|         "client.shipping_state",
 | |
|         "client.shipping_postal_code",
 | |
|         "client.shipping_country_id",
 | |
|         "client.state",
 | |
|         "client.vat_number",
 | |
|         "client.website",
 | |
|         "contact.first_name",
 | |
|         "contact.last_name",
 | |
|         "contact.email",
 | |
|         "contact.phone",
 | |
|         "contact.custom_value1",
 | |
|         "contact.custom_value2",
 | |
|         "contact.custom_value3",
 | |
|         "contact.custom_value4",
 | |
|     ];
 | |
| 
 | |
|     private $all_payment_report_keys = [  
 | |
|             'payment.date',
 | |
|             'payment.amount',
 | |
|             'payment.refunded',
 | |
|             'payment.applied',
 | |
|             'payment.transaction_reference',
 | |
|             'payment.currency',
 | |
|             'payment.exchange_rate',
 | |
|             'payment.number',
 | |
|             'payment.method',
 | |
|             'payment.status',
 | |
|             'payment.private_notes',
 | |
|             'payment.custom_value1',
 | |
|             'payment.custom_value2',
 | |
|             'payment.custom_value3',
 | |
|             'payment.custom_value4',
 | |
|             'payment.user_id',
 | |
|             'payment.assigned_user_id'
 | |
|         ];
 | |
| 
 | |
|     private $all_invoice_report_keys = [
 | |
|         'invoice.number',
 | |
|         'invoice.amount',
 | |
|         'invoice.balance',
 | |
|         'invoice.paid_to_date',
 | |
|         'invoice.discount',
 | |
|         'invoice.po_number',
 | |
|         'invoice.date',
 | |
|         'invoice.due_date',
 | |
|         'invoice.terms',
 | |
|         'invoice.footer',
 | |
|         'invoice.status',
 | |
|         'invoice.public_notes',
 | |
|         'invoice.private_notes',
 | |
|         'invoice.uses_inclusive_taxes',
 | |
|         'invoice.is_amount_discount',
 | |
|         'invoice.partial',
 | |
|         'invoice.partial_due_date',
 | |
|         'invoice.custom_value1',
 | |
|         'invoice.custom_value2',
 | |
|         'invoice.custom_value3',
 | |
|         'invoice.custom_value4',
 | |
|         'invoice.custom_surcharge1',
 | |
|         'invoice.custom_surcharge2',
 | |
|         'invoice.custom_surcharge3',
 | |
|         'invoice.custom_surcharge4',
 | |
|         'invoice.exchange_rate',
 | |
|         'invoice.total_taxes',
 | |
|         'invoice.assigned_user_id',
 | |
|         'invoice.user_id',
 | |
|     ];
 | |
| 
 | |
|     /**
 | |
|      *      start_date - Y-m-d
 | |
|             end_date - Y-m-d
 | |
|             date_range -
 | |
|                 all
 | |
|                 last7
 | |
|                 last30
 | |
|                 this_month
 | |
|                 last_month
 | |
|                 this_quarter
 | |
|                 last_quarter
 | |
|                 this_year
 | |
|                 custom
 | |
|             is_income_billed - true = Invoiced || false = Payments
 | |
|             expense_billed - true = Expensed || false = Expenses marked as paid
 | |
|             include_tax - true tax_included || false - tax_excluded
 | |
|      */
 | |
|     private function buildData()
 | |
|     {
 | |
|         $this->account = Account::factory()->create([
 | |
|             'hosted_client_count' => 1000,
 | |
|             'hosted_company_count' => 1000,
 | |
|         ]);
 | |
| 
 | |
|         $this->account->num_users = 3;
 | |
|         $this->account->save();
 | |
| 
 | |
|         $this->user = User::factory()->create([
 | |
|             'account_id' => $this->account->id,
 | |
|             'confirmation_code' => 'xyz123',
 | |
|             'email' => $this->faker->unique()->safeEmail(),
 | |
|         ]);
 | |
| 
 | |
|         $settings = CompanySettings::defaults();
 | |
|         $settings->client_online_payment_notification = false;
 | |
|         $settings->client_manual_payment_notification = false;
 | |
| 
 | |
|         $this->company = Company::factory()->create([
 | |
|             'account_id' => $this->account->id,
 | |
|             'settings' => $settings,
 | |
|         ]);
 | |
| 
 | |
|         $this->company->settings = $settings;
 | |
|         $this->company->save();
 | |
| 
 | |
|         $this->cu = CompanyUserFactory::create($this->user->id, $this->company->id, $this->account->id);
 | |
|         $this->cu->is_owner = true;
 | |
|         $this->cu->is_admin = true;
 | |
|         $this->cu->is_locked = false;
 | |
|         $this->cu->save();
 | |
| 
 | |
|         $this->token = \Illuminate\Support\Str::random(64);
 | |
| 
 | |
|         $company_token = new CompanyToken;
 | |
|         $company_token->user_id = $this->user->id;
 | |
|         $company_token->company_id = $this->company->id;
 | |
|         $company_token->account_id = $this->account->id;
 | |
|         $company_token->name = 'test token';
 | |
|         $company_token->token = $this->token;
 | |
|         $company_token->is_system = true;
 | |
| 
 | |
|         $company_token->save();
 | |
| 
 | |
|         $this->payload = [
 | |
|             'start_date' => '2000-01-01',
 | |
|             'end_date' => '2030-01-11',
 | |
|             'date_range' => 'custom',
 | |
|             'is_income_billed' => true,
 | |
|             'include_tax' => false,
 | |
|         ];
 | |
| 
 | |
|         $this->client = Client::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             // 'assigned_user_id', $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'is_deleted' => 0,
 | |
|             'name' => 'bob',
 | |
|             'address1' => '1234',
 | |
|             'balance' => 100,
 | |
|             'paid_to_date' => 50,
 | |
|         ]);
 | |
| 
 | |
|         ClientContact::factory()->create([
 | |
|                 'user_id' => $this->user->id,
 | |
|                 'client_id' => $this->client->id,
 | |
|                 'company_id' => $this->company->id,
 | |
|                 'is_primary' => 1,
 | |
|                 'first_name' => 'john',
 | |
|                 'last_name' => 'doe',
 | |
|                 'email' => 'john@doe.com'
 | |
|             ]);
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testVendorCsvGeneration()
 | |
|     {
 | |
|         
 | |
|         $vendor =
 | |
|         \App\Models\Vendor::factory()->create(
 | |
|             [
 | |
|                 'user_id' => $this->user->id,
 | |
|                 'company_id' => $this->company->id,
 | |
|                 'name' => 'Vendor 1',
 | |
|                 'city' => 'city',
 | |
|                 'address1' => 'address1',
 | |
|                 'address2' => 'address2',
 | |
|                 'postal_code' => 'postal_code',
 | |
|                 'phone' => 'work_phone',
 | |
|                 'private_notes' => 'private_notes',
 | |
|                 'public_notes' => 'public_notes',
 | |
|                 'website' => 'website',
 | |
|                 'number' => '1234', 
 | |
|             ]
 | |
|         );
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             // 'report_keys' => ["vendor.name","purchase_order.number","purchase_order.amount", "item.quantity", "item.cost", "item.line_total", "item.discount", "item.notes", "item.product_key", "item.custom_value1", "item.tax_name1", "item.tax_rate1",],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/vendors', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('Vendor 1', $this->getFirstValueByColumn($csv, 'Vendor Name'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Vendor Number'));
 | |
|         $this->assertEquals('city', $this->getFirstValueByColumn($csv, 'Vendor City'));
 | |
|         $this->assertEquals('address1', $this->getFirstValueByColumn($csv, 'Vendor Street'));
 | |
|         $this->assertEquals('address2', $this->getFirstValueByColumn($csv, 'Vendor Apt/Suite'));
 | |
|         $this->assertEquals('postal_code', $this->getFirstValueByColumn($csv, 'Vendor Postal Code'));
 | |
|         $this->assertEquals('work_phone', $this->getFirstValueByColumn($csv, 'Vendor Phone'));
 | |
|         $this->assertEquals('private_notes', $this->getFirstValueByColumn($csv, 'Vendor Private Notes'));
 | |
|         $this->assertEquals('public_notes', $this->getFirstValueByColumn($csv, 'Vendor Public Notes'));
 | |
|         $this->assertEquals('website', $this->getFirstValueByColumn($csv, 'Vendor Website'));
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             // 'end_date' => 'bail|required_if:date_range,custom|nullable|date',
 | |
|             // 'start_date' => 'bail|required_if:date_range,custom|nullable|date',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|             // 'status' => 'sometimes|string|nullable|in:all,draft,sent,viewed,paid,unpaid,overdue',
 | |
|         ];
 | |
| 
 | |
|         $export = new VendorExport($this->company, $data);
 | |
|         $data = $export->returnJson();
 | |
| 
 | |
|         $this->assertNotNull($data);
 | |
| 
 | |
|         $this->assertEquals(0, $this->traverseJson($data, 'columns.0.identifier'));
 | |
|         $this->assertEquals('Vendor Name', $this->traverseJson($data, 'columns.9.display_value'));
 | |
|         $this->assertEquals('vendor', $this->traverseJson($data, '0.0.entity'));
 | |
|         $this->assertEquals('address1', $this->traverseJson($data, '0.0.id'));
 | |
|         $this->assertNull($this->traverseJson($data, '0.0.hashed_id'));
 | |
|         $this->assertEquals('address1', $this->traverseJson($data, '0.0.value'));
 | |
|         $this->assertEquals('vendor.address1', $this->traverseJson($data, '0.0.identifier'));
 | |
|         $this->assertEquals('address1', $this->traverseJson($data, '0.0.display_value'));
 | |
|     }
 | |
| 
 | |
|     public function testVendorCustomColumnCsvGeneration()   
 | |
|     {
 | |
|         
 | |
|         \App\Models\Vendor::query()->cursor()->each(function ($t) {
 | |
|             $t->forceDelete();
 | |
|         });
 | |
| 
 | |
|         $vendor =
 | |
|         \App\Models\Vendor::factory()->create(
 | |
|             [
 | |
|                 'user_id' => $this->user->id,
 | |
|                 'company_id' => $this->company->id,
 | |
|                 'name' => 'Vendor 1',
 | |
|                 'city' => 'city',
 | |
|                 'address1' => 'address1',
 | |
|                 'address2' => 'address2',
 | |
|                 'postal_code' => 'postal_code',
 | |
|                 'phone' => 'work_phone',
 | |
|                 'private_notes' => 'private_notes',
 | |
|                 'public_notes' => 'public_notes',
 | |
|                 'website' => 'website',
 | |
|                 'number' => '1234', 
 | |
|             ]
 | |
|         );
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => ["vendor.name", "vendor.city", "vendor.number"],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/vendors', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('Vendor 1', $this->getFirstValueByColumn($csv, 'Vendor Name'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Vendor Number'));
 | |
|         $this->assertEquals('city', $this->getFirstValueByColumn($csv, 'Vendor City'));
 | |
| 
 | |
|         $export = new VendorExport($this->company, $data);
 | |
|         $data = $export->returnJson();
 | |
| 
 | |
|         $this->assertNotNull($data);
 | |
| 
 | |
|         $this->assertEquals(0, $this->traverseJson($data, 'columns.0.identifier'));
 | |
|         $this->assertEquals('Vendor Name', $this->traverseJson($data, 'columns.0.display_value'));
 | |
|         $this->assertEquals('vendor', $this->traverseJson($data, '0.0.entity'));
 | |
|         $this->assertEquals('name', $this->traverseJson($data, '0.0.id'));
 | |
|         $this->assertNull($this->traverseJson($data, '0.0.hashed_id'));
 | |
|         $this->assertEquals('Vendor 1', $this->traverseJson($data, '0.0.value'));
 | |
|         $this->assertEquals('vendor.name', $this->traverseJson($data, '0.0.identifier'));
 | |
|         $this->assertEquals('Vendor 1', $this->traverseJson($data, '0.0.display_value'));
 | |
|         $this->assertEquals('number', $this->traverseJson($data, '0.2.id'));
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testTaskCustomColumnsCsvGeneration()    
 | |
|     {
 | |
| 
 | |
|         $invoice = \App\Models\Invoice::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'date' => '2023-01-01',
 | |
|             'amount' => 1000,
 | |
|             'balance' => 1000,
 | |
|             'number' => '123456',
 | |
|             'status_id' => 2,
 | |
|             'discount' => 10,
 | |
|             'po_number' => '12345',
 | |
|             'public_notes' => 'Public5',
 | |
|             'private_notes' => 'Private5',
 | |
|             'terms' => 'Terms5',
 | |
|             ]);
 | |
| 
 | |
| 
 | |
|         $log =  '[[1689547165,1689550765,"sumtin",true]]';
 | |
| 
 | |
|         \App\Models\Task::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'invoice_id' => $invoice->id,
 | |
|             'description' => 'test1',
 | |
|             'time_log' => $log,
 | |
|             'custom_value1' => 'Custom 11',
 | |
|             'custom_value2' => 'Custom 22',
 | |
|             'custom_value3' => 'Custom 33',
 | |
|             'custom_value4' => 'Custom 44',
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [
 | |
|                 'client.name',
 | |
|                 'invoice.number',
 | |
|                 'invoice.amount',
 | |
|                 'task.start_date',
 | |
|                 'task.end_date',
 | |
|                 'task.duration',
 | |
|                 'task.description',
 | |
|                 'task.custom_value1',
 | |
|                 'task.custom_value2',
 | |
|                 'task.custom_value3',
 | |
|                 'task.custom_value4',
 | |
|             ],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/tasks', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals(3600, $this->getFirstValueByColumn($csv, 'Task Duration'));
 | |
|         $this->assertEquals('test1', $this->getFirstValueByColumn($csv, 'Task Description'));
 | |
|         $this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Task Start Date'));
 | |
|         $this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Task End Date'));
 | |
|         $this->assertEquals('Custom 11', $this->getFirstValueByColumn($csv, 'Task Custom Value 1'));
 | |
|         $this->assertEquals('Custom 22', $this->getFirstValueByColumn($csv, 'Task Custom Value 2'));
 | |
|         $this->assertEquals('Custom 33', $this->getFirstValueByColumn($csv, 'Task Custom Value 3'));
 | |
|         $this->assertEquals('Custom 44', $this->getFirstValueByColumn($csv, 'Task Custom Value 4'));
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals('123456', $this->getFirstValueByColumn($csv, 'Invoice Invoice Number'));
 | |
|         $this->assertEquals(1000, $this->getFirstValueByColumn($csv, 'Invoice Amount'));
 | |
| 
 | |
|         $export = new TaskExport($this->company, $data);
 | |
|         $data = $export->returnJson();
 | |
| 
 | |
|         $this->assertNotNull($data);
 | |
| 
 | |
|         $this->assertEquals(0, $this->traverseJson($data, 'columns.0.identifier'));
 | |
|         $this->assertEquals('Client Name', $this->traverseJson($data, 'columns.0.display_value'));
 | |
|         $this->assertEquals('client', $this->traverseJson($data, '0.0.entity'));
 | |
|         $this->assertEquals('name', $this->traverseJson($data, '0.0.id'));
 | |
|         $this->assertNotNull($this->traverseJson($data, '0.0.hashed_id'));
 | |
|         $this->assertEquals('bob', $this->traverseJson($data, '0.0.value'));
 | |
|         $this->assertEquals('client.name', $this->traverseJson($data, '0.0.identifier'));
 | |
|         $this->assertEquals('bob', $this->traverseJson($data, '0.0.display_value'));
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_client_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/tasks', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => array_merge(["task.date","task.number"], $this->all_invoice_report_keys),
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/tasks', $data);
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|     public function testTasksCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         \App\Models\Task::query()->cursor()->each(function ($t) {
 | |
|             $t->forceDelete();
 | |
|         });
 | |
| 
 | |
|         $log =  '[[1689547165,1689550765,"sumtin",true]]';
 | |
| 
 | |
|         \App\Models\Task::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'description' => 'test',
 | |
|             'time_log' => $log,
 | |
|             'custom_value1' => 'Custom 1',
 | |
|             'custom_value2' => 'Custom 2',
 | |
|             'custom_value3' => 'Custom 3',
 | |
|             'custom_value4' => 'Custom 4',
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/tasks', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals(3600, $this->getFirstValueByColumn($csv, 'Task Duration'));
 | |
|         $this->assertEquals('test', $this->getFirstValueByColumn($csv, 'Task Description'));
 | |
|         $this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Task Start Date'));
 | |
|         $this->assertEquals('16/Jul/2023', $this->getFirstValueByColumn($csv, 'Task End Date'));
 | |
|         $this->assertEquals('Custom 1', $this->getFirstValueByColumn($csv, 'Task Custom Value 1'));
 | |
|         $this->assertEquals('Custom 2', $this->getFirstValueByColumn($csv, 'Task Custom Value 2'));
 | |
|         $this->assertEquals('Custom 3', $this->getFirstValueByColumn($csv, 'Task Custom Value 3'));
 | |
|         $this->assertEquals('Custom 4', $this->getFirstValueByColumn($csv, 'Task Custom Value 4'));
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public function testProductsCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         \App\Models\Product::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'product_key' => 'product_key',
 | |
|             'notes' => 'notes',
 | |
|             'cost' => 100,
 | |
|             'quantity' => 1,
 | |
|             'custom_value1' => 'Custom 1',
 | |
|             'custom_value2' => 'Custom 2',
 | |
|             'custom_value3' => 'Custom 3',
 | |
|             'custom_value4' => 'Custom 4',
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/products', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('product_key', $this->getFirstValueByColumn($csv, 'Product'));
 | |
|         $this->assertEquals('notes', $this->getFirstValueByColumn($csv, 'Notes'));
 | |
|         $this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Cost'));
 | |
|         $this->assertEquals(1, $this->getFirstValueByColumn($csv, 'Quantity'));
 | |
|         $this->assertEquals('Custom 1', $this->getFirstValueByColumn($csv, 'Custom Value 1'));
 | |
|         $this->assertEquals('Custom 2', $this->getFirstValueByColumn($csv, 'Custom Value 2'));
 | |
|         $this->assertEquals('Custom 3', $this->getFirstValueByColumn($csv, 'Custom Value 3'));
 | |
|         $this->assertEquals('Custom 4', $this->getFirstValueByColumn($csv, 'Custom Value 4'));    
 | |
| 
 | |
|         $export = new ProductExport($this->company, $data);
 | |
|         $data = $export->returnJson();
 | |
| 
 | |
|         $this->assertNotNull($data);
 | |
| 
 | |
|         $this->assertEquals(0, $this->traverseJson($data, 'columns.0.identifier'));
 | |
|         $this->assertEquals('Custom Value 1', $this->traverseJson($data, 'columns.0.display_value'));
 | |
|         $this->assertEquals('custom_value1', $this->traverseJson($data, '0.0.entity'));
 | |
|         $this->assertEquals('custom_value1', $this->traverseJson($data, '0.0.id'));
 | |
|         $this->assertNull($this->traverseJson($data, '0.0.hashed_id'));
 | |
|         $this->assertEquals('Custom 1', $this->traverseJson($data, '0.0.value'));
 | |
|         $this->assertEquals('custom_value1', $this->traverseJson($data, '0.0.identifier'));
 | |
|         $this->assertEquals('Custom 1', $this->traverseJson($data, '0.0.display_value'));
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testPaymentCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         $invoice = \App\Models\Invoice::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'date' => '2023-01-01',
 | |
|             'amount' => 100,
 | |
|             'balance' => 100,
 | |
|             'number' => '12345',
 | |
|             'status_id' => 2,
 | |
|             'discount' => 10,
 | |
|             'po_number' => '1234',
 | |
|             'public_notes' => 'Public',
 | |
|             'private_notes' => 'Private',
 | |
|             'terms' => 'Terms',
 | |
|             ]);
 | |
| 
 | |
|         $invoice->client->balance = 100;
 | |
|         $invoice->client->paid_to_date = 0;
 | |
|         $invoice->push();
 | |
| 
 | |
|         $invoice->service()->markPaid()->save();
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [
 | |
|                 "payment.date",
 | |
|                 "payment.amount",
 | |
|                 "invoice.number",
 | |
|                 "invoice.amount",
 | |
|                 "client.name",
 | |
|                 "client.balance",
 | |
|                 "client.paid_to_date"
 | |
|             ],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/payments', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Payment Amount'));
 | |
|         $this->assertEquals(now()->addSeconds($this->company->timezone()->utc_offset)->format('Y-m-d'), $this->getFirstValueByColumn($csv, 'Payment Date'));
 | |
|         $this->assertEquals('12345', $this->getFirstValueByColumn($csv, 'Invoice Invoice Number'));
 | |
|         $this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Invoice Amount'));
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals(0, $this->getFirstValueByColumn($csv, 'Client Balance'));
 | |
|         $this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Client Paid to Date'));
 | |
|             
 | |
|         $export = new PaymentExport($this->company, $data);
 | |
|         $data = $export->returnJson();
 | |
| 
 | |
|         $this->assertNotNull($data);
 | |
| 
 | |
|         $this->assertEquals(0, $this->traverseJson($data, 'columns.0.identifier'));
 | |
|         $this->assertEquals('Payment Date', $this->traverseJson($data, 'columns.0.display_value'));
 | |
|         $this->assertEquals(1, $this->traverseJson($data, 'columns.1.identifier'));
 | |
|         $this->assertEquals('Payment Amount', $this->traverseJson($data, 'columns.1.display_value'));
 | |
|         $this->assertEquals(2, $this->traverseJson($data, 'columns.2.identifier'));
 | |
|         $this->assertEquals('Invoice Invoice Number', $this->traverseJson($data, 'columns.2.display_value'));
 | |
|         $this->assertEquals(4, $this->traverseJson($data, 'columns.4.identifier'));
 | |
|         $this->assertEquals('Client Name', $this->traverseJson($data, 'columns.4.display_value'));
 | |
| 
 | |
| 
 | |
|         $this->assertEquals('payment', $this->traverseJson($data, '0.0.entity'));
 | |
|         $this->assertEquals('date', $this->traverseJson($data, '0.0.id'));
 | |
|         $this->assertNull($this->traverseJson($data, '0.0.hashed_id'));
 | |
|         $this->assertEquals('payment.date', $this->traverseJson($data, '0.0.identifier'));
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_client_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/payments', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
|         
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => array_merge(["payment.amount","payment.date"],$this->all_invoice_report_keys),
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/payments', $data);
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testPaymentCustomFieldsCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         \App\Models\Payment::factory()->create([
 | |
|             'amount' => 500,
 | |
|             'date' => '2020-01-01',
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'transaction_reference' => '1234',
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/payments', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals(500, $this->getFirstValueByColumn($csv, 'Payment Amount'));
 | |
|         $this->assertEquals(0, $this->getFirstValueByColumn($csv, 'Payment Applied'));
 | |
|         $this->assertEquals(0, $this->getFirstValueByColumn($csv, 'Payment Refunded'));
 | |
|         $this->assertEquals('2020-01-01', $this->getFirstValueByColumn($csv, 'Payment Date'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Payment Transaction Reference'));
 | |
|     
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testClientCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/clients', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| // nlog($csv);
 | |
|         $reader = Reader::createFromString($csv);
 | |
|         $reader->setHeaderOffset(0);
 | |
|         
 | |
|         $res = $reader->fetchColumnByName('Street');
 | |
|         $res = iterator_to_array($res, true);
 | |
| 
 | |
|         $this->assertEquals('1234', $res[1]);
 | |
| 
 | |
|         $res = $reader->fetchColumnByName('Name');
 | |
|         $res = iterator_to_array($res, true);
 | |
| 
 | |
|         $this->assertEquals('bob', $res[1]);
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public function testClientCustomColumnsCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => ["client.name","client.user","client.assigned_user","client.balance","client.paid_to_date","client.currency_id"],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/clients', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Name'));
 | |
|         $this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Balance'));
 | |
|         $this->assertEquals(50, $this->getFirstValueByColumn($csv, 'Paid to Date'));
 | |
|         $this->assertEquals($this->user->present()->name(), $this->getFirstValueByColumn($csv, 'Client User'));
 | |
|         $this->assertEquals('', $this->getFirstValueByColumn($csv, 'Client Assigned User'));
 | |
|         $this->assertEquals('USD', $this->getFirstValueByColumn($csv, 'Client Currency'));
 | |
| 
 | |
|     }
 | |
| 
 | |
|     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,
 | |
|         ])->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());
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public function testCreditCustomColumnsCsvGeneration()
 | |
|     {
 | |
|         
 | |
|         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', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Credit Credit Number'));
 | |
|         $this->assertEquals('Unpaid', $this->getFirstValueByColumn($csv, 'Payment Amount'));
 | |
|         $this->assertEquals('', $this->getFirstValueByColumn($csv, 'Payment Date'));
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_payment_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/credits', $data)->assertStatus(200);
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public function testInvoiceCustomColumnsCsvGeneration()
 | |
|     {
 | |
|         
 | |
|         \App\Models\Invoice::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","invoice.number","invoice.amount","payment.date", "payment.amount","invoice.user"],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/invoices', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| // nlog($csv);
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Invoice Invoice Number'));
 | |
|         $this->assertEquals('Unpaid', $this->getFirstValueByColumn($csv, 'Payment Amount'));
 | |
|         $this->assertEquals('', $this->getFirstValueByColumn($csv, 'Payment Date'));
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_client_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/invoices', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_payment_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/invoices', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
|     }
 | |
|     
 | |
|     public function testRecurringInvoiceCustomColumnsCsvGeneration()
 | |
|     {
 | |
|         
 | |
|         \App\Models\RecurringInvoice::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',
 | |
|            'frequency_id' => 1,
 | |
|        ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => ["client.name","recurring_invoice.number","recurring_invoice.amount", "recurring_invoice.frequency_id"],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/recurring_invoices', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Recurring Invoice Invoice Number'));
 | |
|         $this->assertEquals('Daily', $this->getFirstValueByColumn($csv, 'Recurring Invoice How Often'));
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_client_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/recurring_invoices', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testInvoiceItemsCustomColumnsCsvGeneration()
 | |
|     {
 | |
|         
 | |
|         \App\Models\Invoice::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',
 | |
|            'line_items' => [
 | |
|                 [
 | |
|                 'quantity' => 10,
 | |
|                 'cost' => 100,
 | |
|                 'line_total' => 1000,
 | |
|                 'is_amount_discount' => true,
 | |
|                 'discount' => 0,
 | |
|                 'notes' => 'item notes',
 | |
|                 'product_key' => 'product key',
 | |
|                 'custom_value1' => 'custom 1',
 | |
|                 'custom_value2' => 'custom 2',
 | |
|                 'custom_value3' => 'custom 3',
 | |
|                 'custom_value4' => 'custom 4',
 | |
|                 'tax_name1' => 'GST',
 | |
|                 'tax_rate1' => 10.00,
 | |
|                 'type_id' => '1',
 | |
|                 ],
 | |
|            ]
 | |
|        ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => ["client.name","invoice.number","invoice.amount","payment.date", "payment.amount", "item.quantity", "item.cost", "item.line_total", "item.discount", "item.notes", "item.product_key", "item.custom_value1", "item.tax_name1", "item.tax_rate1",],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/invoice_items', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| // nlog($csv);//
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Invoice Invoice Number'));
 | |
|         $this->assertEquals('Unpaid', $this->getFirstValueByColumn($csv, 'Payment Amount'));
 | |
|         $this->assertEquals('', $this->getFirstValueByColumn($csv, 'Payment Date'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Item Quantity'));
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Item Cost'));
 | |
|         $this->assertEquals('1000', $this->getFirstValueByColumn($csv, 'Item Line Total'));
 | |
|         $this->assertEquals('0', $this->getFirstValueByColumn($csv, 'Item Discount'));
 | |
|         $this->assertEquals('item notes', $this->getFirstValueByColumn($csv, 'Item Notes'));
 | |
|         $this->assertEquals('product key', $this->getFirstValueByColumn($csv, 'Item Product'));
 | |
|         $this->assertEquals('custom 1', $this->getFirstValueByColumn($csv, 'Item Custom Value 1'));
 | |
|         $this->assertEquals('GST', $this->getFirstValueByColumn($csv, 'Item Tax Name 1'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Item Tax Rate 1'));
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_client_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/invoice_items', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_payment_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/invoice_items', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testQuoteItemsCustomColumnsCsvGeneration()
 | |
|     {
 | |
|         
 | |
|         \App\Models\Quote::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',
 | |
|            'line_items' => [
 | |
|                 [
 | |
|                 'quantity' => 10,
 | |
|                 'cost' => 100,
 | |
|                 'line_total' => 1000,
 | |
|                 'is_amount_discount' => true,
 | |
|                 'discount' => 0,
 | |
|                 'notes' => 'item notes',
 | |
|                 'product_key' => 'product key',
 | |
|                 'custom_value1' => 'custom 1',
 | |
|                 'custom_value2' => 'custom 2',
 | |
|                 'custom_value3' => 'custom 3',
 | |
|                 'custom_value4' => 'custom 4',
 | |
|                 'tax_name1' => 'GST',
 | |
|                 'tax_rate1' => 10.00,
 | |
|                 'type_id' => '1',
 | |
|                 ],
 | |
|            ]
 | |
|        ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => ["client.name","quote.number","quote.amount", "item.quantity", "item.cost", "item.line_total", "item.discount", "item.notes", "item.product_key", "item.custom_value1", "item.tax_name1", "item.tax_rate1",],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/quote_items', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
| 
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Quote Number'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Item Quantity'));
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Item Cost'));
 | |
|         $this->assertEquals('1000', $this->getFirstValueByColumn($csv, 'Item Line Total'));
 | |
|         $this->assertEquals('0', $this->getFirstValueByColumn($csv, 'Item Discount'));
 | |
|         $this->assertEquals('item notes', $this->getFirstValueByColumn($csv, 'Item Notes'));
 | |
|         $this->assertEquals('product key', $this->getFirstValueByColumn($csv, 'Item Product'));
 | |
|         $this->assertEquals('custom 1', $this->getFirstValueByColumn($csv, 'Item Custom Value 1'));
 | |
|         $this->assertEquals('GST', $this->getFirstValueByColumn($csv, 'Item Tax Name 1'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Item Tax Rate 1'));
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_client_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/quote_items', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testPurchaseOrderCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         $vendor =
 | |
|         \App\Models\Vendor::factory()->create(
 | |
|             [
 | |
|                 'user_id' => $this->user->id,
 | |
|                 'company_id' => $this->company->id,
 | |
|                 'name' => 'Vendor 1',
 | |
|             ]
 | |
|         );
 | |
| 
 | |
|         \App\Models\PurchaseOrder::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'vendor_id' => $vendor->id,
 | |
|             'amount' => 100,
 | |
|             'balance' => 50,
 | |
|             'status_id' => 2,
 | |
|             'discount' => 10,
 | |
|             'number' => '1234',
 | |
|             'public_notes' => 'Public',
 | |
|             'private_notes' => 'Private',
 | |
|             'terms' => 'Terms',
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/purchase_orders', $data);
 | |
| 
 | |
|         $response->assertStatus(200);
 | |
| 
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Amount'));
 | |
|         $this->assertEquals('50', $this->getFirstValueByColumn($csv, 'Balance'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Discount'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Number'));
 | |
|         $this->assertEquals('Public', $this->getFirstValueByColumn($csv, 'Public Notes'));
 | |
|         $this->assertEquals('Private', $this->getFirstValueByColumn($csv, 'Private Notes'));
 | |
|         $this->assertEquals('Terms', $this->getFirstValueByColumn($csv, 'Terms'));
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testPurchaseOrderItemsCustomColumnsCsvGeneration()
 | |
|     {
 | |
|         
 | |
|         $vendor =
 | |
|         \App\Models\Vendor::factory()->create(
 | |
|             [
 | |
|                 'user_id' => $this->user->id,
 | |
|                 'company_id' => $this->company->id,
 | |
|                 'name' => 'Vendor 1',
 | |
|             ]
 | |
|         );
 | |
| 
 | |
| 
 | |
|         \App\Models\PurchaseOrder::factory()->create([
 | |
|            'user_id' => $this->user->id,
 | |
|            'company_id' => $this->company->id,
 | |
|            'vendor_id' => $vendor->id,
 | |
|            'amount' => 100,
 | |
|            'balance' => 50,
 | |
|            'number' => '1234',
 | |
|            'po_number' => '1234',
 | |
|            'status_id' => 2,
 | |
|            'discount' => 10,
 | |
|            'po_number' => '1234',
 | |
|            'public_notes' => 'Public',
 | |
|            'private_notes' => 'Private',
 | |
|            'terms' => 'Terms',
 | |
|            'line_items' => [
 | |
|                 [
 | |
|                 'quantity' => 10,
 | |
|                 'cost' => 100,
 | |
|                 'line_total' => 1000,
 | |
|                 'is_amount_discount' => true,
 | |
|                 'discount' => 0,
 | |
|                 'notes' => 'item notes',
 | |
|                 'product_key' => 'product key',
 | |
|                 'custom_value1' => 'custom 1',
 | |
|                 'custom_value2' => 'custom 2',
 | |
|                 'custom_value3' => 'custom 3',
 | |
|                 'custom_value4' => 'custom 4',
 | |
|                 'tax_name1' => 'GST',
 | |
|                 'tax_rate1' => 10.00,
 | |
|                 'type_id' => '1',
 | |
|                 ],
 | |
|            ]
 | |
|        ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => ["vendor.name","purchase_order.number","purchase_order.amount", "item.quantity", "item.cost", "item.line_total", "item.discount", "item.notes", "item.product_key", "item.custom_value1", "item.tax_name1", "item.tax_rate1",],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/purchase_order_items', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('Vendor 1', $this->getFirstValueByColumn($csv, 'Vendor Name'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Purchase Order Number'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Item Quantity'));
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Item Cost'));
 | |
|         $this->assertEquals('1000', $this->getFirstValueByColumn($csv, 'Item Line Total'));
 | |
|         $this->assertEquals('0', $this->getFirstValueByColumn($csv, 'Item Discount'));
 | |
|         $this->assertEquals('item notes', $this->getFirstValueByColumn($csv, 'Item Notes'));
 | |
|         $this->assertEquals('product key', $this->getFirstValueByColumn($csv, 'Item Product'));
 | |
|         $this->assertEquals('custom 1', $this->getFirstValueByColumn($csv, 'Item Custom Value 1'));
 | |
|         $this->assertEquals('GST', $this->getFirstValueByColumn($csv, 'Item Tax Name 1'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Item Tax Rate 1'));
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public function testQuoteCustomColumnsCsvGeneration()
 | |
|     {
 | |
|         
 | |
|         \App\Models\Quote::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","quote.number","quote.amount"],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/quotes', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Quote Number'));
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Quote Amount'));
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_client_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/quotes', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testInvoicePaidCustomColumnsCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         $invoice = \App\Models\Invoice::factory()->create([
 | |
|            'user_id' => $this->user->id,
 | |
|            'company_id' => $this->company->id,
 | |
|            'client_id' => $this->client->id,
 | |
|            'date' => '2023-01-01',
 | |
|            'amount' => 100,
 | |
|            'balance' => 100,
 | |
|            'number' => '12345',
 | |
|            'status_id' => 2,
 | |
|            'discount' => 10,
 | |
|            'po_number' => '1234',
 | |
|            'public_notes' => 'Public',
 | |
|            'private_notes' => 'Private',
 | |
|            'terms' => 'Terms',
 | |
|        ]);
 | |
| 
 | |
|        $invoice->service()->markPaid()->save();
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => ["client.name","invoice.number","invoice.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/invoices', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals('12345', $this->getFirstValueByColumn($csv, 'Invoice Invoice Number'));
 | |
|         $this->assertEquals(100, $this->getFirstValueByColumn($csv, 'Payment Amount'));
 | |
|         $this->assertEquals(now()->addSeconds($this->company->timezone()->utc_offset)->format('Y-m-d'), $this->getFirstValueByColumn($csv, 'Payment Date'));
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public function testClientContactCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/contacts', $data);
 | |
|        
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $reader = Reader::createFromString($csv);
 | |
|         $reader->setHeaderOffset(0);
 | |
|         
 | |
|         $res = $reader->fetchColumnByName('Contact First Name');
 | |
|         $res = iterator_to_array($res, true);
 | |
| 
 | |
|         $this->assertEquals('john', $res[1]);
 | |
| 
 | |
|         $res = $reader->fetchColumnByName('Contact Last Name');
 | |
|         $res = iterator_to_array($res, true);
 | |
| 
 | |
|         $this->assertEquals('doe', $res[1]);
 | |
| 
 | |
|         $res = $reader->fetchColumnByName('Contact Email');
 | |
|         $res = iterator_to_array($res, true);
 | |
| 
 | |
|         $this->assertEquals('john@doe.com', $res[1]);
 | |
| 
 | |
|     }
 | |
| 
 | |
|     private function traverseJson($array, $keys)
 | |
|     {
 | |
|         $value = data_get($array, $keys, false);
 | |
| 
 | |
|         return $value;
 | |
|     }
 | |
| 
 | |
|     private function getFirstValueByColumn($csv, $column)
 | |
|     {
 | |
|         $reader = Reader::createFromString($csv);
 | |
|         $reader->setHeaderOffset(0);
 | |
|         
 | |
|         $res = $reader->fetchColumnByName($column);
 | |
|         $res = iterator_to_array($res, true);
 | |
| 
 | |
|         return $res[1];
 | |
|     }
 | |
| 
 | |
|     public function testCreditCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         Credit::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'amount' => 100,
 | |
|             'balance' => 50,
 | |
|             'status_id' => 2,
 | |
|             'discount' => 10,
 | |
|             'po_number' => '1234',
 | |
|             'public_notes' => 'Public',
 | |
|             'private_notes' => 'Private',
 | |
|             'terms' => 'Terms',
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/credits', $data);
 | |
| 
 | |
|         $response->assertStatus(200);
 | |
| 
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Credit Amount'));
 | |
|         $this->assertEquals('50', $this->getFirstValueByColumn($csv, 'Credit Balance'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Credit Discount'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Credit PO Number'));
 | |
|         $this->assertEquals('Public', $this->getFirstValueByColumn($csv, 'Credit Public Notes'));
 | |
|         $this->assertEquals('Private', $this->getFirstValueByColumn($csv, 'Credit Private Notes'));
 | |
|         $this->assertEquals('Terms', $this->getFirstValueByColumn($csv, 'Credit Terms'));
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_client_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/credits', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_payment_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/credits', $data)->assertStatus(200);
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public function testInvoiceCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         Invoice::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'amount' => 100,
 | |
|             'balance' => 50,
 | |
|             'status_id' => 2,
 | |
|             'discount' => 10,
 | |
|             'po_number' => '1234',
 | |
|             'public_notes' => 'Public',
 | |
|             'private_notes' => 'Private',
 | |
|             'terms' => 'Terms',
 | |
|             'date' => '2020-01-01',
 | |
|             'due_date' => '2021-01-02',
 | |
|             'partial_due_date' => '2021-01-03',
 | |
|             'partial' => 10,
 | |
|             'discount' => 10,
 | |
|             'custom_value1' => 'Custom 1',
 | |
|             'custom_value2' => 'Custom 2',
 | |
|             'custom_value3' => 'Custom 3',
 | |
|             'custom_value4' => 'Custom 4',
 | |
|             'footer' => 'Footer',
 | |
|             'tax_name1' => 'Tax 1',
 | |
|             'tax_rate1' => 10,
 | |
|             'tax_name2' => 'Tax 2',
 | |
|             'tax_rate2' => 20,
 | |
|             'tax_name3' => 'Tax 3',
 | |
|             'tax_rate3' => 30,
 | |
| 
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/invoices', $data);
 | |
| 
 | |
|         $response->assertStatus(200);
 | |
| 
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Invoice Amount'));
 | |
|         $this->assertEquals('50', $this->getFirstValueByColumn($csv, 'Invoice Balance'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Invoice Discount'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Invoice PO Number'));
 | |
|         $this->assertEquals('Public', $this->getFirstValueByColumn($csv, 'Invoice Public Notes'));
 | |
|         $this->assertEquals('Private', $this->getFirstValueByColumn($csv, 'Invoice Private Notes'));
 | |
|         $this->assertEquals('Terms', $this->getFirstValueByColumn($csv, 'Invoice Terms'));
 | |
|         $this->assertEquals('2020-01-01', $this->getFirstValueByColumn($csv, 'Invoice Date'));
 | |
|         $this->assertEquals('2021-01-02', $this->getFirstValueByColumn($csv, 'Invoice Due Date'));
 | |
|         $this->assertEquals('2021-01-03', $this->getFirstValueByColumn($csv, 'Invoice Partial Due Date'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Invoice Partial/Deposit'));
 | |
|         $this->assertEquals('Custom 1', $this->getFirstValueByColumn($csv, 'Invoice Custom Value 1'));
 | |
|         $this->assertEquals('Custom 2', $this->getFirstValueByColumn($csv, 'Invoice Custom Value 2'));
 | |
|         $this->assertEquals('Custom 3', $this->getFirstValueByColumn($csv, 'Invoice Custom Value 3'));
 | |
|         $this->assertEquals('Custom 4', $this->getFirstValueByColumn($csv, 'Invoice Custom Value 4'));
 | |
|         $this->assertEquals('Footer', $this->getFirstValueByColumn($csv, 'Invoice Footer'));
 | |
|         $this->assertEquals('Tax 1', $this->getFirstValueByColumn($csv, 'Invoice Tax Name 1'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Invoice Tax Rate 1'));
 | |
|         $this->assertEquals('Tax 2', $this->getFirstValueByColumn($csv, 'Invoice Tax Name 2'));
 | |
|         $this->assertEquals('20', $this->getFirstValueByColumn($csv, 'Invoice Tax Rate 2'));
 | |
|         $this->assertEquals('Tax 3', $this->getFirstValueByColumn($csv, 'Invoice Tax Name 3'));
 | |
|         $this->assertEquals('30', $this->getFirstValueByColumn($csv, 'Invoice Tax Rate 3'));
 | |
|         $this->assertEquals('Sent', $this->getFirstValueByColumn($csv, 'Invoice Status'));
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public function testRecurringInvoiceCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         \App\Models\RecurringInvoice::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'amount' => 100,
 | |
|             'balance' => 50,
 | |
|             'status_id' => 2,
 | |
|             'discount' => 10,
 | |
|             'po_number' => '1234',
 | |
|             'public_notes' => 'Public',
 | |
|             'private_notes' => 'Private',
 | |
|             'terms' => 'Terms',
 | |
|             'date' => '2020-01-01',
 | |
|             'due_date' => '2021-01-02',
 | |
|             'partial_due_date' => '2021-01-03',
 | |
|             'partial' => 10,
 | |
|             'discount' => 10,
 | |
|             'custom_value1' => 'Custom 1',
 | |
|             'custom_value2' => 'Custom 2',
 | |
|             'custom_value3' => 'Custom 3',
 | |
|             'custom_value4' => 'Custom 4',
 | |
|             'footer' => 'Footer',
 | |
|             'tax_name1' => 'Tax 1',
 | |
|             'tax_rate1' => 10,
 | |
|             'tax_name2' => 'Tax 2',
 | |
|             'tax_rate2' => 20,
 | |
|             'tax_name3' => 'Tax 3',
 | |
|             'tax_rate3' => 30,
 | |
|             'frequency_id' => 1,
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/recurring_invoices', $data);
 | |
| 
 | |
|         $response->assertStatus(200);
 | |
| 
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Recurring Invoice Amount'));
 | |
|         $this->assertEquals('50', $this->getFirstValueByColumn($csv, 'Recurring Invoice Balance'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Recurring Invoice Discount'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Recurring Invoice PO Number'));
 | |
|         $this->assertEquals('Public', $this->getFirstValueByColumn($csv, 'Recurring Invoice Public Notes'));
 | |
|         $this->assertEquals('Private', $this->getFirstValueByColumn($csv, 'Recurring Invoice Private Notes'));
 | |
|         $this->assertEquals('Terms', $this->getFirstValueByColumn($csv, 'Recurring Invoice Terms'));
 | |
|         $this->assertEquals('2020-01-01', $this->getFirstValueByColumn($csv, 'Recurring Invoice Date'));
 | |
|         $this->assertEquals('2021-01-02', $this->getFirstValueByColumn($csv, 'Recurring Invoice Due Date'));
 | |
|         $this->assertEquals('2021-01-03', $this->getFirstValueByColumn($csv, 'Recurring Invoice Partial Due Date'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Recurring Invoice Partial/Deposit'));
 | |
|         $this->assertEquals('Custom 1', $this->getFirstValueByColumn($csv, 'Recurring Invoice Custom Value 1'));
 | |
|         $this->assertEquals('Custom 2', $this->getFirstValueByColumn($csv, 'Recurring Invoice Custom Value 2'));
 | |
|         $this->assertEquals('Custom 3', $this->getFirstValueByColumn($csv, 'Recurring Invoice Custom Value 3'));
 | |
|         $this->assertEquals('Custom 4', $this->getFirstValueByColumn($csv, 'Recurring Invoice Custom Value 4'));
 | |
|         $this->assertEquals('Footer', $this->getFirstValueByColumn($csv, 'Recurring Invoice Footer'));
 | |
|         $this->assertEquals('Tax 1', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Name 1'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Rate 1'));
 | |
|         $this->assertEquals('Tax 2', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Name 2'));
 | |
|         $this->assertEquals('20', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Rate 2'));
 | |
|         $this->assertEquals('Tax 3', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Name 3'));
 | |
|         $this->assertEquals('30', $this->getFirstValueByColumn($csv, 'Recurring Invoice Tax Rate 3'));
 | |
|         $this->assertEquals('Daily', $this->getFirstValueByColumn($csv, 'Recurring Invoice How Often'));
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testQuoteCsvGeneration()
 | |
|     {
 | |
| 
 | |
|         \App\Models\Quote::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'amount' => 100,
 | |
|             'balance' => 50,
 | |
|             'status_id' => 2,
 | |
|             'discount' => 10,
 | |
|             'po_number' => '1234',
 | |
|             'public_notes' => 'Public',
 | |
|             'private_notes' => 'Private',
 | |
|             'terms' => 'Terms',
 | |
|             'date' => '2020-01-01',
 | |
|             'due_date' => '2020-01-01',
 | |
|             'partial_due_date' => '2021-01-03',
 | |
|             'partial' => 10,
 | |
|             'discount' => 10,
 | |
|             'custom_value1' => 'Custom 1',
 | |
|             'custom_value2' => 'Custom 2',
 | |
|             'custom_value3' => 'Custom 3',
 | |
|             'custom_value4' => 'Custom 4',
 | |
|             'footer' => 'Footer',
 | |
|             'tax_name1' => 'Tax 1',
 | |
|             'tax_rate1' => 10,
 | |
|             'tax_name2' => 'Tax 2',
 | |
|             'tax_rate2' => 20,
 | |
|             'tax_name3' => 'Tax 3',
 | |
|             'tax_rate3' => 30,
 | |
| 
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/quotes', $data);
 | |
| 
 | |
|         $response->assertStatus(200);
 | |
| 
 | |
|         $csv = $response->streamedContent();
 | |
|         
 | |
|         //nlog($csv);
 | |
| 
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Quote Amount'));
 | |
|         $this->assertEquals('50', $this->getFirstValueByColumn($csv, 'Quote Balance'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Quote Discount'));
 | |
|         $this->assertEquals('1234', $this->getFirstValueByColumn($csv, 'Quote PO Number'));
 | |
|         $this->assertEquals('Public', $this->getFirstValueByColumn($csv, 'Quote Public Notes'));
 | |
|         $this->assertEquals('Private', $this->getFirstValueByColumn($csv, 'Quote Private Notes'));
 | |
|         $this->assertEquals('Terms', $this->getFirstValueByColumn($csv, 'Quote Terms'));
 | |
|         $this->assertEquals('2020-01-01', $this->getFirstValueByColumn($csv, 'Quote Date'));
 | |
|         $this->assertEquals('2020-01-01', $this->getFirstValueByColumn($csv, 'Quote Valid Until'));
 | |
|         $this->assertEquals('2021-01-03', $this->getFirstValueByColumn($csv, 'Quote Partial Due Date'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Quote Partial/Deposit'));
 | |
|         $this->assertEquals('Custom 1', $this->getFirstValueByColumn($csv, 'Quote Custom Value 1'));
 | |
|         $this->assertEquals('Custom 2', $this->getFirstValueByColumn($csv, 'Quote Custom Value 2'));
 | |
|         $this->assertEquals('Custom 3', $this->getFirstValueByColumn($csv, 'Quote Custom Value 3'));
 | |
|         $this->assertEquals('Custom 4', $this->getFirstValueByColumn($csv, 'Quote Custom Value 4'));
 | |
|         $this->assertEquals('Footer', $this->getFirstValueByColumn($csv, 'Quote Footer'));
 | |
|         $this->assertEquals('Tax 1', $this->getFirstValueByColumn($csv, 'Quote Tax Name 1'));
 | |
|         $this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Quote Tax Rate 1'));
 | |
|         $this->assertEquals('Tax 2', $this->getFirstValueByColumn($csv, 'Quote Tax Name 2'));
 | |
|         $this->assertEquals('20', $this->getFirstValueByColumn($csv, 'Quote Tax Rate 2'));
 | |
|         $this->assertEquals('Tax 3', $this->getFirstValueByColumn($csv, 'Quote Tax Name 3'));
 | |
|         $this->assertEquals('30', $this->getFirstValueByColumn($csv, 'Quote Tax Rate 3'));
 | |
|         $this->assertEquals('Expired', $this->getFirstValueByColumn($csv, 'Quote Status'));
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function testExpenseCsvGeneration()
 | |
|     {
 | |
|         Expense::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'amount' => 100,
 | |
|             'public_notes' => 'Public',
 | |
|             'private_notes' => 'Private',            
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => [],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/expenses', $data);
 | |
| 
 | |
|         $response->assertStatus(200);
 | |
| 
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Expense Amount'));
 | |
|         $this->assertEquals('Public', $this->getFirstValueByColumn($csv, 'Expense Public Notes'));
 | |
|         $this->assertEquals('Private', $this->getFirstValueByColumn($csv, 'Expense Private Notes'));
 | |
|         $this->assertEquals($this->user->present()->name(), $this->getFirstValueByColumn($csv, 'Expense User'));
 | |
|         
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => $this->all_client_report_keys,
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/expenses', $data)->assertStatus(200);
 | |
| 
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public function testExpenseCustomColumnsCsvGeneration()
 | |
|     {
 | |
|         $vendor = 
 | |
|         \App\Models\Vendor::factory()->create(
 | |
|             [
 | |
|                 'user_id' => $this->user->id,
 | |
|                 'company_id' => $this->company->id,
 | |
|                 'name' => 'Vendor 1',
 | |
|             ]
 | |
|         
 | |
|         );
 | |
| 
 | |
|         Expense::factory()->create([
 | |
|             'user_id' => $this->user->id,
 | |
|             'company_id' => $this->company->id,
 | |
|             'client_id' => $this->client->id,
 | |
|             'vendor_id' => $vendor->id,
 | |
|             'amount' => 100,
 | |
|             'public_notes' => 'Public',
 | |
|             'private_notes' => 'Private',   
 | |
|             'currency_id' => 1,         
 | |
|         ]);
 | |
| 
 | |
|         $data = [
 | |
|             'date_range' => 'all',
 | |
|             'report_keys' => ['client.name','vendor.name','expense.amount','expense.currency_id'],
 | |
|             'send_email' => false,
 | |
|         ];
 | |
| 
 | |
|         $response = $this->withHeaders([
 | |
|             'X-API-SECRET' => config('ninja.api_secret'),
 | |
|             'X-API-TOKEN' => $this->token,
 | |
|         ])->post('/api/v1/reports/expenses', $data);
 | |
| 
 | |
|         $response->assertStatus(200);
 | |
| 
 | |
|         $csv = $response->streamedContent();
 | |
| 
 | |
|         $this->assertEquals('bob', $this->getFirstValueByColumn($csv, 'Client Name'));
 | |
|         $this->assertEquals('Vendor 1', $this->getFirstValueByColumn($csv, 'Vendor Name'));
 | |
|         $this->assertEquals('100', $this->getFirstValueByColumn($csv, 'Expense Amount'));
 | |
|         $this->assertEquals('USD', $this->getFirstValueByColumn($csv, 'Expense Currency'));
 | |
|         
 | |
|     }
 | |
| 
 | |
| 
 | |
| } |