mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-30 21:24:32 -04:00
commit
41fea85fa5
@ -1 +1 @@
|
||||
5.6.0
|
||||
5.6.1
|
@ -435,11 +435,38 @@ class CheckData extends Command
|
||||
|
||||
private function checkEntityInvitations()
|
||||
{
|
||||
|
||||
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]);
|
||||
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]);
|
||||
|
||||
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) {
|
||||
if ($entity::doesntHave('invitations')->count() > 0) {
|
||||
|
@ -102,8 +102,13 @@ class PaymentFilters extends QueryFilters
|
||||
if (count($payment_filters) >0) {
|
||||
$query->whereIn('status_id', $payment_filters);
|
||||
}
|
||||
|
||||
if(in_array('partially_unapplied', $status_parameters)) {
|
||||
$query->where('amount', '>', 'applied')->where('refunded', 0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace App\Jobs\Cron;
|
||||
|
||||
use App\Models\Payment;
|
||||
use App\Models\Project;
|
||||
use App\Libraries\MultiDB;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
@ -65,7 +66,6 @@ class UpdateCalculatedFields
|
||||
$project->save();
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -621,7 +621,7 @@ class Account extends BaseModel
|
||||
|
||||
public function getTrialDays()
|
||||
{
|
||||
if ($this->payment_id) {
|
||||
if ($this->payment_id || $this->is_migrated) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ use Illuminate\Support\Str;
|
||||
* @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 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 newQuery()
|
||||
* @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)
|
||||
->where('is_deleted', 0)
|
||||
->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) {
|
||||
$this->client = Client::withTrashed()->where('id', $this->client->id)->lockForUpdate()->first();
|
||||
|
@ -371,28 +371,28 @@ class Statement
|
||||
|
||||
return $ranges;
|
||||
case '60':
|
||||
$ranges[0] = now()->startOfDay()->subDays(30);
|
||||
$ranges[0] = now()->startOfDay()->subDays(31);
|
||||
$ranges[1] = now()->startOfDay()->subDays(60);
|
||||
|
||||
return $ranges;
|
||||
case '90':
|
||||
$ranges[0] = now()->startOfDay()->subDays(60);
|
||||
$ranges[0] = now()->startOfDay()->subDays(61);
|
||||
$ranges[1] = now()->startOfDay()->subDays(90);
|
||||
|
||||
return $ranges;
|
||||
case '120':
|
||||
$ranges[0] = now()->startOfDay()->subDays(90);
|
||||
$ranges[0] = now()->startOfDay()->subDays(91);
|
||||
$ranges[1] = now()->startOfDay()->subDays(120);
|
||||
|
||||
return $ranges;
|
||||
case '120+':
|
||||
$ranges[0] = now()->startOfDay()->subDays(120);
|
||||
$ranges[0] = now()->startOfDay()->subDays(121);
|
||||
$ranges[1] = now()->startOfDay()->subYears(20);
|
||||
|
||||
return $ranges;
|
||||
default:
|
||||
$ranges[0] = now()->startOfDay()->subDays(0);
|
||||
$ranges[1] = now()->subDays(30);
|
||||
$ranges[0] = now()->startOfDay();
|
||||
$ranges[1] = now()->startOfDay()->subDays(30);
|
||||
|
||||
return $ranges;
|
||||
}
|
||||
|
@ -130,13 +130,6 @@ class CreditService
|
||||
->credits()
|
||||
->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->service()
|
||||
->updatePaidToDate($adjustment)
|
||||
|
@ -123,7 +123,7 @@ class ARSummaryReport extends BaseExport
|
||||
->where('balance', '>', 0)
|
||||
->where('is_deleted', 0)
|
||||
->where(function ($query){
|
||||
$query->where('due_date', '<', now()->startOfDay())
|
||||
$query->where('due_date', '>', now()->startOfDay())
|
||||
->orWhereNull('due_date');
|
||||
})
|
||||
->sum('balance');
|
||||
@ -173,22 +173,22 @@ class ARSummaryReport extends BaseExport
|
||||
|
||||
return $ranges;
|
||||
case '60':
|
||||
$ranges[0] = now()->startOfDay()->subDays(30);
|
||||
$ranges[0] = now()->startOfDay()->subDays(31);
|
||||
$ranges[1] = now()->startOfDay()->subDays(60);
|
||||
|
||||
return $ranges;
|
||||
case '90':
|
||||
$ranges[0] = now()->startOfDay()->subDays(60);
|
||||
$ranges[0] = now()->startOfDay()->subDays(61);
|
||||
$ranges[1] = now()->startOfDay()->subDays(90);
|
||||
|
||||
return $ranges;
|
||||
case '120':
|
||||
$ranges[0] = now()->startOfDay()->subDays(90);
|
||||
$ranges[0] = now()->startOfDay()->subDays(91);
|
||||
$ranges[1] = now()->startOfDay()->subDays(120);
|
||||
|
||||
return $ranges;
|
||||
case '120+':
|
||||
$ranges[0] = now()->startOfDay()->subDays(120);
|
||||
$ranges[0] = now()->startOfDay()->subDays(121);
|
||||
$ranges[1] = now()->startOfDay()->subYears(20);
|
||||
|
||||
return $ranges;
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace App\Transformers;
|
||||
|
||||
use App\Models\Document;
|
||||
use App\Models\Project;
|
||||
use App\Models\Task;
|
||||
use App\Models\TaskStatus;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
@ -33,7 +34,8 @@ class TaskTransformer extends EntityTransformer
|
||||
*/
|
||||
protected $availableIncludes = [
|
||||
'client',
|
||||
'status'
|
||||
'status',
|
||||
'project',
|
||||
];
|
||||
|
||||
public function includeDocuments(Task $task)
|
||||
@ -65,6 +67,16 @@ class TaskTransformer extends EntityTransformer
|
||||
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)
|
||||
{
|
||||
|
@ -15,8 +15,8 @@ return [
|
||||
'require_https' => env('REQUIRE_HTTPS', true),
|
||||
'app_url' => rtrim(env('APP_URL', ''), '/'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
|
||||
'app_version' => '5.6.0',
|
||||
'app_tag' => '5.6.0',
|
||||
'app_version' => '5.6.1',
|
||||
'app_tag' => '5.6.1',
|
||||
'minimum_client_version' => '5.0.16',
|
||||
'terms_version' => '1.0.1',
|
||||
'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/activities', ActivityReportController::class);
|
||||
Route::post('reports/client_contacts', ClientContactReportController::class);
|
||||
Route::post('reports/contacts', ClientContactReportController::class);
|
||||
Route::post('reports/credits', CreditReportController::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('.env', function () {
|
||||
})->middleware('throttle:honeypot');
|
||||
|
||||
Route::fallback(function () {
|
||||
|
||||
if (Ninja::isSelfHost() && Account::first()?->set_react_as_default_ap) {
|
||||
|
@ -11,14 +11,15 @@
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\Task;
|
||||
use App\Models\Project;
|
||||
use Tests\MockAccountData;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* @test
|
||||
@ -358,6 +359,34 @@ class TaskApiTest extends TestCase
|
||||
$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()
|
||||
{
|
||||
$response = $this->withHeaders([
|
||||
|
Loading…
x
Reference in New Issue
Block a user