mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-04 09:14:36 -04:00
commit
41fea85fa5
@ -1 +1 @@
|
|||||||
5.6.0
|
5.6.1
|
@ -435,11 +435,38 @@ class CheckData extends Command
|
|||||||
|
|
||||||
private function checkEntityInvitations()
|
private function checkEntityInvitations()
|
||||||
{
|
{
|
||||||
|
|
||||||
RecurringInvoiceInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
RecurringInvoiceInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||||
InvoiceInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
InvoiceInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||||
QuoteInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
QuoteInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||||
CreditInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
CreditInvitation::where('deleted_at', "0000-00-00 00:00:00.000000")->withTrashed()->update(['deleted_at' => null]);
|
||||||
|
|
||||||
|
InvoiceInvitation::where('sent_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii){
|
||||||
|
$ii->sent_date = null;
|
||||||
|
$ii->saveQuietly();
|
||||||
|
});
|
||||||
|
InvoiceInvitation::where('viewed_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||||
|
$ii->viewed_date = null;
|
||||||
|
$ii->saveQuietly();
|
||||||
|
});
|
||||||
|
|
||||||
|
QuoteInvitation::where('sent_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||||
|
$ii->sent_date = null;
|
||||||
|
$ii->saveQuietly();
|
||||||
|
});
|
||||||
|
QuoteInvitation::where('viewed_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||||
|
$ii->viewed_date = null;
|
||||||
|
$ii->saveQuietly();
|
||||||
|
});
|
||||||
|
|
||||||
|
CreditInvitation::where('sent_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||||
|
$ii->sent_date = null;
|
||||||
|
$ii->saveQuietly();
|
||||||
|
});
|
||||||
|
CreditInvitation::where('viewed_date', '0000-00-00 00:00:00')->cursor()->each(function ($ii) {
|
||||||
|
$ii->viewed_date = null;
|
||||||
|
$ii->saveQuietly();
|
||||||
|
});
|
||||||
|
|
||||||
collect([Invoice::class, Quote::class, Credit::class, PurchaseOrder::class])->each(function ($entity) {
|
collect([Invoice::class, Quote::class, Credit::class, PurchaseOrder::class])->each(function ($entity) {
|
||||||
if ($entity::doesntHave('invitations')->count() > 0) {
|
if ($entity::doesntHave('invitations')->count() > 0) {
|
||||||
|
@ -102,8 +102,13 @@ class PaymentFilters extends QueryFilters
|
|||||||
if (count($payment_filters) >0) {
|
if (count($payment_filters) >0) {
|
||||||
$query->whereIn('status_id', $payment_filters);
|
$query->whereIn('status_id', $payment_filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(in_array('partially_unapplied', $status_parameters)) {
|
||||||
|
$query->where('amount', '>', 'applied')->where('refunded', 0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return $this->builder;
|
return $this->builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace App\Jobs\Cron;
|
namespace App\Jobs\Cron;
|
||||||
|
|
||||||
|
use App\Models\Payment;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
@ -65,7 +66,6 @@ class UpdateCalculatedFields
|
|||||||
$project->save();
|
$project->save();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -621,7 +621,7 @@ class Account extends BaseModel
|
|||||||
|
|
||||||
public function getTrialDays()
|
public function getTrialDays()
|
||||||
{
|
{
|
||||||
if ($this->payment_id) {
|
if ($this->payment_id || $this->is_migrated) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ use Illuminate\Support\Str;
|
|||||||
* @property \App\Models\Company $company
|
* @property \App\Models\Company $company
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|Illuminate\Database\Eloquent\Relations\BelongsTo|\Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo|\App\Models\Company company()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel|Illuminate\Database\Eloquent\Relations\BelongsTo|\Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo|\App\Models\Company company()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel exclude($columns)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel with()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel newQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel query()
|
* @method static \Illuminate\Database\Eloquent\Builder|BaseModel query()
|
||||||
|
@ -86,6 +86,10 @@ class RouteServiceProvider extends ServiceProvider
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RateLimiter::for('honeypot', function (Request $request) {
|
||||||
|
return Limit::perMinute(2)->by($request->ip());
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +80,7 @@ class ClientService
|
|||||||
$amount = Payment::where('client_id', $this->client->id)
|
$amount = Payment::where('client_id', $this->client->id)
|
||||||
->where('is_deleted', 0)
|
->where('is_deleted', 0)
|
||||||
->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
->whereIn('status_id', [Payment::STATUS_COMPLETED, Payment::STATUS_PENDING, Payment::STATUS_PARTIALLY_REFUNDED, Payment::STATUS_REFUNDED])
|
||||||
->sum(DB::Raw('amount - refunded - applied'));
|
->sum(DB::Raw('amount - applied'));
|
||||||
|
|
||||||
DB::connection(config('database.default'))->transaction(function () use ($amount) {
|
DB::connection(config('database.default'))->transaction(function () use ($amount) {
|
||||||
$this->client = Client::withTrashed()->where('id', $this->client->id)->lockForUpdate()->first();
|
$this->client = Client::withTrashed()->where('id', $this->client->id)->lockForUpdate()->first();
|
||||||
|
@ -371,28 +371,28 @@ class Statement
|
|||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
case '60':
|
case '60':
|
||||||
$ranges[0] = now()->startOfDay()->subDays(30);
|
$ranges[0] = now()->startOfDay()->subDays(31);
|
||||||
$ranges[1] = now()->startOfDay()->subDays(60);
|
$ranges[1] = now()->startOfDay()->subDays(60);
|
||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
case '90':
|
case '90':
|
||||||
$ranges[0] = now()->startOfDay()->subDays(60);
|
$ranges[0] = now()->startOfDay()->subDays(61);
|
||||||
$ranges[1] = now()->startOfDay()->subDays(90);
|
$ranges[1] = now()->startOfDay()->subDays(90);
|
||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
case '120':
|
case '120':
|
||||||
$ranges[0] = now()->startOfDay()->subDays(90);
|
$ranges[0] = now()->startOfDay()->subDays(91);
|
||||||
$ranges[1] = now()->startOfDay()->subDays(120);
|
$ranges[1] = now()->startOfDay()->subDays(120);
|
||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
case '120+':
|
case '120+':
|
||||||
$ranges[0] = now()->startOfDay()->subDays(120);
|
$ranges[0] = now()->startOfDay()->subDays(121);
|
||||||
$ranges[1] = now()->startOfDay()->subYears(20);
|
$ranges[1] = now()->startOfDay()->subYears(20);
|
||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
default:
|
default:
|
||||||
$ranges[0] = now()->startOfDay()->subDays(0);
|
$ranges[0] = now()->startOfDay();
|
||||||
$ranges[1] = now()->subDays(30);
|
$ranges[1] = now()->startOfDay()->subDays(30);
|
||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
}
|
}
|
||||||
|
@ -130,13 +130,6 @@ class CreditService
|
|||||||
->credits()
|
->credits()
|
||||||
->attach($this->credit->id, ['amount' => $adjustment]);
|
->attach($this->credit->id, ['amount' => $adjustment]);
|
||||||
|
|
||||||
//reduce client paid_to_date by $this->credit->balance amount
|
|
||||||
// $this->credit
|
|
||||||
// ->client
|
|
||||||
// ->service()
|
|
||||||
// ->updatePaidToDate($adjustment)
|
|
||||||
// ->save();
|
|
||||||
|
|
||||||
$client = $this->credit->client->fresh();
|
$client = $this->credit->client->fresh();
|
||||||
$client->service()
|
$client->service()
|
||||||
->updatePaidToDate($adjustment)
|
->updatePaidToDate($adjustment)
|
||||||
|
@ -123,7 +123,7 @@ class ARSummaryReport extends BaseExport
|
|||||||
->where('balance', '>', 0)
|
->where('balance', '>', 0)
|
||||||
->where('is_deleted', 0)
|
->where('is_deleted', 0)
|
||||||
->where(function ($query){
|
->where(function ($query){
|
||||||
$query->where('due_date', '<', now()->startOfDay())
|
$query->where('due_date', '>', now()->startOfDay())
|
||||||
->orWhereNull('due_date');
|
->orWhereNull('due_date');
|
||||||
})
|
})
|
||||||
->sum('balance');
|
->sum('balance');
|
||||||
@ -173,22 +173,22 @@ class ARSummaryReport extends BaseExport
|
|||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
case '60':
|
case '60':
|
||||||
$ranges[0] = now()->startOfDay()->subDays(30);
|
$ranges[0] = now()->startOfDay()->subDays(31);
|
||||||
$ranges[1] = now()->startOfDay()->subDays(60);
|
$ranges[1] = now()->startOfDay()->subDays(60);
|
||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
case '90':
|
case '90':
|
||||||
$ranges[0] = now()->startOfDay()->subDays(60);
|
$ranges[0] = now()->startOfDay()->subDays(61);
|
||||||
$ranges[1] = now()->startOfDay()->subDays(90);
|
$ranges[1] = now()->startOfDay()->subDays(90);
|
||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
case '120':
|
case '120':
|
||||||
$ranges[0] = now()->startOfDay()->subDays(90);
|
$ranges[0] = now()->startOfDay()->subDays(91);
|
||||||
$ranges[1] = now()->startOfDay()->subDays(120);
|
$ranges[1] = now()->startOfDay()->subDays(120);
|
||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
case '120+':
|
case '120+':
|
||||||
$ranges[0] = now()->startOfDay()->subDays(120);
|
$ranges[0] = now()->startOfDay()->subDays(121);
|
||||||
$ranges[1] = now()->startOfDay()->subYears(20);
|
$ranges[1] = now()->startOfDay()->subYears(20);
|
||||||
|
|
||||||
return $ranges;
|
return $ranges;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace App\Transformers;
|
namespace App\Transformers;
|
||||||
|
|
||||||
use App\Models\Document;
|
use App\Models\Document;
|
||||||
|
use App\Models\Project;
|
||||||
use App\Models\Task;
|
use App\Models\Task;
|
||||||
use App\Models\TaskStatus;
|
use App\Models\TaskStatus;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
@ -33,7 +34,8 @@ class TaskTransformer extends EntityTransformer
|
|||||||
*/
|
*/
|
||||||
protected $availableIncludes = [
|
protected $availableIncludes = [
|
||||||
'client',
|
'client',
|
||||||
'status'
|
'status',
|
||||||
|
'project',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function includeDocuments(Task $task)
|
public function includeDocuments(Task $task)
|
||||||
@ -65,6 +67,16 @@ class TaskTransformer extends EntityTransformer
|
|||||||
return $this->includeItem($task->status, $transformer, TaskStatus::class);
|
return $this->includeItem($task->status, $transformer, TaskStatus::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function includeProject(Task $task): ?Item
|
||||||
|
{
|
||||||
|
$transformer = new ProjectTransformer($this->serializer);
|
||||||
|
|
||||||
|
if (!$task->project) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->includeItem($task->project, $transformer, Project::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function transform(Task $task)
|
public function transform(Task $task)
|
||||||
{
|
{
|
||||||
|
@ -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' => '5.6.0',
|
'app_version' => '5.6.1',
|
||||||
'app_tag' => '5.6.0',
|
'app_tag' => '5.6.1',
|
||||||
'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', ''),
|
||||||
|
@ -283,6 +283,7 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale']
|
|||||||
|
|
||||||
Route::post('reports/clients', ClientReportController::class);
|
Route::post('reports/clients', ClientReportController::class);
|
||||||
Route::post('reports/activities', ActivityReportController::class);
|
Route::post('reports/activities', ActivityReportController::class);
|
||||||
|
Route::post('reports/client_contacts', ClientContactReportController::class);
|
||||||
Route::post('reports/contacts', ClientContactReportController::class);
|
Route::post('reports/contacts', ClientContactReportController::class);
|
||||||
Route::post('reports/credits', CreditReportController::class);
|
Route::post('reports/credits', CreditReportController::class);
|
||||||
Route::post('reports/documents', DocumentReportController::class);
|
Route::post('reports/documents', DocumentReportController::class);
|
||||||
|
@ -141,6 +141,9 @@ Route::group(['middleware' => ['invite_db'], 'prefix' => 'client', 'as' => 'clie
|
|||||||
|
|
||||||
Route::get('phantom/{entity}/{invitation_key}', [Phantom::class, 'displayInvitation'])->middleware(['invite_db', 'phantom_secret'])->name('phantom_view');
|
Route::get('phantom/{entity}/{invitation_key}', [Phantom::class, 'displayInvitation'])->middleware(['invite_db', 'phantom_secret'])->name('phantom_view');
|
||||||
|
|
||||||
|
Route::get('.env', function () {
|
||||||
|
})->middleware('throttle:honeypot');
|
||||||
|
|
||||||
Route::fallback(function () {
|
Route::fallback(function () {
|
||||||
|
|
||||||
if (Ninja::isSelfHost() && Account::first()?->set_react_as_default_ap) {
|
if (Ninja::isSelfHost() && Account::first()?->set_react_as_default_ap) {
|
||||||
|
@ -11,14 +11,15 @@
|
|||||||
|
|
||||||
namespace Tests\Feature;
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use Tests\TestCase;
|
||||||
use App\Models\Task;
|
use App\Models\Task;
|
||||||
|
use App\Models\Project;
|
||||||
|
use Tests\MockAccountData;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Tests\MockAccountData;
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
use Tests\TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
@ -358,6 +359,34 @@ class TaskApiTest extends TestCase
|
|||||||
$this->assertTrue($this->checkTimeLog($log));
|
$this->assertTrue($this->checkTimeLog($log));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTaskListWithProjects()
|
||||||
|
{
|
||||||
|
|
||||||
|
$project = Project::factory()->create([
|
||||||
|
'user_id' => $this->user->id,
|
||||||
|
'company_id' => $this->company->id,
|
||||||
|
'client_id' => $this->client->id,
|
||||||
|
'name' => 'proggy',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'project_id' => $this->encodePrimaryKey($project->id),
|
||||||
|
'timelog' => [[1,2,'a'],[3,4,'d']],
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = $this->withHeaders([
|
||||||
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
|
'X-API-TOKEN' => $this->token,
|
||||||
|
])->post('/api/v1/tasks?include=project', $data);
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
|
||||||
|
$arr = $response->json();
|
||||||
|
|
||||||
|
$this->assertEquals('proggy', $arr['data']['project']['name']);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function testTaskListClientStatus()
|
public function testTaskListClientStatus()
|
||||||
{
|
{
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
|
Loading…
x
Reference in New Issue
Block a user