Serve tailwind locally (#3505)

* Fixes for tests

* Working on PDF tables

* Fixes for null values in designs

* Refactoring entity variables for PDF

* Fixes for pdf variables

* Minor fixes for designs

* Working on variable replacement for tables

* Refactoring designs

* Refactoring designs

* Refactoring design implementation

* Working on refactoring designs

* Serve tailwind locally

* Design changes

* refactor white labelling

* refactors for white label

* Fixes for payment type id nulls
This commit is contained in:
David Bomba 2020-03-17 19:40:10 +11:00 committed by GitHub
parent 0e12b63c95
commit 58803d37f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 261 additions and 185 deletions

View File

@ -0,0 +1,156 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Http\Controllers;
use App\Models\Account;
use App\Utils\CurlUtils;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Http\Request;
class LicenseController extends BaseController
{
public function __construct()
{
parent::__construct();
}
/**
* Claim a white label license.
*
* @return \Illuminate\Http\Response
*
* @OA\Get(
* path="/api/v1/claim_license",
* operationId="getClaimLicense",
* tags={"claim_license"},
* summary="Attempts to claim a white label license",
* description="Attempts to claim a white label license",
* @OA\Parameter(ref="#/components/parameters/X-Api-Secret"),
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
* @OA\Parameter(
* name="license_key",
* in="path",
* description="The license hash",
* example="d87sh-s755s-s7d76-sdsd8",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Parameter(
* name="product_id",
* in="path",
* description="The ID of the product purchased.",
* example="1",
* required=true,
* @OA\Schema(
* type="string",
* format="string",
* ),
* ),
* @OA\Response(
* response=200,
* description="Success!",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
* ),
* @OA\Response(
* response=422,
* description="Validation error",
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
* ),
* @OA\Response(
* response="default",
* description="Unexpected Error",
* @OA\JsonContent(ref="#/components/schemas/Error"),
* ),
* )
*/
public function index()
{
/* Catch claim license requests */
if(config('ninja.environment') == 'selfhost' && $request->has('license_key') && $request->has('product_id') )
{
$license_key = $request->input('license_key');
$product_id = $request->input('product_id');
$url = config('ninja.license_url') . "/claim_license?license_key={$license_key}&product_id={$product_id}&get_date=true";
$data = trim(CurlUtils::get($url));
if ($data == Account::RESULT_FAILURE) {
$error = [
'message' => trans('texts.invalid_white_label_license'),
'errors' => []
];
return response()->json($error, 400);
} elseif ($data) {
$date = date_create($data)->modify('+1 year');
if ($date < date_create()) {
$error = [
'message' => trans('texts.invalid_white_label_license'),
'errors' => []
];
return response()->json($error, 400);
} else {
$account = auth()->user()->company()->account;
$account->plan_term = Account::PLAN_TERM_YEARLY;
$account->plan_paid = $data;
$account->plan_expires = $date->format('Y-m-d');
$account->plan = Account::PLAN_WHITE_LABEL;
$account->save();
$error = [
'message' => trans('texts.bought_white_label'),
'errors' => []
];
return response()->json($error, 200);
}
} else {
$error = [
'message' => trans('texts.white_label_license_error'),
'errors' => []
];
return response()->json($error, 400);
}
}
$error = [
'message' => trans('texts.invalid_white_label_license'),
'errors' => []
];
return response()->json($error, 400);
}
}

View File

@ -70,69 +70,6 @@ class StartupCheck
}
}
/* Catch claim license requests */
if(config('ninja.environment') == 'selfhost' && $request->has('license_key') && $request->has('product_id') && $request->segment(3) == 'claim_license')
{
$license_key = $request->input('license_key');
$product_id = $request->input('product_id');
$url = config('ninja.license_url') . "/claim_license?license_key={$license_key}&product_id={$product_id}&get_date=true";
$data = trim(CurlUtils::get($url));
if ($data == Account::RESULT_FAILURE) {
$error = [
'message' => trans('texts.invalid_white_label_license'),
'errors' => []
];
return response()->json($error, 400);
} elseif ($data) {
$date = date_create($data)->modify('+1 year');
if ($date < date_create()) {
$error = [
'message' => trans('texts.invalid_white_label_license'),
'errors' => []
];
return response()->json($error, 400);
} else {
$account = auth()->user()->company()->account;
$account->plan_term = Account::PLAN_TERM_YEARLY;
$account->plan_paid = $data;
$account->plan_expires = $date->format('Y-m-d');
$account->plan = Account::PLAN_WHITE_LABEL;
$account->save();
$error = [
'message' => trans('texts.bought_white_label'),
'errors' => []
];
return response()->json($error, 200);
}
} else {
$error = [
'message' => trans('texts.white_label_license_error'),
'errors' => []
];
return response()->json($error, 400);
}
}
$response = $next($request);
return $response;

