mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Tax Reports
This commit is contained in:
parent
d1b3fa12ba
commit
e591dbb7cd
@ -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 = '';
|
||||
}
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
203
tests/Feature/Export/TaxSummaryReportTest.php
Normal file
203
tests/Feature/Export/TaxSummaryReportTest.php
Normal 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;
|
||||
}
|
||||
}
|
@ -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',
|
||||
],
|
||||
];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user