mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Updates
This commit is contained in:
commit
1adbd3907e
@ -259,10 +259,17 @@ class ExpenseExport extends BaseExport
|
||||
{
|
||||
$precision = $expense->currency->precision ?? 2;
|
||||
|
||||
$entity['expense.net_amount'] = round($expense->amount, $precision);
|
||||
|
||||
if($expense->calculate_tax_by_amount) {
|
||||
|
||||
$total_tax_amount = round($expense->tax_amount1 + $expense->tax_amount2 + $expense->tax_amount3, $precision);
|
||||
|
||||
if($expense->uses_inclusive_taxes) {
|
||||
$entity['expense.net_amount'] = round($expense->amount, $precision) - $total_tax_amount;
|
||||
}
|
||||
else {
|
||||
$entity['expense.net_amount'] = round($expense->amount, $precision);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if($expense->uses_inclusive_taxes) {
|
||||
|
@ -152,22 +152,22 @@ class InvoiceFilters extends QueryFilters
|
||||
{
|
||||
|
||||
return $this->builder->where(function ($query) {
|
||||
$query->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT])
|
||||
->where('is_deleted', 0)
|
||||
->where('balance', '>', 0)
|
||||
->where(function ($query) {
|
||||
$query->whereIn('invoices.status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT])
|
||||
->where('invoices.is_deleted', 0)
|
||||
->where('invoices.balance', '>', 0)
|
||||
->orWhere(function ($query) {
|
||||
|
||||
$query->whereNull('due_date')
|
||||
$query->whereNull('invoices.due_date')
|
||||
->orWhere(function ($q) {
|
||||
$q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0);
|
||||
$q->where('invoices.due_date', '>=', now()->startOfDay()->subSecond())->where('invoices.partial', 0);
|
||||
})
|
||||
->orWhere(function ($q) {
|
||||
$q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0);
|
||||
$q->where('invoices.partial_due_date', '>=', now()->startOfDay()->subSecond())->where('invoices.partial', '>', 0);
|
||||
});
|
||||
|
||||
})
|
||||
->orderByRaw('ISNULL(due_date), due_date ' . 'desc')
|
||||
->orderByRaw('ISNULL(partial_due_date), partial_due_date ' . 'desc');
|
||||
->orderByRaw('ISNULL(invoices.due_date), invoices.due_date ' . 'desc')
|
||||
->orderByRaw('ISNULL(invoices.partial_due_date), invoices.partial_due_date ' . 'desc');
|
||||
});
|
||||
|
||||
}
|
||||
@ -337,10 +337,10 @@ class InvoiceFilters extends QueryFilters
|
||||
// return $this->builder->orderByRaw('CAST(number AS UNSIGNED), number ' . $dir);
|
||||
// return $this->builder->orderByRaw("number REGEXP '^[A-Za-z]+$',CAST(number as SIGNED INTEGER),CAST(REPLACE(number,'-','')AS SIGNED INTEGER) ,number");
|
||||
// return $this->builder->orderByRaw('ABS(number) ' . $dir);
|
||||
return $this->builder->orderByRaw("REGEXP_REPLACE(number,'[^0-9]+','')+0 " . $dir);
|
||||
return $this->builder->orderByRaw("REGEXP_REPLACE(invoices.number,'[^0-9]+','')+0 " . $dir);
|
||||
}
|
||||
|
||||
return $this->builder->orderBy($sort_col[0], $dir);
|
||||
return $this->builder->orderBy("{$this->builder->getQuery()->from}.".$sort_col[0], $dir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -273,23 +273,11 @@ abstract class QueryFilters
|
||||
|
||||
public function filter_deleted_clients($value)
|
||||
{
|
||||
// if ($value == 'true') {
|
||||
// return $this->builder->whereHas('client', function (Builder $query) {
|
||||
// $query->where('is_deleted', 0);
|
||||
// });
|
||||
// }
|
||||
|
||||
if($value == 'true')
|
||||
{
|
||||
return $this->builder->leftJoin('clients', function($join) {
|
||||
|
||||
$join->on("{$this->builder->getQuery()->from}.client_id", '=', 'clients.id')
|
||||
->where('clients.is_deleted', 0)
|
||||
->whereNull('clients.deleted_at');
|
||||
|
||||
if ($value == 'true') {
|
||||
return $this->builder->whereHas('client', function (Builder $query) {
|
||||
$query->where('is_deleted', 0);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
@ -115,13 +115,8 @@ class AccountController extends BaseController
|
||||
|
||||
public function update(UpdateAccountRequest $request, Account $account)
|
||||
{
|
||||
$fi = new \FilesystemIterator(public_path('react'), \FilesystemIterator::SKIP_DOTS);
|
||||
|
||||
if (iterator_count($fi) < 30) {
|
||||
return response()->json(['message' => 'React App Not Installed, Please install the React app before attempting to switch.'], 400);
|
||||
}
|
||||
|
||||
$account->fill($request->all());
|
||||
$account->set_react_as_default_ap = $request->input('set_react_as_default_ap');
|
||||
$account->save();
|
||||
|
||||
$this->entity_type = Account::class;
|
||||
|
@ -937,7 +937,9 @@ class BaseController extends Controller
|
||||
} elseif (in_array($this->entity_type, [Design::class, GroupSetting::class, PaymentTerm::class, TaskStatus::class])) {
|
||||
// nlog($this->entity_type);
|
||||
} else {
|
||||
$query->where('user_id', '=', $user->id)->orWhere('assigned_user_id', $user->id);
|
||||
$query->where(function ($q) use ($user){ //grouping these together improves query performance significantly)
|
||||
$q->where('user_id', '=', $user->id)->orWhere('assigned_user_id', $user->id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,8 @@ class SetDomainNameDb
|
||||
return response()->json($error, 403);
|
||||
} else {
|
||||
MultiDB::setDb('db-ninja-01');
|
||||
nlog('I could not set the DB - defaulting to DB1');
|
||||
nlog('SetDomainNameDb:: I could not set the DB - defaulting to DB1');
|
||||
$request->session()->invalidate();
|
||||
//abort(400, 'Domain not found');
|
||||
}
|
||||
}
|
||||
@ -73,7 +74,8 @@ class SetDomainNameDb
|
||||
return response()->json($error, 403);
|
||||
} else {
|
||||
MultiDB::setDb('db-ninja-01');
|
||||
nlog('I could not set the DB - defaulting to DB1');
|
||||
nlog('SetDomainNameDb:: I could not set the DB - defaulting to DB1');
|
||||
$request->session()->invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class InvoiceTransformer extends BaseTransformer
|
||||
'due_date' => isset($invoice_data['Due Date']) ? $this->parseDate($invoice_data['Due Date']) : null,
|
||||
'po_number' => $this->getString($invoice_data, 'PurchaseOrder'),
|
||||
'public_notes' => $this->getString($invoice_data, 'Notes'),
|
||||
'currency_id' => $this->getCurrencyByCode($invoice_data, 'Currency'),
|
||||
// 'currency_id' => $this->getCurrencyByCode($invoice_data, 'Currency'),
|
||||
'amount' => $this->getFloat($invoice_data, 'Total'),
|
||||
'balance' => $this->getFloat($invoice_data, 'Balance'),
|
||||
'status_id' => $invoiceStatusMap[$status =
|
||||
|
@ -86,6 +86,9 @@ class UpdateCalculatedFields
|
||||
|
||||
foreach(json_decode($task->time_log) as $log) {
|
||||
|
||||
if(!is_array($log))
|
||||
continue;
|
||||
|
||||
$start_time = $log[0];
|
||||
$end_time = $log[1] == 0 ? time() : $log[1];
|
||||
|
||||
|
@ -47,7 +47,7 @@ class TaskAssigned implements ShouldQueue
|
||||
|
||||
$company_user = $this->task->assignedCompanyUser();
|
||||
|
||||
if($this->findEntityAssignedNotification($company_user, 'task'))
|
||||
if($company_user && $this->findEntityAssignedNotification($company_user, 'task'))
|
||||
{
|
||||
$mo = new EmailObject();
|
||||
$mo->subject = ctrans('texts.task_assigned_subject', ['task' => $this->task->number, 'date' => now()->setTimeZone($this->task->company->timezone()->name)->format($this->task->company->date_format()) ]);
|
||||
|
@ -59,28 +59,19 @@ class ReminderJob implements ShouldQueue
|
||||
nrlog("Sending invoice reminders on ".now()->format('Y-m-d h:i:s'));
|
||||
|
||||
Invoice::query()
|
||||
->where('invoices.is_deleted', 0)
|
||||
->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->whereNull('invoices.deleted_at')
|
||||
->where('invoices.balance', '>', 0)
|
||||
->where('invoices.next_send_date', '<=', now()->toDateTimeString())
|
||||
// ->whereHas('client', function ($query) {
|
||||
// $query->where('is_deleted', 0)
|
||||
// ->where('deleted_at', null);
|
||||
// })
|
||||
// ->whereHas('company', function ($query) {
|
||||
// $query->where('is_disabled', 0);
|
||||
// })
|
||||
->leftJoin('clients', function ($join) {
|
||||
$join->on('invoices.client_id', '=', 'clients.id')
|
||||
->where('clients.is_deleted', 0)
|
||||
->whereNull('clients.deleted_at');
|
||||
})
|
||||
->leftJoin('companies', function ($join) {
|
||||
$join->on('invoices.company_id', '=', 'companies.id')
|
||||
->where('companies.is_disabled', 0);
|
||||
})
|
||||
->with('invitations')->chunk(50, function ($invoices) {
|
||||
->where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->whereNull('deleted_at')
|
||||
->where('balance', '>', 0)
|
||||
->where('next_send_date', '<=', now()->toDateTimeString())
|
||||
->whereHas('client', function ($query) {
|
||||
$query->where('is_deleted', 0)
|
||||
->where('deleted_at', null);
|
||||
})
|
||||
->whereHas('company', function ($query) {
|
||||
$query->where('is_disabled', 0);
|
||||
})
|
||||
->with('invitations')->chunk(200, function ($invoices) {
|
||||
foreach ($invoices as $invoice) {
|
||||
$this->sendReminderForInvoice($invoice);
|
||||
}
|
||||
@ -96,28 +87,19 @@ class ReminderJob implements ShouldQueue
|
||||
nrlog("Sending invoice reminders on db {$db} ".now()->format('Y-m-d h:i:s'));
|
||||
|
||||
Invoice::query()
|
||||
->where('invoices.is_deleted', 0)
|
||||
->whereIn('invoices.status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->whereNull('invoices.deleted_at')
|
||||
->where('invoices.balance', '>', 0)
|
||||
->where('invoices.next_send_date', '<=', now()->toDateTimeString())
|
||||
// ->whereHas('client', function ($query) {
|
||||
// $query->where('is_deleted', 0)
|
||||
// ->where('deleted_at', null);
|
||||
// })
|
||||
// ->whereHas('company', function ($query) {
|
||||
// $query->where('is_disabled', 0);
|
||||
// })
|
||||
->leftJoin('clients', function ($join) {
|
||||
$join->on('invoices.client_id', '=', 'clients.id')
|
||||
->where('clients.is_deleted', 0)
|
||||
->whereNull('clients.deleted_at');
|
||||
})
|
||||
->leftJoin('companies', function ($join) {
|
||||
$join->on('invoices.company_id', '=', 'companies.id')
|
||||
->where('companies.is_disabled', 0);
|
||||
})
|
||||
->with('invitations')->chunk(50, function ($invoices) {
|
||||
->where('is_deleted', 0)
|
||||
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
|
||||
->whereNull('deleted_at')
|
||||
->where('balance', '>', 0)
|
||||
->where('next_send_date', '<=', now()->toDateTimeString())
|
||||
->whereHas('client', function ($query) {
|
||||
$query->where('is_deleted', 0)
|
||||
->where('deleted_at', null);
|
||||
})
|
||||
->whereHas('company', function ($query) {
|
||||
$query->where('is_disabled', 0);
|
||||
})
|
||||
->with('invitations')->chunk(200, function ($invoices) {
|
||||
|
||||
foreach ($invoices as $invoice) {
|
||||
$this->sendReminderForInvoice($invoice);
|
||||
|
@ -134,18 +134,6 @@ class BaseModel extends Model
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function scopeWithoutDeletedClients($query)
|
||||
{
|
||||
|
||||
$query->leftJoin('clients', function ($join) use ($query){
|
||||
$join->on("{$query->getQuery()->from}.client_id", '=', 'clients.id')
|
||||
->where('clients.is_deleted', 0)
|
||||
->whereNull('clients.deleted_at');
|
||||
});
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated version
|
||||
*/
|
||||
|
@ -107,7 +107,6 @@ use Laracasts\Presenter\PresentableTrait;
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Document> $documents
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Backup> $history
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\QuoteInvitation> $invitations
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel company()
|
||||
* @mixin \Eloquent
|
||||
* @mixin \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
|
@ -261,7 +261,7 @@ class TaskRepository extends BaseRepository
|
||||
|
||||
public function roundTimeLog(int $start_time, int $end_time): int
|
||||
{
|
||||
if($this->task_round_to_nearest == 1 || $end_time == 0) {
|
||||
if(in_array($this->task_round_to_nearest, [0,1]) || $end_time == 0) {
|
||||
return $end_time;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ class ZugferdEDocument extends AbstractService {
|
||||
*/
|
||||
public function run(): Expense
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
$this->document = ZugferdDocumentReader::readAndGuessFromContent($this->tempdocument);
|
||||
$this->document->getDocumentInformation($documentno, $documenttypecode, $documentdate, $invoiceCurrency, $taxCurrency, $documentname, $documentlanguage, $effectiveSpecifiedPeriod);
|
||||
@ -102,13 +103,13 @@ class ZugferdEDocument extends AbstractService {
|
||||
if ($taxid != null) {
|
||||
$vendor->vat_number = $taxid;
|
||||
}
|
||||
$vendor->currency_id = Currency::whereCode($invoiceCurrency)->first()->id;
|
||||
$vendor->currency_id = Currency::query()->where('code', $invoiceCurrency)->first()->id;
|
||||
$vendor->phone = $contact_phone;
|
||||
$vendor->address1 = $address_1;
|
||||
$vendor->address2 = $address_2;
|
||||
$vendor->city = $city;
|
||||
$vendor->postal_code = $postcode;
|
||||
$vendor->country_id = Country::where('iso_3166_2', $country)->first()->id;
|
||||
$vendor->country_id = Country::query()->where('iso_3166_2', $country)->first()->id;
|
||||
|
||||
$vendor->save();
|
||||
$expense->vendor_id = $vendor->id;
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace App\Utils;
|
||||
|
||||
use Illuminate\Http\File;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
class TempFile
|
||||
{
|
||||
public static function path($url): string
|
||||
@ -34,4 +36,61 @@ class TempFile
|
||||
|
||||
return $file_path;
|
||||
}
|
||||
|
||||
public static function UploadedFileFromRaw(string $fileData, string|null $fileName = null, string|null $mimeType = null): UploadedFile
|
||||
{
|
||||
// Create temp file and get its absolute path
|
||||
$tempFile = tmpfile();
|
||||
$tempFilePath = stream_get_meta_data($tempFile)['uri'];
|
||||
|
||||
// Save file data in file
|
||||
file_put_contents($tempFilePath, $fileData);
|
||||
|
||||
$tempFileObject = new File($tempFilePath);
|
||||
$file = new UploadedFile(
|
||||
$tempFileObject->getPathname(),
|
||||
$fileName ?: $tempFileObject->getFilename(),
|
||||
$mimeType ?: $tempFileObject->getMimeType(),
|
||||
0,
|
||||
true // Mark it as test, since the file isn't from real HTTP POST.
|
||||
);
|
||||
|
||||
// Close this file after response is sent.
|
||||
// Closing the file will cause to remove it from temp director!
|
||||
app()->terminating(function () use ($tempFile) {
|
||||
fclose($tempFile);
|
||||
});
|
||||
|
||||
// return UploadedFile object
|
||||
return $file;
|
||||
}
|
||||
|
||||
/* create a tmp file from a raw string: https://gist.github.com/waska14/8b3bcebfad1f86f7fcd3b82927576e38*/
|
||||
public static function UploadedFileFromUrl(string $url, string|null $fileName = null, string|null $mimeType = null): UploadedFile
|
||||
{
|
||||
// Create temp file and get its absolute path
|
||||
$tempFile = tmpfile();
|
||||
$tempFilePath = stream_get_meta_data($tempFile)['uri'];
|
||||
|
||||
// Save file data in file
|
||||
file_put_contents($tempFilePath, file_get_contents($url));
|
||||
|
||||
$tempFileObject = new File($tempFilePath);
|
||||
$file = new UploadedFile(
|
||||
$tempFileObject->getPathname(),
|
||||
$fileName ?: $tempFileObject->getFilename(),
|
||||
$mimeType ?: $tempFileObject->getMimeType(),
|
||||
0,
|
||||
true // Mark it as test, since the file isn't from real HTTP POST.
|
||||
);
|
||||
|
||||
// Close this file after response is sent.
|
||||
// Closing the file will cause to remove it from temp director!
|
||||
app()->terminating(function () use ($tempFile) {
|
||||
fclose($tempFile);
|
||||
});
|
||||
|
||||
// return UploadedFile object
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
6
public/flutter_service_worker.js
vendored
6
public/flutter_service_worker.js
vendored
@ -16,9 +16,9 @@ const RESOURCES = {"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
|
||||
"canvaskit/canvaskit.js": "c86fbd9e7b17accae76e5ad116583dc4",
|
||||
"canvaskit/canvaskit.wasm": "3d2a2d663e8c5111ac61a46367f751ac",
|
||||
"canvaskit/skwasm.wasm": "e42815763c5d05bba43f9d0337fa7d84",
|
||||
"version.json": "1592dbbd49cf08963e29ab3a85640d96",
|
||||
"version.json": "f789e711f61e122f41a7eda7522a1fba",
|
||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
|
||||
"main.dart.js": "0512d8a34cb5c2d5d565a27c3666d9f9",
|
||||
"main.dart.js": "bb6cfbe200a5c6a0d8857eaffd21b759",
|
||||
"assets/NOTICES": "412b336cf9e33e70058d612857effae1",
|
||||
"assets/AssetManifest.bin": "bf3be26e7055ad9a32f66b3a56138224",
|
||||
"assets/assets/images/logo_light.png": "e5f46d5a78e226e7a9553d4ca6f69219",
|
||||
@ -307,7 +307,7 @@ const RESOURCES = {"icons/Icon-512.png": "0f9aff01367f0a0c69773d25ca16ef35",
|
||||
"assets/FontManifest.json": "087fb858dc3cbfbf6baf6a30004922f1",
|
||||
"assets/fonts/MaterialIcons-Regular.otf": "a57618538ab8b4c4081d4491870ac333",
|
||||
"assets/AssetManifest.json": "759f9ef9973f7e26c2a51450b55bb9fa",
|
||||
"/": "a53ace1edfc2ce12fc50cbbade610be3",
|
||||
"/": "e847f898173e2b358dcf6efc58032f91",
|
||||
"favicon.ico": "51636d3a390451561744c42188ccd628",
|
||||
"manifest.json": "ef43d90e57aa7682d7e2cfba2f484a40"};
|
||||
// The application shell files that are downloaded before a service worker can
|
||||
|
271459
public/main.dart.js
vendored
271459
public/main.dart.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
269785
public/main.foss.dart.js
vendored
269785
public/main.foss.dart.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
17671
public/main.profile.dart.js
vendored
17671
public/main.profile.dart.js
vendored
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
{"app_name":"invoiceninja_flutter","version":"5.0.160","build_number":"160","package_name":"invoiceninja_flutter"}
|
||||
{"app_name":"invoiceninja_flutter","version":"5.0.161","build_number":"161","package_name":"invoiceninja_flutter"}
|
@ -11,7 +11,9 @@
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
@ -44,6 +46,122 @@ class ClientModelTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
public function testNewWithoutAndDeletedClientFilters()
|
||||
{
|
||||
|
||||
$this->invoice->amount = 10;
|
||||
$this->invoice->balance = 10;
|
||||
$this->invoice->status_id=2;
|
||||
$this->invoice->date = now()->subDays(2);
|
||||
$this->invoice->due_date = now()->addDays(2);
|
||||
$this->invoice->save();
|
||||
|
||||
$cd = Client::factory()->create([
|
||||
'company_id' => $this->company->id,
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
|
||||
$cd2 = Client::factory()->create([
|
||||
'company_id' => $this->company->id,
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
$invoice_count = Invoice::where('company_id', $this->company->id)->count();
|
||||
|
||||
$this->assertGreaterThan(0, $invoice_count);
|
||||
|
||||
$i = Invoice::factory()->create([
|
||||
'client_id' => $cd->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'status_id' => 2,
|
||||
'amount' => 10,
|
||||
'balance' => 10,
|
||||
'date' => now()->subDays(2)->format('Y-m-d'),
|
||||
'due_date' => now()->addDays(5)->format('Y-m-d'),
|
||||
]);
|
||||
|
||||
|
||||
$i2 = Invoice::factory()->create([
|
||||
'client_id' => $cd2->id,
|
||||
'user_id' => $this->user->id,
|
||||
'company_id' => $this->company->id,
|
||||
'status_id' => 2,
|
||||
'amount' => 10,
|
||||
'balance' => 10,
|
||||
'date' => now()->subDays(2)->format('Y-m-d'),
|
||||
'due_date' => now()->addDays(5)->format('Y-m-d'),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/invoices?status=active');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals($invoice_count+2, count($arr['data']));
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/invoices?upcoming=true&status=active&include=client');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals($invoice_count + 2, count($arr['data']));
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/invoices?upcoming=true&status=active&without_deleted_clients=true');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals($invoice_count + 2, count($arr['data']));
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/invoices?upcoming=true&status=active&filter_deleted_clients=true');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals($invoice_count + 2, count($arr['data']));
|
||||
|
||||
$cd2->is_deleted = true;
|
||||
$cd2->save();
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/invoices?upcoming=true&status=active&without_deleted_clients=true');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals($invoice_count + 1, count($arr['data']));
|
||||
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->get('/api/v1/invoices?upcoming=true&status=active&filter_deleted_clients=true');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$arr = $response->json();
|
||||
|
||||
$this->assertEquals($invoice_count + 1, count($arr['data']));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function testPaymentMethodsWithCreditsEnforced()
|
||||
{
|
||||
|
||||
@ -51,6 +169,6 @@ class ClientModelTest extends TestCase
|
||||
|
||||
$this->assertGreaterThan(0, CompanyGateway::count());
|
||||
|
||||
$this->assertEquals(1, count($payment_methods));
|
||||
$this->assertEquals(2, count($payment_methods));
|
||||
}
|
||||
}
|
||||
|
@ -189,6 +189,22 @@ class TaskApiTest extends TestCase
|
||||
|
||||
}
|
||||
|
||||
public function testTaskDivisionByZero()
|
||||
{
|
||||
$data = [
|
||||
"rate" => 0,
|
||||
"time_log" => '[[1719350900,1719352700,"",true]]',
|
||||
];
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->postJson("/api/v1/tasks", $data);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
}
|
||||
|
||||
public function testRequestRuleParsing()
|
||||
{
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user