mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-12 06:02:39 +01:00
commit
50386b66b6
@ -1 +1 @@
|
|||||||
5.3.52
|
5.3.53
|
@ -192,7 +192,7 @@ class Handler extends ExceptionHandler
|
|||||||
} elseif ($exception instanceof MethodNotAllowedHttpException && $request->expectsJson()) {
|
} elseif ($exception instanceof MethodNotAllowedHttpException && $request->expectsJson()) {
|
||||||
return response()->json(['message'=>'Method not supported for this route'], 404);
|
return response()->json(['message'=>'Method not supported for this route'], 404);
|
||||||
} elseif ($exception instanceof ValidationException && $request->expectsJson()) {
|
} elseif ($exception instanceof ValidationException && $request->expectsJson()) {
|
||||||
nlog($exception->validator->getMessageBag());
|
// nlog($exception->validator->getMessageBag());
|
||||||
return response()->json(['message' => 'The given data was invalid.', 'errors' => $exception->validator->getMessageBag()], 422);
|
return response()->json(['message' => 'The given data was invalid.', 'errors' => $exception->validator->getMessageBag()], 422);
|
||||||
} elseif ($exception instanceof RelationNotFoundException && $request->expectsJson()) {
|
} elseif ($exception instanceof RelationNotFoundException && $request->expectsJson()) {
|
||||||
return response()->json(['message' => $exception->getMessage()], 400);
|
return response()->json(['message' => $exception->getMessage()], 400);
|
||||||
|
@ -203,6 +203,11 @@ class CreditController extends BaseController
|
|||||||
->triggeredActions($request)
|
->triggeredActions($request)
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
|
if($credit->invoice_id){
|
||||||
|
$credit = $credit->service()->markSent()->save();
|
||||||
|
$credit->client->service()->updatePaidToDate(-1 * $credit->balance)->save();
|
||||||
|
}
|
||||||
|
|
||||||
event(new CreditWasCreated($credit, $credit->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
event(new CreditWasCreated($credit, $credit->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null)));
|
||||||
|
|
||||||
return $this->itemResponse($credit);
|
return $this->itemResponse($credit);
|
||||||
|
@ -42,6 +42,9 @@ class HostedMigrationController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$account = CreateAccount::dispatchNow($request->all(), $request->getClientIp());
|
$account = CreateAccount::dispatchNow($request->all(), $request->getClientIp());
|
||||||
|
$account->hosted_client_count = 100;
|
||||||
|
$account->hosted_company_count = 10;
|
||||||
|
$account->save();
|
||||||
|
|
||||||
$company = $account->companies->first();
|
$company = $account->companies->first();
|
||||||
|
|
||||||
|
@ -658,7 +658,8 @@ class InvoiceController extends BaseController
|
|||||||
// code...
|
// code...
|
||||||
break;
|
break;
|
||||||
case 'mark_paid':
|
case 'mark_paid':
|
||||||
if ($invoice->balance < 0 || $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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ class Kernel extends HttpKernel
|
|||||||
|
|
||||||
'api' => [
|
'api' => [
|
||||||
// 'throttle:300,1',
|
// 'throttle:300,1',
|
||||||
|
// 'cors',
|
||||||
'bindings',
|
'bindings',
|
||||||
'query_logging',
|
'query_logging',
|
||||||
],
|
],
|
||||||
|
@ -16,7 +16,7 @@ class Cors
|
|||||||
// ALLOW OPTIONS METHOD
|
// ALLOW OPTIONS METHOD
|
||||||
$headers = [
|
$headers = [
|
||||||
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
|
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
|
||||||
'Access-Control-Allow-Headers'=> 'X-API-COMPANY-KEY,X-CLIENT-VERSION,X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-CSRF-TOKEN,X-XSRF-TOKEN,X-LIVEWIRE',
|
'Access-Control-Allow-Headers'=> 'X-API-PASSWORD-BASE64,X-API-COMPANY-KEY,X-CLIENT-VERSION,X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-CSRF-TOKEN,X-XSRF-TOKEN,X-LIVEWIRE',
|
||||||
];
|
];
|
||||||
|
|
||||||
return Response::make('OK', 200, $headers);
|
return Response::make('OK', 200, $headers);
|
||||||
@ -26,7 +26,7 @@ class Cors
|
|||||||
|
|
||||||
$response->headers->set('Access-Control-Allow-Origin', '*');
|
$response->headers->set('Access-Control-Allow-Origin', '*');
|
||||||
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
||||||
$response->headers->set('Access-Control-Allow-Headers', 'X-API-COMPANY-KEY,X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-CSRF-TOKEN,X-XSRF-TOKEN,X-LIVEWIRE');
|
$response->headers->set('Access-Control-Allow-Headers', 'X-API-PASSWORD-BASE64,X-API-COMPANY-KEY,X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-CSRF-TOKEN,X-XSRF-TOKEN,X-LIVEWIRE');
|
||||||
$response->headers->set('Access-Control-Expose-Headers', 'X-APP-VERSION,X-MINIMUM-CLIENT-VERSION');
|
$response->headers->set('Access-Control-Expose-Headers', 'X-APP-VERSION,X-MINIMUM-CLIENT-VERSION');
|
||||||
$response->headers->set('X-APP-VERSION', config('ninja.app_version'));
|
$response->headers->set('X-APP-VERSION', config('ninja.app_version'));
|
||||||
$response->headers->set('X-MINIMUM-CLIENT-VERSION', config('ninja.minimum_client_version'));
|
$response->headers->set('X-MINIMUM-CLIENT-VERSION', config('ninja.minimum_client_version'));
|
||||||
|
@ -39,7 +39,7 @@ class SessionDomains
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
||||||
Cookie::queue(Cookie::forget('invoice_ninja_session', '/'));
|
// Cookie::queue(Cookie::forget('invoice_ninja_session', '/'));
|
||||||
|
|
||||||
config(['session.domain' => $domain_name]);
|
config(['session.domain' => $domain_name]);
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ namespace App\Http\Requests\Credit;
|
|||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
use App\Http\ValidationRules\Credit\UniqueCreditNumberRule;
|
use App\Http\ValidationRules\Credit\UniqueCreditNumberRule;
|
||||||
|
use App\Http\ValidationRules\Credit\ValidInvoiceCreditRule;
|
||||||
use App\Models\Credit;
|
use App\Models\Credit;
|
||||||
use App\Utils\Traits\CleanLineItems;
|
use App\Utils\Traits\CleanLineItems;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
@ -58,7 +59,8 @@ class StoreCreditRequest extends Request
|
|||||||
$rules['number'] = ['nullable', Rule::unique('credits')->where('company_id', auth()->user()->company()->id)];
|
$rules['number'] = ['nullable', Rule::unique('credits')->where('company_id', auth()->user()->company()->id)];
|
||||||
$rules['discount'] = 'sometimes|numeric';
|
$rules['discount'] = 'sometimes|numeric';
|
||||||
|
|
||||||
|
if($this->invoice_id)
|
||||||
|
$rules['invoice_id'] = new ValidInvoiceCreditRule();
|
||||||
|
|
||||||
$rules['line_items'] = 'array';
|
$rules['line_items'] = 'array';
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ class UpdateInvoiceRequest extends Request
|
|||||||
$rules['line_items'] = 'array';
|
$rules['line_items'] = 'array';
|
||||||
$rules['discount'] = 'sometimes|numeric';
|
$rules['discount'] = 'sometimes|numeric';
|
||||||
|
|
||||||
if($this->input('status_id') != Invoice::STATUS_DRAFT)
|
// if($this->input('status_id') != Invoice::STATUS_DRAFT)
|
||||||
$rules['balance'] = new InvoiceBalanceSanity($this->invoice, $this->all());
|
// $rules['balance'] = new InvoiceBalanceSanity($this->invoice, $this->all());
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
79
app/Http/ValidationRules/Credit/ValidInvoiceCreditRule.php
Normal file
79
app/Http/ValidationRules/Credit/ValidInvoiceCreditRule.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Credit Ninja (https://creditninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/creditninja/creditninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2021. Credit Ninja LLC (https://creditninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\ValidationRules\Credit;
|
||||||
|
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ValidInvoiceCreditRule.
|
||||||
|
*/
|
||||||
|
class ValidInvoiceCreditRule implements Rule
|
||||||
|
{
|
||||||
|
public $error_message;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function passes($attribute, $value)
|
||||||
|
{
|
||||||
|
return $this->checkIfCreditInvoiceValid($value); //if it exists, return false!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return $this->error_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function checkIfCreditInvoiceValid($value) : bool
|
||||||
|
{
|
||||||
|
$invoice = Invoice::withTrashed()->find($value);
|
||||||
|
|
||||||
|
if($invoice->balance >= $invoice->amount){
|
||||||
|
$this->error_message = "Cannot reverse an invoice with no payment applied.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$existing_credit_amounts = $invoice->credits()->sum('amount');
|
||||||
|
|
||||||
|
if($this->sumCredit() > ($invoice->amount - $invoice->balance - $existing_credit_amounts)){
|
||||||
|
$this->error_message = "Credit cannot exceed the payment / credits already applied to invoice.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function sumCredit()
|
||||||
|
{
|
||||||
|
$cost = 0;
|
||||||
|
|
||||||
|
foreach(request()->input('line_items') as $item)
|
||||||
|
{
|
||||||
|
$cost += $item['cost'] * $item['quantity'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cost;
|
||||||
|
}
|
||||||
|
}
|
@ -82,7 +82,8 @@ class CreateAccount
|
|||||||
|
|
||||||
if(Ninja::isHosted())
|
if(Ninja::isHosted())
|
||||||
{
|
{
|
||||||
|
$sp794f3f->hosted_client_count = config('ninja.quotas.free.clients');
|
||||||
|
$sp794f3f->hosted_company_count = config('ninja.quotas.free.max_companies');
|
||||||
$sp794f3f->trial_started = now();
|
$sp794f3f->trial_started = now();
|
||||||
$sp794f3f->trial_plan = 'pro';
|
$sp794f3f->trial_plan = 'pro';
|
||||||
|
|
||||||
|
@ -327,6 +327,8 @@ class BaseRepository
|
|||||||
if (! $model->design_id)
|
if (! $model->design_id)
|
||||||
$model->design_id = $this->decodePrimaryKey($client->getSetting('credit_design_id'));
|
$model->design_id = $this->decodePrimaryKey($client->getSetting('credit_design_id'));
|
||||||
|
|
||||||
|
if(array_key_exists('invoice_id', $data) && $data['invoice_id'])
|
||||||
|
$model->invoice_id = $data['invoice_id'];
|
||||||
|
|
||||||
if($this->new_model)
|
if($this->new_model)
|
||||||
event('eloquent.created: App\Models\Credit', $model);
|
event('eloquent.created: App\Models\Credit', $model);
|
||||||
|
@ -88,7 +88,6 @@ class MarkPaid extends AbstractService
|
|||||||
$this->invoice
|
$this->invoice
|
||||||
->service()
|
->service()
|
||||||
->applyNumber()
|
->applyNumber()
|
||||||
// ->deletePdf()
|
|
||||||
->touchPdf()
|
->touchPdf()
|
||||||
->save();
|
->save();
|
||||||
|
|
||||||
|
@ -83,6 +83,8 @@ class AccountTransformer extends EntityTransformer
|
|||||||
'emails_sent' => (int) $account->emailsSent(),
|
'emails_sent' => (int) $account->emailsSent(),
|
||||||
'email_quota' => (int) $account->getDailyEmailLimit(),
|
'email_quota' => (int) $account->getDailyEmailLimit(),
|
||||||
'is_migrated' => (bool) $account->is_migrated,
|
'is_migrated' => (bool) $account->is_migrated,
|
||||||
|
'hosted_client_count' => (int) $account->hosted_client_count,
|
||||||
|
'hosted_company_count' => (int) $account->hosted_company_count,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,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.3.52',
|
'app_version' => '5.3.53',
|
||||||
'app_tag' => '5.3.52',
|
'app_tag' => '5.3.53',
|
||||||
'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', ''),
|
||||||
@ -134,14 +134,19 @@ return [
|
|||||||
],
|
],
|
||||||
'quotas' => [
|
'quotas' => [
|
||||||
'free' => [
|
'free' => [
|
||||||
'clients' => 50,
|
|
||||||
'daily_emails' => 50,
|
'daily_emails' => 50,
|
||||||
|
'clients' => 20,
|
||||||
|
'max_companies' => 1,
|
||||||
],
|
],
|
||||||
'pro' => [
|
'pro' => [
|
||||||
'daily_emails' => 100,
|
'daily_emails' => 100,
|
||||||
|
'clients' => 1000000,
|
||||||
|
'max_companies' => 10,
|
||||||
],
|
],
|
||||||
'enterprise' => [
|
'enterprise' => [
|
||||||
'daily_emails' => 200,
|
'daily_emails' => 200,
|
||||||
|
'clients' => 1000000,
|
||||||
|
'max_companies' => 10,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'auth' => [
|
'auth' => [
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddClientCountToAccountsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('accounts', function (Blueprint $table) {
|
||||||
|
$table->unsignedInteger('hosted_client_count')->nullable();
|
||||||
|
$table->unsignedInteger('hosted_company_count')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user