Tax Reports

This commit is contained in:
David Bomba 2023-04-14 15:46:49 +10:00
parent d1b3fa12ba
commit e591dbb7cd
6 changed files with 288 additions and 20 deletions

View File

@ -11,14 +11,14 @@
namespace App\DataMapper\Schedule;
class EmailProductSalesReport
class EmailReport
{
/**
* Defines the template name
*
* @var string
*/
public string $template = 'email_product_sales_report';
public string $template = 'email_report';
/**
* An array of clients hashed_ids
@ -66,5 +66,8 @@ class EmailProductSalesReport
* @var string
*/
public string $end_date = '';
/** @var string $report_name */
public string $report_name = '';
}

View File

@ -45,6 +45,7 @@ class StoreSchedulerRequest extends Request
'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'],
'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'],
'parameters.entity_id' => ['bail', 'sometimes', 'string'],
'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report', 'in:ar_summary_report,ar_detail_report,tax_summary_report,user_sales_report,client_sales_report,client_balance_report,product_sales_report'],
];
return $rules;

View File

@ -19,9 +19,14 @@ use App\Utils\Traits\MakesDates;
use App\Jobs\Mail\NinjaMailerJob;
use App\Jobs\Mail\NinjaMailerObject;
use App\Export\CSV\ProductSalesExport;
use App\DataMapper\Schedule\EmailStatement;
use App\Services\Report\ARDetailReport;
use App\Services\Report\ARSummaryReport;
use App\Services\Report\ClientBalanceReport;
use App\Services\Report\ClientSalesReport;
use App\Services\Report\TaxSummaryReport;
use App\Services\Report\UserSalesReport;
class EmailProductSalesReport
class EmailReport
{
use MakesHash;
use MakesDates;
@ -30,7 +35,7 @@ class EmailProductSalesReport
private bool $multiple_clients = false;
private string $file_name = 'product_sales.csv';
private string $file_name = 'file.csv';
public function __construct(public Scheduler $scheduler)
{
@ -54,7 +59,25 @@ class EmailProductSalesReport
$data['clients'] = $this->transformKeys($this->scheduler->parameters['clients']);
}
$export = (new ProductSalesExport($this->scheduler->company, $data));
$export = false;
match($this->scheduler->parameters['report_name'])
{
'product_sales_report' => $export = (new ProductSalesExport($this->scheduler->company, $data)),
'email_ar_detailed_report' => (new ARDetailReport($this->scheduler->company, $data)),
'email_ar_summary_report' => (new ARSummaryReport($this->scheduler->company, $data)),
'email_tax_summary_report' => (new TaxSummaryReport($this->scheduler->company, $data)),
'email_client_balance_report' => (new ClientBalanceReport($this->scheduler->company, $data)),
'email_client_sales_report' => (new ClientSalesReport($this->scheduler->company, $data)),
'email_user_sales_report' => (new UserSalesReport($this->scheduler->company, $data)),
default => $export = false,
};
if(!$export) {
$this->cancelSchedule();
return;
}
$csv = $export->run();
//todo - potentially we send this to more than one user.
@ -72,7 +95,10 @@ class EmailProductSalesReport
}
private function cancelSchedule()
{
$this->scheduler->forceDelete();
}

View File

