mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
commit
b3fddb8afc
@ -1 +1 @@
|
|||||||
5.7.37
|
5.7.38
|
@ -904,26 +904,6 @@ class CheckData extends Command
|
|||||||
public function checkClientSettings()
|
public function checkClientSettings()
|
||||||
{
|
{
|
||||||
if ($this->option('fix') == 'true') {
|
if ($this->option('fix') == 'true') {
|
||||||
// Client::query()->whereNull('settings->currency_id')->cursor()->each(function ($client){
|
|
||||||
|
|
||||||
// if(is_array($client->settings) && count($client->settings) == 0)
|
|
||||||
// {
|
|
||||||
// $settings = ClientSettings::defaults();
|
|
||||||
// $settings->currency_id = $client->company->settings->currency_id;
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// $settings = $client->settings;
|
|
||||||
// $settings->currency_id = $client->company->settings->currency_id;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// $client->settings = $settings;
|
|
||||||
// $client->save();
|
|
||||||
|
|
||||||
// $this->logMessage("Fixing currency for # {$client->id}");
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
Client::query()->whereNull('country_id')->cursor()->each(function ($client) {
|
Client::query()->whereNull('country_id')->cursor()->each(function ($client) {
|
||||||
$client->country_id = $client->company->settings->country_id;
|
$client->country_id = $client->company->settings->country_id;
|
||||||
$client->save();
|
$client->save();
|
||||||
|
@ -807,6 +807,24 @@ class BaseExport
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function applyFilters(Builder $query): Builder
|
||||||
|
{
|
||||||
|
|
||||||
|
if(isset($this->input['product_key'])) {
|
||||||
|
|
||||||
|
$products = explode(",", $this->input['product_key']);
|
||||||
|
|
||||||
|
$query->where(function ($q) use ($products) {
|
||||||
|
foreach($products as $product) {
|
||||||
|
$q->orWhereJsonContains('line_items', ['product_key' => $product]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
protected function addInvoiceStatusFilter($query, $status): Builder
|
protected function addInvoiceStatusFilter($query, $status): Builder
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -864,6 +882,8 @@ class BaseExport
|
|||||||
|
|
||||||
protected function addDateRange($query)
|
protected function addDateRange($query)
|
||||||
{
|
{
|
||||||
|
$query = $this->applyFilters($query);
|
||||||
|
|
||||||
$date_range = $this->input['date_range'];
|
$date_range = $this->input['date_range'];
|
||||||
|
|
||||||
if (array_key_exists('date_key', $this->input) && strlen($this->input['date_key']) > 1) {
|
if (array_key_exists('date_key', $this->input) && strlen($this->input['date_key']) > 1) {
|
||||||
|
@ -72,6 +72,8 @@ class InvoiceItemExport extends BaseExport
|
|||||||
|
|
||||||
$query = $this->addDateRange($query);
|
$query = $this->addDateRange($query);
|
||||||
|
|
||||||
|
$query = $this->applyFilters($query);
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -487,13 +487,19 @@ class InvoiceController extends BaseController
|
|||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
||||||
$action = $request->input('action');
|
$action = $request->input('action');
|
||||||
|
|
||||||
$ids = $request->input('ids');
|
$ids = $request->input('ids');
|
||||||
|
|
||||||
if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->company()->account->account_sms_verified) {
|
if (Ninja::isHosted() && (stripos($action, 'email') !== false) && !$user->company()->account->account_sms_verified) {
|
||||||
return response(['message' => 'Please verify your account to send emails.'], 400);
|
return response(['message' => 'Please verify your account to send emails.'], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**@var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if(in_array($request->action, ['auto_bill','mark_paid']) && $user->cannot('create', \App\Models\Payment::class)) {
|
||||||
|
return response(['message' => ctrans('texts.not_authorized'), 'errors' => ['ids' => [ctrans('texts.not_authorized')]]], 422);
|
||||||
|
}
|
||||||
|
|
||||||
$invoices = Invoice::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
|
$invoices = Invoice::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
|
||||||
|
|
||||||
if (! $invoices) {
|
if (! $invoices) {
|
||||||
@ -645,9 +651,13 @@ class InvoiceController extends BaseController
|
|||||||
|
|
||||||
private function performAction(Invoice $invoice, $action, $bulk = false)
|
private function performAction(Invoice $invoice, $action, $bulk = false)
|
||||||
{
|
{
|
||||||
|
/** @var \App\Models\User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
/*If we are using bulk actions, we don't want to return anything */
|
/*If we are using bulk actions, we don't want to return anything */
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'auto_bill':
|
case 'auto_bill':
|
||||||
|
|
||||||
AutoBill::dispatch($invoice->id, $invoice->company->db);
|
AutoBill::dispatch($invoice->id, $invoice->company->db);
|
||||||
return $this->itemResponse($invoice);
|
return $this->itemResponse($invoice);
|
||||||
|
|
||||||
@ -671,7 +681,6 @@ class InvoiceController extends BaseController
|
|||||||
break;
|
break;
|
||||||
case 'mark_paid':
|
case 'mark_paid':
|
||||||
if ($invoice->status_id == Invoice::STATUS_PAID || $invoice->is_deleted === true) {
|
if ($invoice->status_id == Invoice::STATUS_PAID || $invoice->is_deleted === true) {
|
||||||
// if ($invoice->balance < 0 || $invoice->status_id == Invoice::STATUS_PAID || $invoice->is_deleted === true) {
|
|
||||||
return $this->errorResponse(['message' => ctrans('texts.invoice_cannot_be_marked_paid')], 400);
|
return $this->errorResponse(['message' => ctrans('texts.invoice_cannot_be_marked_paid')], 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Http\Requests\Invoice;
|
namespace App\Http\Requests\Invoice;
|
||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
|
use App\Models\Payment;
|
||||||
|
|
||||||
class BulkInvoiceRequest extends Request
|
class BulkInvoiceRequest extends Request
|
||||||
{
|
{
|
||||||
|
@ -180,7 +180,7 @@ class PreviewInvoiceRequest extends Request
|
|||||||
$this->entity_plural = 'credits';
|
$this->entity_plural = 'credits';
|
||||||
return $this;
|
return $this;
|
||||||
case 'recurring_invoice':
|
case 'recurring_invoice':
|
||||||
$this->entity_plural = 'invoices';
|
$this->entity_plural = 'recurring_invoices';
|
||||||
return $this;
|
return $this;
|
||||||
default:
|
default:
|
||||||
$this->entity_plural = 'invoices';
|
$this->entity_plural = 'invoices';
|
||||||
|
@ -11,14 +11,20 @@
|
|||||||
|
|
||||||
namespace App\Jobs\Util;
|
namespace App\Jobs\Util;
|
||||||
|
|
||||||
use App\Models\Account;
|
|
||||||
use App\Utils\Ninja;
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use App\Utils\Ninja;
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Models\Vendor;
|
||||||
|
use App\Models\Account;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use App\Models\ClientContact;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
|
use App\Factory\ClientContactFactory;
|
||||||
|
use App\Factory\VendorContactFactory;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
class VersionCheck implements ShouldQueue
|
class VersionCheck implements ShouldQueue
|
||||||
{
|
{
|
||||||
@ -54,8 +60,60 @@ class VersionCheck implements ShouldQueue
|
|||||||
if ($account->plan == 'white_label' && $account->plan_expires && Carbon::parse($account->plan_expires)->lt(now())) {
|
if ($account->plan == 'white_label' && $account->plan_expires && Carbon::parse($account->plan_expires)->lt(now())) {
|
||||||
$account->plan = null;
|
$account->plan = null;
|
||||||
$account->plan_expires = null;
|
$account->plan_expires = null;
|
||||||
$account->save();
|
$account->saveQuietly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Client::query()->whereNull('country_id')->cursor()->each(function ($client) {
|
||||||
|
$client->country_id = $client->company->settings->country_id;
|
||||||
|
$client->saveQuietly();
|
||||||
|
});
|
||||||
|
|
||||||
|
Vendor::query()->whereNull('currency_id')->orWhere('currency_id', '')->cursor()->each(function ($vendor) {
|
||||||
|
$vendor->currency_id = $vendor->company->settings->currency_id;
|
||||||
|
$vendor->saveQuietly();
|
||||||
|
});
|
||||||
|
|
||||||
|
ClientContact::whereNull('email')
|
||||||
|
->where('send_email', true)
|
||||||
|
->cursor()
|
||||||
|
->each(function ($c) {
|
||||||
|
|
||||||
|
$c->send_email = false;
|
||||||
|
$c->saveQuietly();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
ClientContact::query()
|
||||||
|
->whereNull('contact_key')
|
||||||
|
->update([
|
||||||
|
'contact_key' => Str::random(config('ninja.key_length')),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Client::doesntHave('contacts')
|
||||||
|
->cursor()
|
||||||
|
->each(function ($client){
|
||||||
|
|
||||||
|
$new_contact = ClientContactFactory::create($client->company_id, $client->user_id);
|
||||||
|
$new_contact->client_id = $client->id;
|
||||||
|
$new_contact->contact_key = Str::random(40);
|
||||||
|
$new_contact->is_primary = true;
|
||||||
|
$new_contact->save();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Vendor::doesntHave('contacts')
|
||||||
|
->cursor()
|
||||||
|
->each(function ($vendor){
|
||||||
|
|
||||||
|
$new_contact = VendorContactFactory::create($vendor->company_id, $vendor->user_id);
|
||||||
|
$new_contact->vendor_id = $vendor->id;
|
||||||
|
$new_contact->contact_key = Str::random(40);
|
||||||
|
$new_contact->is_primary = true;
|
||||||
|
$new_contact->save();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,8 +527,8 @@ class FacturaEInvoice extends AbstractService
|
|||||||
"website" => substr($company->settings->website, 0, 50),
|
"website" => substr($company->settings->website, 0, 50),
|
||||||
// "contactPeople" => substr($company->owner()->present()->name(), 0, 40),
|
// "contactPeople" => substr($company->owner()->present()->name(), 0, 40),
|
||||||
"name" => $company->owner()->present()->firstName(),
|
"name" => $company->owner()->present()->firstName(),
|
||||||
// "firstSurname" => $company->owner()->present()->firstName(),
|
"firstSurname" => $company->owner()->present()->lastName(),
|
||||||
"lastSurname" => $company->owner()->present()->lastName(),
|
// "lastSurname" => $company->owner()->present()->lastName(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->fac->setSeller($seller);
|
$this->fac->setSeller($seller);
|
||||||
|
@ -1102,7 +1102,7 @@ class PdfBuilder
|
|||||||
|
|
||||||
foreach ($variables as $variable) {
|
foreach ($variables as $variable) {
|
||||||
if ($variable == '$total_taxes') {
|
if ($variable == '$total_taxes') {
|
||||||
$taxes = $this->service->config->entity->total_tax_map;
|
$taxes = $this->service->config->entity->calc()->getTotalTaxMap();
|
||||||
|
|
||||||
if (!$taxes) {
|
if (!$taxes) {
|
||||||
continue;
|
continue;
|
||||||
@ -1115,7 +1115,7 @@ class PdfBuilder
|
|||||||
]];
|
]];
|
||||||
}
|
}
|
||||||
} elseif ($variable == '$line_taxes') {
|
} elseif ($variable == '$line_taxes') {
|
||||||
$taxes = $this->service->config->entity->tax_map;
|
$taxes = $this->service->config->entity->calc()->getTaxMap();
|
||||||
|
|
||||||
if (!$taxes) {
|
if (!$taxes) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -181,7 +181,7 @@ class PdfConfiguration
|
|||||||
$this->entity_design_id = 'invoice_design_id';
|
$this->entity_design_id = 'invoice_design_id';
|
||||||
$this->settings = $this->client->getMergedSettings();
|
$this->settings = $this->client->getMergedSettings();
|
||||||
$this->settings_object = $this->client;
|
$this->settings_object = $this->client;
|
||||||
$this->country = $this->client->country;
|
$this->country = $this->client->country ?? $this->client->company->country();
|
||||||
} elseif ($this->service->invitation instanceof QuoteInvitation) {
|
} elseif ($this->service->invitation instanceof QuoteInvitation) {
|
||||||
$this->entity = $this->service->invitation->quote;
|
$this->entity = $this->service->invitation->quote;
|
||||||
$this->entity_string = 'quote';
|
$this->entity_string = 'quote';
|
||||||
@ -191,7 +191,7 @@ class PdfConfiguration
|
|||||||
$this->entity_design_id = 'quote_design_id';
|
$this->entity_design_id = 'quote_design_id';
|
||||||
$this->settings = $this->client->getMergedSettings();
|
$this->settings = $this->client->getMergedSettings();
|
||||||
$this->settings_object = $this->client;
|
$this->settings_object = $this->client;
|
||||||
$this->country = $this->client->country;
|
$this->country = $this->client->country ?? $this->client->company->country();
|
||||||
} elseif ($this->service->invitation instanceof CreditInvitation) {
|
} elseif ($this->service->invitation instanceof CreditInvitation) {
|
||||||
$this->entity = $this->service->invitation->credit;
|
$this->entity = $this->service->invitation->credit;
|
||||||
$this->entity_string = 'credit';
|
$this->entity_string = 'credit';
|
||||||
@ -201,7 +201,7 @@ class PdfConfiguration
|
|||||||
$this->entity_design_id = 'credit_design_id';
|
$this->entity_design_id = 'credit_design_id';
|
||||||
$this->settings = $this->client->getMergedSettings();
|
$this->settings = $this->client->getMergedSettings();
|
||||||
$this->settings_object = $this->client;
|
$this->settings_object = $this->client;
|
||||||
$this->country = $this->client->country;
|
$this->country = $this->client->country ?? $this->client->company->country();
|
||||||
} elseif ($this->service->invitation instanceof RecurringInvoiceInvitation) {
|
} elseif ($this->service->invitation instanceof RecurringInvoiceInvitation) {
|
||||||
$this->entity = $this->service->invitation->recurring_invoice;
|
$this->entity = $this->service->invitation->recurring_invoice;
|
||||||
$this->entity_string = 'recurring_invoice';
|
$this->entity_string = 'recurring_invoice';
|
||||||
@ -211,7 +211,7 @@ class PdfConfiguration
|
|||||||
$this->entity_design_id = 'invoice_design_id';
|
$this->entity_design_id = 'invoice_design_id';
|
||||||
$this->settings = $this->client->getMergedSettings();
|
$this->settings = $this->client->getMergedSettings();
|
||||||
$this->settings_object = $this->client;
|
$this->settings_object = $this->client;
|
||||||
$this->country = $this->client->country;
|
$this->country = $this->client->country ?? $this->client->company->country();
|
||||||
} elseif ($this->service->invitation instanceof PurchaseOrderInvitation) {
|
} elseif ($this->service->invitation instanceof PurchaseOrderInvitation) {
|
||||||
$this->entity = $this->service->invitation->purchase_order;
|
$this->entity = $this->service->invitation->purchase_order;
|
||||||
$this->entity_string = 'purchase_order';
|
$this->entity_string = 'purchase_order';
|
||||||
@ -223,7 +223,7 @@ class PdfConfiguration
|
|||||||
$this->settings = $this->vendor->company->settings;
|
$this->settings = $this->vendor->company->settings;
|
||||||
$this->settings_object = $this->vendor;
|
$this->settings_object = $this->vendor;
|
||||||
$this->client = null;
|
$this->client = null;
|
||||||
$this->country = $this->vendor->country ?: $this->vendor->company->country();
|
$this->country = $this->vendor->country ?? $this->vendor->company->country();
|
||||||
} else {
|
} else {
|
||||||
throw new \Exception('Unable to resolve entity', 500);
|
throw new \Exception('Unable to resolve entity', 500);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ class TemplateAction implements ShouldQueue
|
|||||||
|
|
||||||
$template = Design::withTrashed()->find($this->decodePrimaryKey($this->template));
|
$template = Design::withTrashed()->find($this->decodePrimaryKey($this->template));
|
||||||
|
|
||||||
$template_service = new TemplateService($template);
|
$template_service = new \App\Services\Template\TemplateService($template);
|
||||||
|
|
||||||
match($this->entity) {
|
match($this->entity) {
|
||||||
Invoice::class => $resource->with('payments', 'client'),
|
Invoice::class => $resource->with('payments', 'client'),
|
||||||
|
@ -15,8 +15,8 @@ return [
|
|||||||
'require_https' => env('REQUIRE_HTTPS', true),
|
'require_https' => env('REQUIRE_HTTPS', true),
|
||||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||||
'app_version' => env('APP_VERSION','5.7.37'),
|
'app_version' => env('APP_VERSION','5.7.38'),
|
||||||
'app_tag' => env('APP_TAG','5.7.37'),
|
'app_tag' => env('APP_TAG','5.7.38'),
|
||||||
'minimum_client_version' => '5.0.16',
|
'minimum_client_version' => '5.0.16',
|
||||||
'terms_version' => '1.0.1',
|
'terms_version' => '1.0.1',
|
||||||
'api_secret' => env('API_SECRET', ''),
|
'api_secret' => env('API_SECRET', ''),
|
||||||
|
@ -11,26 +11,28 @@
|
|||||||
|
|
||||||
namespace Tests\Feature\Export;
|
namespace Tests\Feature\Export;
|
||||||
|
|
||||||
use App\DataMapper\CompanySettings;
|
use Tests\TestCase;
|
||||||
use App\Export\CSV\PaymentExport;
|
use App\Models\User;
|
||||||
use App\Export\CSV\ProductExport;
|
|
||||||
use App\Export\CSV\TaskExport;
|
|
||||||
use App\Export\CSV\VendorExport;
|
|
||||||
use App\Factory\CompanyUserFactory;
|
|
||||||
use App\Models\Account;
|
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\ClientContact;
|
|
||||||
use App\Models\Company;
|
|
||||||
use App\Models\CompanyToken;
|
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
|
use League\Csv\Reader;
|
||||||
|
use App\Models\Account;
|
||||||
|
use App\Models\Company;
|
||||||
use App\Models\Expense;
|
use App\Models\Expense;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\User;
|
use App\Models\CompanyToken;
|
||||||
|
use App\Models\ClientContact;
|
||||||
|
use App\Export\CSV\TaskExport;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
use App\Export\CSV\VendorExport;
|
||||||
|
use App\Export\CSV\PaymentExport;
|
||||||
|
use App\Export\CSV\ProductExport;
|
||||||
|
use App\DataMapper\CompanySettings;
|
||||||
|
use App\DataMapper\InvoiceItem;
|
||||||
|
use App\Factory\CompanyUserFactory;
|
||||||
|
use App\Factory\InvoiceItemFactory;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use League\Csv\Reader;
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
use Tests\TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
@ -52,13 +54,14 @@ class ReportCsvGenerationTest extends TestCase
|
|||||||
);
|
);
|
||||||
|
|
||||||
$this->withoutExceptionHandling();
|
$this->withoutExceptionHandling();
|
||||||
|
|
||||||
|
Invoice::withTrashed()->cursor()->each(function ($i) { $i->forceDelete();});
|
||||||
|
|
||||||
$this->buildData();
|
$this->buildData();
|
||||||
|
|
||||||
if (config('ninja.testvars.travis') !== false)
|
if (config('ninja.testvars.travis') !== false)
|
||||||
$this->markTestSkipped('Skip test no company gateways installed');
|
$this->markTestSkipped('Skip test no company gateways installed');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public $company;
|
public $company;
|
||||||
@ -290,6 +293,155 @@ class ReportCsvGenerationTest extends TestCase
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testProductJsonFiltering()
|
||||||
|
{
|
||||||
|
|
||||||
|
$query = Invoice::query();
|
||||||
|
|
||||||
|
$products = explode(",", "clown,joker,batman,bob the builder");
|
||||||
|
|
||||||
|
foreach($products as $product) {
|
||||||
|
$query->where(function ($q) use ($product) {
|
||||||
|
$q->orWhereJsonContains('line_items', ['product_key' => $product]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEquals(0, $query->count());
|
||||||
|
|
||||||
|
$item = InvoiceItemFactory::create();
|
||||||
|
$item->product_key = 'haloumi';
|
||||||
|
|
||||||
|
$line_items = [];
|
||||||
|
|
||||||
|
$line_items[] = $item;
|
||||||
|
Invoice::factory()->create(
|
||||||
|
[
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'line_items' => $line_items
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$query->where(function ($q) use ($products) {
|
||||||
|
foreach($products as $product) {
|
||||||
|
$q->orWhereJsonContains('line_items', ['product_key' => $product]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertEquals(0, $query->count());
|
||||||
|
|
||||||
|
$item = InvoiceItemFactory::create();
|
||||||
|
$item->product_key = 'batman';
|
||||||
|
|
||||||
|
$line_items = [];
|
||||||
|
|
||||||
|
$line_items[] = $item;
|
||||||
|
$item = InvoiceItemFactory::create();
|
||||||
|
$item->product_key = 'bob the builder';
|
||||||
|
|
||||||
|
$line_items[] = $item;
|
||||||
|
|
||||||
|
Invoice::factory()->create(
|
||||||
|
[
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'line_items' => $line_items
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$query = Invoice::query();
|
||||||
|
|
||||||
|
$query->where(function ($q) use($products){
|
||||||
|
foreach($products as $product) {
|
||||||
|
$q->orWhereJsonContains('line_items', ['product_key' => $product]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertEquals(1, $query->count());
|
||||||
|
|
||||||
|
$query = Invoice::query();
|
||||||
|
|
||||||
|
$query->where(function ($q){
|
||||||
|
$q->orWhereJsonContains('line_items', ['product_key' => 'bob the builder']);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertEquals(1, $query->count());
|
||||||
|
|
||||||
|
Invoice::withTrashed()->cursor()->each(function ($i) { $i->forceDelete();});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testProductKeyFilterQueries()
|
||||||
|
{
|
||||||
|
|
||||||
|
$item = InvoiceItemFactory::create();
|
||||||
|
$item->product_key = 'haloumi';
|
||||||
|
|
||||||
|
$line_items = [];
|
||||||
|
|
||||||
|
$line_items[] = $item;
|
||||||
|
$q = Invoice::whereJsonContains('line_items', ['product_key' => 'haloumi']);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $q->count());
|
||||||
|
|
||||||
|
Invoice::factory()->create(
|
||||||
|
[
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'line_items' => $line_items
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(1, $q->count());
|
||||||
|
|
||||||
|
$q->forceDelete();
|
||||||
|
|
||||||
|
Invoice::factory()->create(
|
||||||
|
[
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'line_items' => $line_items
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$item = InvoiceItemFactory::create();
|
||||||
|
$item->product_key = 'bob the builder';
|
||||||
|
|
||||||
|
$line_items = [];
|
||||||
|
|
||||||
|
$line_items[] = $item;
|
||||||
|
|
||||||
|
$q = Invoice::whereJsonContains('line_items', ['product_key' => 'bob the builder']);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $q->count());
|
||||||
|
|
||||||
|
Invoice::factory()->create(
|
||||||
|
[
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'line_items' => $line_items
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(1, $q->count());
|
||||||
|
|
||||||
|
$q = Invoice::whereJsonContains('line_items', ['product_key' => 'Bob the builder']);
|
||||||
|
$this->assertEquals(0, $q->count());
|
||||||
|
|
||||||
|
$q = Invoice::whereJsonContains('line_items', ['product_key' => 'bob']);
|
||||||
|
$this->assertEquals(0, $q->count());
|
||||||
|
|
||||||
|
$q->forceDelete();
|
||||||
|
|
||||||
|
Invoice::withTrashed()->cursor()->each(function ($i){ $i->forceDelete();});
|
||||||
|
}
|
||||||
|
|
||||||
public function testVendorCsvGeneration()
|
public function testVendorCsvGeneration()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -1260,14 +1412,12 @@ class ReportCsvGenerationTest extends TestCase
|
|||||||
$this->assertEquals('GST', $this->getFirstValueByColumn($csv, 'Item Tax Name 1'));
|
$this->assertEquals('GST', $this->getFirstValueByColumn($csv, 'Item Tax Name 1'));
|
||||||
$this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Item Tax Rate 1'));
|
$this->assertEquals('10', $this->getFirstValueByColumn($csv, 'Item Tax Rate 1'));
|
||||||
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'date_range' => 'all',
|
'date_range' => 'all',
|
||||||
'report_keys' => $this->all_client_report_keys,
|
'report_keys' => $this->all_client_report_keys,
|
||||||
'send_email' => false,
|
'send_email' => false,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
'X-API-SECRET' => config('ninja.api_secret'),
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
'X-API-TOKEN' => $this->token,
|
'X-API-TOKEN' => $this->token,
|
||||||
@ -1286,6 +1436,17 @@ class ReportCsvGenerationTest extends TestCase
|
|||||||
])->post('/api/v1/reports/invoice_items', $data)->assertStatus(200);
|
])->post('/api/v1/reports/invoice_items', $data)->assertStatus(200);
|
||||||
|
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'date_range' => 'all',
|
||||||
|
'report_keys' => $this->all_payment_report_keys,
|
||||||
|
'send_email' => false,
|
||||||
|
'product_key' => 'haloumi,cheese',
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->postJson('/api/v1/reports/invoice_items', $data)->assertStatus(200);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user