View File

@ -20,6 +20,9 @@ use Illuminate\Support\Facades\DB;
*/
class Ninja
{
const TEST_USERNAME = 'user@example.com';
public static function isSelfHost()
{
return config('ninja.environment') === 'selfhost';
@ -72,4 +75,33 @@ class Ninja
{
return 'Self hosted installation limited to one account';
}
public static function registerNinjaUser($user)
{
if (! $user || $user->email == self::TEST_USERNAME) {
return false;
}
$url = (Utils::isNinjaDev() ? SITE_URL : NINJA_APP_URL) . '/signup/register';
$data = '';
$fields = [
'first_name' => urlencode($user->first_name),
'last_name' => urlencode($user->last_name),
'email' => urlencode($user->email),
];
foreach ($fields as $key => $value) {
$data .= $key.'='.$value.'&';
}
rtrim($data, '&');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
}
}

View File

@ -73,7 +73,7 @@ trait MakesInvoiceValues
{
$custom_fields = $this->company->custom_fields;
if(property_exists($custom_fields, $field)){
if($custom_fields && property_exists($custom_fields, $field)){
$custom_field = $custom_fields->{$field};
$custom_field_parts = explode("|", $custom_field);
@ -84,59 +84,6 @@ trait MakesInvoiceValues
return '';
// //todo we might want to translate like this
// //trans('texts.labe', [], null, $this->client->locale());
// $data = [];
// foreach (self::$labels as $label) {
// $data['$'.$label . '_label'] = ctrans('texts.'.$label);
// }
// if($custom_fields)
// {
// foreach($custom_fields as $key => $value)
// {
// if(strpos($value, '|') !== false)
// {
// $value = explode("|", $value);
// $value = $value[0];
// }
// $data['$'.$key.'_label'] = $value;
// }
// }
/*
Don't forget pipe | strings for dropdowns needs to be filtered
*/
/*
invoice1
invoice2
invoice3
invoice4
surcharge1
surcharge2
surcharge3
surcharge4
client1
client2
client3
client4
contact1
contact2
contact3
contact4
*/
// $arrKeysLength = array_map('strlen', array_keys($data));
// array_multisort($arrKeysLength, SORT_DESC, $data);
// return $data;
}
public function makeLabels($contact = null) :array

View File

@ -973,8 +973,6 @@ class CreateUsersTable extends Migration
$t->foreign('company_gateway_id')->references('id')->on('company_gateways')->onDelete('cascade')->onUpdate('cascade');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
$t->foreign('type_id')->references('id')->on('payment_types');
});
Schema::create('paymentables', function ($table) { //allows multiple invoices to one payment

View File

@ -18,127 +18,133 @@ return $request->user();
Route::group(['middleware' => ['api_secret_check']], function () {
Route::post('api/v1/signup', 'AccountController@store')->name('signup.submit');
Route::post('api/v1/oauth_login', 'Auth\LoginController@oauthApiLogin');
Route::post('api/v1/signup', 'AccountController@store')->name('signup.submit');
Route::post('api/v1/oauth_login', 'Auth\LoginController@oauthApiLogin');
});
});
Route::group(['api_secret_check', 'email_db'], function () {
Route::post('api/v1/login', 'Auth\LoginController@apiLogin')->name('login.submit');
Route::post('api/v1/reset_password', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.reset');
Route::post('api/v1/login', 'Auth\LoginController@apiLogin')->name('login.submit');
Route::post('api/v1/reset_password', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.reset');
});
});
Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'api/v1', 'as' => 'api.'], function () {
Route::resource('activities', 'ActivityController');// name = (clients. index / create / show / update / destroy / edit
Route::resource('activities', 'ActivityController');// name = (clients. index / create / show / update / destroy / edit
Route::resource('clients', 'ClientController');// name = (clients. index / create / show / update / destroy / edit
Route::resource('clients', 'ClientController');// name = (clients. index / create / show / update / destroy / edit
Route::post('clients/bulk', 'ClientController@bulk')->name('clients.bulk');
Route::post('clients/bulk', 'ClientController@bulk')->name('clients.bulk');
Route::resource('invoices', 'InvoiceController');// name = (invoices. index / create / show / update / destroy / edit
Route::resource('invoices', 'InvoiceController');// name = (invoices. index / create / show / update / destroy / edit
Route::get('invoices/{invoice}/{action}', 'InvoiceController@action')->name('invoices.action');
Route::get('invoices/{invoice}/{action}', 'InvoiceController@action')->name('invoices.action');
Route::get('invoice/{invitation_key}/download', 'InvoiceController@downloadPdf')->name('invoices.downloadPdf');
Route::get('invoice/{invitation_key}/download', 'InvoiceController@downloadPdf')->name('invoices.downloadPdf');
Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk');
Route::post('invoices/bulk', 'InvoiceController@bulk')->name('invoices.bulk');
Route::resource('credits', 'CreditController');// name = (credits. index / create / show / update / destroy / edit
Route::resource('credits', 'CreditController');// name = (credits. index / create / show / update / destroy / edit
Route::get('credits/{credit}/{action}', 'CreditController@action')->name('credits.action');
Route::get('credits/{credit}/{action}', 'CreditController@action')->name('credits.action');
Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
Route::resource('products', 'ProductController');// name = (products. index / create / show / update / destroy / edit
Route::resource('products', 'ProductController');// name = (products. index / create / show / update / destroy / edit
Route::post('products/bulk', 'ProductController@bulk')->name('products.bulk');
Route::post('products/bulk', 'ProductController@bulk')->name('products.bulk');
Route::resource('quotes', 'QuoteController');// name = (quotes. index / create / show / update / destroy / edit
Route::resource('quotes', 'QuoteController');// name = (quotes. index / create / show / update / destroy / edit
Route::get('quotes/{quote}/{action}', 'QuoteController@action')->name('quotes.action');
Route::get('quotes/{quote}/{action}', 'QuoteController@action')->name('quotes.action');
Route::post('quotes/bulk', 'QuoteController@bulk')->name('quotes.bulk');
Route::post('quotes/bulk', 'QuoteController@bulk')->name('quotes.bulk');
Route::resource('recurring_invoices', 'RecurringInvoiceController');// name = (recurring_invoices. index / create / show / update / destroy / edit
Route::resource('recurring_invoices', 'RecurringInvoiceController');// name = (recurring_invoices. index / create / show / update / destroy / edit
Route::post('recurring_invoices/bulk', 'RecurringInvoiceController@bulk')->name('recurring_invoices.bulk');
Route::post('recurring_invoices/bulk', 'RecurringInvoiceController@bulk')->name('recurring_invoices.bulk');
Route::resource('recurring_quotes', 'RecurringQuoteController');// name = (recurring_invoices. index / create / show / update / destroy / edit
Route::resource('recurring_quotes', 'RecurringQuoteController');// name = (recurring_invoices. index / create / show / update / destroy / edit
Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk');
Route::post('recurring_quotes/bulk', 'RecurringQuoteController@bulk')->name('recurring_quotes.bulk');
Route::resource('expenses', 'ExpenseController');// name = (expenses. index / create / show / update / destroy / edit
Route::resource('expenses', 'ExpenseController');// name = (expenses. index / create / show / update / destroy / edit
Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
Route::post('expenses/bulk', 'ExpenseController@bulk')->name('expenses.bulk');
Route::resource('vendors', 'VendorController');// name = (vendors. index / create / show / update / destroy / edit
Route::resource('vendors', 'VendorController');// name = (vendors. index / create / show / update / destroy / edit
Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk');
Route::post('vendors/bulk', 'VendorController@bulk')->name('vendors.bulk');
Route::resource('client_statement', 'ClientStatementController@statement');// name = (client_statement. index / create / show / update / destroy / edit
Route::resource('client_statement', 'ClientStatementController@statement');// name = (client_statement. index / create / show / update / destroy / edit
Route::resource('payments', 'PaymentController');// name = (payments. index / create / show / update / destroy / edit
Route::resource('payments', 'PaymentController');// name = (payments. index / create / show / update / destroy / edit
Route::post('payments/refund', 'PaymentController@refund')->name('payments.refund');
Route::post('payments/refund', 'PaymentController@refund')->name('payments.refund');
Route::post('payments/bulk', 'PaymentController@bulk')->name('payments.bulk');
Route::post('payments/bulk', 'PaymentController@bulk')->name('payments.bulk');
Route::post('migrate', 'MigrationController@index')->name('migrate.start');
Route::post('migrate', 'MigrationController@index')->name('migrate.start');
Route::resource('designs', 'DesignController');// name = (payments. index / create / show / update / destroy / edit
Route::resource('designs', 'DesignController');// name = (payments. index / create / show / update / destroy / edit
// Route::resource('users', 'UserController')->middleware('password_protected'); // name = (users. index / create / show / update / destroy / edit
Route::get('users', 'UserController@index');
Route::put('users/{user}', 'UserController@update')->middleware('password_protected');
Route::post('users', 'UserController@store')->middleware('password_protected');
Route::post('users/{user}/attach_to_company', 'UserController@attach')->middleware('password_protected');
Route::delete('users/{user}/detach_from_company', 'UserController@detach')->middleware('password_protected');
// Route::resource('users', 'UserController')->middleware('password_protected'); // name = (users. index / create / show / update / destroy / edit
Route::get('users', 'UserController@index');
Route::put('users/{user}', 'UserController@update')->middleware('password_protected');
Route::post('users', 'UserController@store')->middleware('password_protected');
Route::post('users/{user}/attach_to_company', 'UserController@attach')->middleware('password_protected');
Route::delete('users/{user}/detach_from_company', 'UserController@detach')->middleware('password_protected');
Route::post('users/bulk', 'UserController@bulk')->name('users.bulk')->middleware('password_protected');
Route::post('users/bulk', 'UserController@bulk')->name('users.bulk')->middleware('password_protected');
Route::post('migration/purge/{company}', 'MigrationController@purgeCompany')->middleware('password_protected');
Route::post('migration/purge_save_settings/{company}', 'MigrationController@purgeCompanySaveSettings')->middleware('password_protected');
Route::post('migration/start/{company}', 'MigrationController@startMigration');
Route::post('migration/purge/{company}', 'MigrationController@purgeCompany')->middleware('password_protected');
Route::post('migration/purge_save_settings/{company}', 'MigrationController@purgeCompanySaveSettings')->middleware('password_protected');
Route::post('migration/start/{company}', 'MigrationController@startMigration');
Route::resource('companies', 'CompanyController');// name = (companies. index / create / show / update / destroy / edit
Route::resource('companies', 'CompanyController');// name = (companies. index / create / show / update / destroy / edit
Route::resource('company_gateways', 'CompanyGatewayController');
Route::put('company_users/{user}', 'CompanyUserController@update');
Route::resource('company_gateways', 'CompanyGatewayController');
Route::put('company_users/{user}', 'CompanyUserController@update');
Route::resource('group_settings', 'GroupSettingController');
Route::resource('group_settings', 'GroupSettingController');
Route::resource('tax_rates', 'TaxRateController');// name = (tasks. index / create / show / update / destroy / edit
Route::resource('tax_rates', 'TaxRateController');// name = (tasks. index / create / show / update / destroy / edit
Route::post('refresh', 'Auth\LoginController@refresh');
Route::post('refresh', 'Auth\LoginController@refresh');
Route::post('templates', 'TemplateController@show')->name('templates.show');
Route::post('preview', 'PreviewController@show')->name('previews.show');
Route::post('templates', 'TemplateController@show')->name('templates.show');
Route::post('preview', 'PreviewController@show')->name('previews.show');
Route::post('self-update', 'SelfUpdateController@update')->middleware('password_protected');
Route::post('self-update', 'SelfUpdateController@update')->middleware('password_protected');
Route::post('self-update/check_version', 'SelfUpdateController@checkVersion');
Route::post('self-update/check_version', 'SelfUpdateController@checkVersion');
/*
Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit
/*
Route::resource('tasks', 'TaskController'); // name = (tasks. index / create / show / update / destroy / edit
Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk');
Route::post('tasks/bulk', 'TaskController@bulk')->name('tasks.bulk');
Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit
Route::resource('credits', 'CreditController'); // name = (credits. index / create / show / update / destroy / edit
Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
Route::post('credits/bulk', 'CreditController@bulk')->name('credits.bulk');
Route::get('settings', 'SettingsController@index')->name('user.settings');
*/
Route::post('support/messages/send', 'Support\Messages\SendingController');
});
Route::get('settings', 'SettingsController@index')->name('user.settings');
*/
Route::post('support/messages/send', 'Support\Messages\SendingController');
});
Route::group(['middleware' => ['api_db', 'locale'], 'prefix' => 'api/v1', 'as' => 'api.'], function () {
Route::get('claim_license', 'LicenseController@index')->name('license.index');
});
Route::fallback('BaseController@notFound');