@ -14,7 +14,7 @@ namespace App\Services\Scheduler;
use App\Models\Scheduler;
use App\Utils\Traits\MakesHash;
use App\Utils\Traits\MakesDates;
use App\Services\Scheduler\EmailProductSalesReport;
use App\Services\Scheduler\EmailReport;
class SchedulerService
{
@ -49,11 +49,15 @@ class SchedulerService
(new EmailStatementService($this->scheduler))->run();
}
private function email_product_sales_report()
private function email_report()
{
(new EmailProductSalesReport($this->scheduler))->run();
match($this->scheduler->template){
'product_sales_report' => (new EmailReport($this->scheduler))->run(),
default => null
};
}
/**
* Sets the next run date of the scheduled task
*

View File

@ -0,0 +1,203 @@
<?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 App\DataMapper\CompanySettings;
use App\Factory\InvoiceItemFactory;
use App\Models\Account;
use App\Models\Client;
use App\Models\Company;
use App\Models\Invoice;
use App\Models\User;
use App\Services\Report\ARDetailReport;
use App\Services\Report\TaxSummaryReport;
use App\Utils\Traits\MakesHash;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Tests\TestCase;
/**
* @test
*/
class TaxSummaryReportTest extends TestCase
{
use MakesHash;
public $faker;
protected function setUp() :void
{
parent::setUp();
$this->faker = \Faker\Factory::create();
$this->withoutMiddleware(
ThrottleRequests::class
);
$this->withoutExceptionHandling();
}
public $company;
public $user;
public $payload;
public $account;
public $client;
/**
* 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->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,
'company_id' => $this->company->id,
'is_deleted' => 0,
]);
}
public function testUserSalesInstance()
{
$this->buildData();
$pl = new TaxSummaryReport($this->company, $this->payload);
$this->assertInstanceOf(TaxSummaryReport::class, $pl);
$this->account->delete();
}
public function testSimpleReport()
{
$this->buildData();
$this->payload = [
'start_date' => '2000-01-01',
'end_date' => '2030-01-11',
'date_range' => 'custom',
'client_id' => $this->client->id,
'report_keys' => []
];
$i = Invoice::factory()->create([
'client_id' => $this->client->id,
'user_id' => $this->user->id,
'company_id' => $this->company->id,
'amount' => 0,
'balance' => 0,
'status_id' => 2,
'total_taxes' => 1,
'date' => now()->format('Y-m-d'),
'terms' => 'nada',
'discount' => 0,
'tax_rate1' => 10,
'tax_rate2' => 17.5,
'tax_rate3' => 5,
'tax_name1' => 'GST',
'tax_name2' => 'VAT',
'tax_name3' => 'CA Sales Tax',
'uses_inclusive_taxes' => false,
'line_items' => $this->buildLineItems(),
]);
$i = $i->calc()->getInvoice();
$pl = new TaxSummaryReport($this->company, $this->payload);
$response = $pl->run();
$this->assertIsString($response);
$this->account->delete();
}
private function buildLineItems()
{
$line_items = [];
$item = InvoiceItemFactory::create();
$item->quantity = 1;
$item->cost = 10;
$item->product_key = 'test';
$item->notes = 'test_product';
// $item->task_id = $this->encodePrimaryKey($this->task->id);
// $item->expense_id = $this->encodePrimaryKey($this->expense->id);
$line_items[] = $item;
$item = InvoiceItemFactory::create();
$item->quantity = 1;
$item->cost = 10;
$item->product_key = 'pumpkin';
$item->notes = 'test_pumpkin';
// $item->task_id = $this->encodePrimaryKey($this->task->id);
// $item->expense_id = $this->encodePrimaryKey($this->expense->id);
$line_items[] = $item;
return $line_items;
}
}

View File

@ -25,7 +25,7 @@ use App\DataMapper\Schedule\EmailStatement;
use Illuminate\Validation\ValidationException;
use Illuminate\Foundation\Testing\WithoutEvents;
use App\Services\Scheduler\EmailStatementService;
use App\Services\Scheduler\EmailProductSalesReport;
use App\Services\Scheduler\EmailReport;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Routing\Middleware\ThrottleRequests;
@ -59,18 +59,48 @@ class SchedulerTest extends TestCase
// $this->withoutExceptionHandling();
}
public function testReportValidationRules()
{
$data = [
'name' => 'A test product sales scheduler',
'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY,
'next_run' => now()->format('Y-m-d'),
'template' => 'email_report',
'parameters' => [
'date_range' => EmailStatement::LAST_MONTH,
'clients' => [],
'report_keys' => [],
'client_id' => $this->client->hashed_id,
'report_name' => '',
],
];
$response = false;
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson('/api/v1/task_schedulers', $data);
$response->assertStatus(422);
}
public function testProductSalesReportGenerationOneClientSeparateParam()
{
$data = [
'name' => 'A test product sales scheduler',
'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY,
'next_run' => now()->format('Y-m-d'),
'template' => 'email_product_sales_report',
'template' => 'email_report',
'parameters' => [
'date_range' => EmailStatement::LAST_MONTH,
'clients' => [],
'report_keys' => [],
'client_id' => $this->client->hashed_id,
'report_name' => 'product_sales_report',
],
];
@ -99,7 +129,7 @@ class SchedulerTest extends TestCase
$this->assertNotNull($scheduler);
$export = (new EmailProductSalesReport($scheduler))->run();
$export = (new EmailReport($scheduler))->run();
$this->assertEquals(now()->addMonth()->format('Y-m-d'), $scheduler->next_run->format('Y-m-d'));
@ -111,13 +141,13 @@ class SchedulerTest extends TestCase
'name' => 'A test product sales scheduler',
'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY,
'next_run' => now()->format('Y-m-d'),
'template' => 'email_product_sales_report',
'template' => 'email_report',
'parameters' => [
'date_range' => EmailStatement::LAST_MONTH,
'clients' => [$this->client->hashed_id],
'report_keys' => [],
'client_id' => null,
'report_name' => 'product_sales_report',
],
];
@ -145,7 +175,7 @@ class SchedulerTest extends TestCase
$this->assertNotNull($scheduler);
$export = (new EmailProductSalesReport($scheduler))->run();
$export = (new EmailReport($scheduler))->run();
$this->assertEquals(now()->addMonth()->format('Y-m-d'), $scheduler->next_run->format('Y-m-d'));
@ -157,13 +187,13 @@ class SchedulerTest extends TestCase
'name' => 'A test product sales scheduler',
'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY,
'next_run' => now()->format('Y-m-d'),
'template' => 'email_product_sales_report',
'template' => 'email_report',
'parameters' => [
'date_range' => EmailStatement::LAST_MONTH,
'clients' => [],
'report_keys' => [],
'client_id' => null,
'report_name' => 'product_sales_report',
],
];
@ -188,7 +218,7 @@ class SchedulerTest extends TestCase
$this->assertNotNull($scheduler);
$export = (new EmailProductSalesReport($scheduler))->run();
$export = (new EmailReport($scheduler))->run();
$this->assertEquals(now()->addMonth()->format('Y-m-d'), $scheduler->next_run->format('Y-m-d'));
@ -200,10 +230,11 @@ class SchedulerTest extends TestCase
'name' => 'A test product sales scheduler',
'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY,
'next_run' => now()->format('Y-m-d'),
'template' => 'email_product_sales_report',
'template' => 'email_report',
'parameters' => [
'date_range' => EmailStatement::LAST_MONTH,
'clients' => [],
'report_name' => 'product_sales_report',
],
];