1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-19 16:01:34 +02:00

Added support for custom subdomains

This commit is contained in:
Hillel Coren 2015-04-28 23:13:52 +03:00
parent 723aa285f5
commit bc10719fbe
34 changed files with 1555 additions and 326 deletions

View File

@ -78,6 +78,7 @@ module.exports = function(grunt) {
'public/js/simpleexpand.js',
*/
'public/vendor/bootstrap/dist/js/bootstrap.min.js',
'public/js/bootstrap-combobox.js',
],
dest: 'public/js/built.public.js',
@ -89,7 +90,7 @@ module.exports = function(grunt) {
'public/vendor/datatables/media/css/jquery.dataTables.css',
'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css',
'public/vendor/font-awesome/css/font-awesome.min.css',
'public/vendor/bootstrap-datepicker/dist/css/bootstrap-datepicker.css',
'public/vendor/bootstrap-datepicker/css/datepicker3.css',
'public/vendor/spectrum/spectrum.css',
'public/css/bootstrap-combobox.css',
'public/css/typeahead.js-bootstrap.css',
@ -110,6 +111,7 @@ module.exports = function(grunt) {
'public/css/bootstrap.splash.css',
'public/css/splash.css',
*/
'public/css/bootstrap-combobox.css',
'public/vendor/datatables/media/css/jquery.dataTables.css',
'public/vendor/datatables-bootstrap3/BS3/assets/css/datatables.css',
],

View File

@ -69,8 +69,12 @@ class SendRecurringInvoices extends Command
$invoice->custom_taxes2 = $recurInvoice->custom_taxes2;
$invoice->is_amount_discount = $recurInvoice->is_amount_discount;
if ($invoice->client->payment_terms) {
$invoice->due_date = date_create()->modify($invoice->client->payment_terms.' day')->format('Y-m-d');
if ($invoice->client->payment_terms != 0) {
$days = $invoice->client->payment_terms;
if ($days == -1) {
$days = 0;
}
$invoice->due_date = date_create()->modify($days.' day')->format('Y-m-d');
}
$invoice->save();

View File

@ -39,12 +39,15 @@ class Handler extends ExceptionHandler {
*/
public function render($request, Exception $e)
{
$data = [
'error' => get_class($e),
'hideHeader' => true,
];
return response()->view('error', $data);
//return parent::render($request, $e);
if (Utils::isNinjaProd()) {
$data = [
'error' => get_class($e),
'hideHeader' => true,
];
return response()->view('error', $data);
} else {
return parent::render($request, $e);
}
}
}

View File

@ -13,9 +13,16 @@ use View;
use stdClass;
use Cache;
use Response;
use parseCSV;
use App\Models\User;
use App\Models\Client;
use App\Models\Contact;
use App\Models\Invoice;
use App\Models\InvoiceItem;
use App\Models\Activity;
use App\Models\Payment;
use App\Models\Credit;
use App\Models\Account;
use App\Models\Country;
use App\Models\Currency;
@ -577,6 +584,14 @@ class AccountController extends BaseController
$rules['email'] = 'email|required|unique:users,email,'.$user->id.',id';
}
$subdomain = preg_replace('/[^a-zA-Z0-9_\-]/', '', substr(strtolower(Input::get('subdomain')), 0, MAX_SUBDOMAIN_LENGTH));
if (in_array($subdomain, ['www', 'app', 'mail'])) {
$subdomain = null;
}
if ($subdomain) {
$rules['subdomain'] = "unique:accounts,subdomain,{$user->account_id},id";
}
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
@ -586,6 +601,7 @@ class AccountController extends BaseController
} else {
$account = Auth::user()->account;
$account->name = trim(Input::get('name'));
$account->subdomain = $subdomain;
$account->id_number = trim(Input::get('id_number'));
$account->vat_number = trim(Input::get('vat_number'));
$account->work_email = trim(Input::get('work_email'));

View File

@ -2,8 +2,9 @@
use Auth;
use Event;
use Utils;
use Illuminate\Http\Request;
use App\Models\User;
use App\Events\UserLoggedIn;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
@ -43,6 +44,15 @@ class AuthController extends Controller {
$this->middleware('guest', ['except' => 'getLogout']);
}
public function getLoginWrapper()
{
if (!Utils::isNinja() && !User::count()) {
return redirect()->to('invoice_now');
}
return self::getLogin();
}
public function postLoginWrapper(Request $request)
{
$response = self::postLogin($request);

View File

@ -44,6 +44,7 @@ class ClientController extends BaseController
return View::make('list', array(
'entityType' => ENTITY_CLIENT,
'title' => trans('texts.clients'),
'sortCol' => '4',
'columns' => Utils::trans(['checkbox', 'client', 'contact', 'email', 'date_created', 'last_login', 'balance', 'action']),
));
}

View File

@ -32,6 +32,7 @@ class CreditController extends BaseController
return View::make('list', array(
'entityType' => ENTITY_CREDIT,
'title' => trans('texts.credits'),
'sortCol' => '4',
'columns' => Utils::trans(['checkbox', 'client', 'credit_amount', 'credit_balance', 'credit_date', 'private_notes', 'action']),
));
}

View File

@ -28,6 +28,8 @@ class HomeController extends BaseController
return Redirect::to('/setup');
} elseif (Account::count() == 0) {
return Redirect::to('/invoice_now');
} elseif (Auth::check()) {
return Redirect::to('/dashboard');
} else {
return Redirect::to('/login');
}

View File

@ -1,6 +1,10 @@
<?php namespace App\Http\Controllers;
use Utils;
use Response;
use Auth;
use Input;
use App\Models\Subscription;
class IntegrationController extends Controller
{

View File

@ -70,6 +70,7 @@ class InvoiceApiController extends Controller
$response = json_encode($error, JSON_PRETTY_PRINT);
} else {
$data = self::prepareData($data);
$data['client_id'] = $client->id;
$invoice = $this->invoiceRepo->save(false, $data, false);
$invitation = Invitation::createNew();

View File

@ -12,7 +12,7 @@ use Event;
use URL;
use Datatable;
use finfo;
use Request;
use App\Models\Invoice;
use App\Models\Invitation;
use App\Models\Client;
@ -27,7 +27,6 @@ use App\Models\PaymentTerm;
use App\Models\InvoiceDesign;
use App\Models\AccountGateway;
use App\Models\Activity;
use App\Ninja\Mailers\ContactMailer as Mailer;
use App\Ninja\Repositories\InvoiceRepository;
use App\Ninja\Repositories\ClientRepository;
@ -184,6 +183,15 @@ class InvoiceController extends BaseController
return View::make('invoices.deleted');
}
if ($account->subdomain) {
$server = explode('.', Request::server('HTTP_HOST'));
$subdomain = $server[0];
if ($subdomain != 'app' && $subdomain != $account->subdomain) {
return View::make('invoices.deleted');
}
}
if (!Session::has($invitationKey) && (!Auth::check() || Auth::user()->account_id != $invoice->account_id)) {
Activity::viewInvoice($invitation);
Event::fire(new InvoiceViewed($invoice));

View File

@ -229,6 +229,8 @@ class PaymentController extends BaseController
private function convertInputForOmnipay($input)
{
$country = Country::find($input['country_id']);
return [
'firstName' => $input['first_name'],
'lastName' => $input['last_name'],
@ -241,11 +243,13 @@ class PaymentController extends BaseController
'billingCity' => $input['city'],
'billingState' => $input['state'],
'billingPostcode' => $input['postal_code'],
'billingCountry' => $country->iso_3166_2,
'shippingAddress1' => $input['address1'],
'shippingAddress2' => $input['address2'],
'shippingCity' => $input['city'],
'shippingState' => $input['state'],
'shippingPostcode' => $input['postal_code']
'shippingPostcode' => $input['postal_code'],
'shippingCountry' => $country->iso_3166_2
];
}
@ -317,7 +321,7 @@ class PaymentController extends BaseController
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
'countries' => Cache::get('countries'),
'currencyId' => $client->currency_id,
'account' => $client->account
'account' => $client->account,
];
return View::make('payments.payment', $data);
@ -386,6 +390,7 @@ class PaymentController extends BaseController
'city' => 'required',
'state' => 'required',
'postal_code' => 'required',
'country_id' => 'required',
);
$validator = Validator::make(Input::all(), $rules);
@ -494,6 +499,7 @@ class PaymentController extends BaseController
'city' => 'required',
'state' => 'required',
'postal_code' => 'required',
'country_id' => 'required',
);
if ($onSite) {

View File

@ -46,12 +46,13 @@ class StartupCheck
'languages' => 'App\Models\Language',
'paymentTerms' => 'App\Models\PaymentTerm',
'paymentTypes' => 'App\Models\PaymentType',
'countries' => 'App\Models\Country',
];
foreach ($cachedTables as $name => $class) {
if (!Cache::has($name)) {
if ($name == 'paymentTerms') {
$orderBy = 'num_days';
} elseif (in_array($name, ['currencies', 'sizes', 'industries', 'languages'])) {
} elseif (in_array($name, ['currencies', 'sizes', 'industries', 'languages', 'countries'])) {
$orderBy = 'name';
} else {
$orderBy = 'id';

View File

@ -64,7 +64,7 @@ Route::controllers([
get('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@getRegister'));
post('/signup', array('as' => 'signup', 'uses' => 'Auth\AuthController@postRegister'));
get('/login', array('as' => 'login', 'uses' => 'Auth\AuthController@getLogin'));
get('/login', array('as' => 'login', 'uses' => 'Auth\AuthController@getLoginWrapper'));
post('/login', array('as' => 'login', 'uses' => 'Auth\AuthController@postLoginWrapper'));
get('/logout', array('as' => 'logout', 'uses' => 'Auth\AuthController@getLogout'));
get('/forgot', array('as' => 'forgot', 'uses' => 'Auth\PasswordController@getEmail'));
@ -179,7 +179,7 @@ Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function()
Route::resource('invoices', 'InvoiceApiController');
Route::resource('quotes', 'QuoteApiController');
Route::resource('payments', 'PaymentApiController');
Route::post('api/hooks', 'IntegrationController@subscribe');
Route::post('hooks', 'IntegrationController@subscribe');
Route::post('email_invoice', 'InvoiceApiController@emailInvoice');
});
@ -287,6 +287,7 @@ define('RANDOM_KEY_LENGTH', 32);
define('MAX_NUM_CLIENTS', 500);
define('MAX_NUM_CLIENTS_PRO', 20000);
define('MAX_NUM_USERS', 20);
define('MAX_SUBDOMAIN_LENGTH', 30);
define('INVOICE_STATUS_DRAFT', 1);
define('INVOICE_STATUS_SENT', 2);

View File

@ -3,6 +3,7 @@
use Eloquent;
use Utils;
use Session;
use DateTime;
use Illuminate\Database\Eloquent\SoftDeletes;

View File

@ -29,6 +29,13 @@ class Invitation extends EntityModel
public function getLink()
{
return SITE_URL.'/view/'.$this->invitation_key;
$this->load('account');
$url = SITE_URL;
if ($this->account->subdomain) {
$url = str_replace(['://www', '://'], "://{$this->account->subdomain}.", $url);
}
return "{$url}/view/{$this->invitation_key}";
}
}

152
composer.lock generated
View File

@ -120,12 +120,12 @@
"source": {
"type": "git",
"url": "https://github.com/formers/former.git",
"reference": "ed7d00c2b11578a4db31531e1fee97f6ccd85030"
"reference": "4a03cdd08f1bdd975bd2521bed74ab38bf590388"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/formers/former/zipball/ed7d00c2b11578a4db31531e1fee97f6ccd85030",
"reference": "ed7d00c2b11578a4db31531e1fee97f6ccd85030",
"url": "https://api.github.com/repos/formers/former/zipball/4a03cdd08f1bdd975bd2521bed74ab38bf590388",
"reference": "4a03cdd08f1bdd975bd2521bed74ab38bf590388",
"shasum": ""
},
"require": {
@ -171,7 +171,7 @@
"foundation",
"laravel"
],
"time": "2015-03-06 17:50:05"
"time": "2015-04-20 13:53:18"
},
{
"name": "anahkiasen/html-object",
@ -335,12 +335,12 @@
"source": {
"type": "git",
"url": "https://github.com/Chumper/Datatable.git",
"reference": "bdd90cbe65b3544761f69ea199a1b9591770f3fc"
"reference": "7fa47cb5469f07c620fb69dee94b8e1a96943ee2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Chumper/Datatable/zipball/bdd90cbe65b3544761f69ea199a1b9591770f3fc",
"reference": "bdd90cbe65b3544761f69ea199a1b9591770f3fc",
"url": "https://api.github.com/repos/Chumper/Datatable/zipball/7fa47cb5469f07c620fb69dee94b8e1a96943ee2",
"reference": "7fa47cb5469f07c620fb69dee94b8e1a96943ee2",
"shasum": ""
},
"require": {
@ -380,24 +380,24 @@
"jquery",
"laravel"
],
"time": "2015-04-08 12:11:23"
"time": "2015-04-20 09:21:21"
},
{
"name": "classpreloader/classpreloader",
"version": "1.2.0",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/ClassPreloader/ClassPreloader.git",
"reference": "f0bfbf71fb3335c9473f695d4d966ba2fb879a9f"
"reference": "0544616ba33fb2a6b792b3a7822650810c6d65d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/f0bfbf71fb3335c9473f695d4d966ba2fb879a9f",
"reference": "f0bfbf71fb3335c9473f695d4d966ba2fb879a9f",
"url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/0544616ba33fb2a6b792b3a7822650810c6d65d9",
"reference": "0544616ba33fb2a6b792b3a7822650810c6d65d9",
"shasum": ""
},
"require": {
"nikic/php-parser": "~1.0",
"nikic/php-parser": "^1.2.2",
"php": ">=5.3.3",
"symfony/console": "~2.1",
"symfony/filesystem": "~2.1",
@ -412,7 +412,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
"dev-master": "1.3-dev"
}
},
"autoload": {
@ -440,7 +440,7 @@
"class",
"preload"
],
"time": "2015-01-26 22:06:19"
"time": "2015-04-15 21:59:30"
},
{
"name": "coatesap/omnipay-datacash",
@ -702,16 +702,16 @@
},
{
"name": "doctrine/annotations",
"version": "v1.2.3",
"version": "v1.2.4",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "eeda578cbe24a170331a1cfdf78be723412df7a4"
"reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/eeda578cbe24a170331a1cfdf78be723412df7a4",
"reference": "eeda578cbe24a170331a1cfdf78be723412df7a4",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/b5202eb9e83f8db52e0e58867e0a46e63be8332e",
"reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e",
"shasum": ""
},
"require": {
@ -766,20 +766,20 @@
"docblock",
"parser"
],
"time": "2014-12-20 20:49:38"
"time": "2014-12-23 22:40:37"
},
{
"name": "doctrine/cache",
"version": "v1.4.0",
"version": "v1.4.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "2346085d2b027b233ae1d5de59b07440b9f288c8"
"reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/2346085d2b027b233ae1d5de59b07440b9f288c8",
"reference": "2346085d2b027b233ae1d5de59b07440b9f288c8",
"url": "https://api.github.com/repos/doctrine/cache/zipball/c9eadeb743ac6199f7eec423cb9426bc518b7b03",
"reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03",
"shasum": ""
},
"require": {
@ -790,13 +790,13 @@
},
"require-dev": {
"phpunit/phpunit": ">=3.7",
"predis/predis": "~0.8",
"predis/predis": "~1.0",
"satooshi/php-coveralls": "~0.6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
"dev-master": "1.5.x-dev"
}
},
"autoload": {
@ -836,25 +836,28 @@
"cache",
"caching"
],
"time": "2015-01-15 20:38:55"
"time": "2015-04-15 00:11:59"
},
{
"name": "doctrine/collections",
"version": "v1.2",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/collections.git",
"reference": "b99c5c46c87126201899afe88ec490a25eedd6a2"
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/collections/zipball/b99c5c46c87126201899afe88ec490a25eedd6a2",
"reference": "b99c5c46c87126201899afe88ec490a25eedd6a2",
"url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
@ -871,17 +874,6 @@
"MIT"
],
"authors": [
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com",
"homepage": "http://www.jwage.com/",
"role": "Creator"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com",
"homepage": "http://www.instaclick.com"
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@ -890,11 +882,17 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com",
"homepage": "https://github.com/schmittjoh",
"role": "Developer of wrapped JMSSerializerBundle"
"email": "schmittjoh@gmail.com"
}
],
"description": "Collections Abstraction library",
@ -904,7 +902,7 @@
"collections",
"iterator"
],
"time": "2014-02-03 23:07:43"
"time": "2015-04-14 22:21:58"
},
{
"name": "doctrine/common",
@ -1374,12 +1372,12 @@
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
"reference": "7edc830d19733a40afae5641aabf0acf6be1961b"
"reference": "6626d7624ac0895137a38c123943afedd0827efc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/7edc830d19733a40afae5641aabf0acf6be1961b",
"reference": "7edc830d19733a40afae5641aabf0acf6be1961b",
"url": "https://api.github.com/repos/Intervention/image/zipball/6626d7624ac0895137a38c123943afedd0827efc",
"reference": "6626d7624ac0895137a38c123943afedd0827efc",
"shasum": ""
},
"require": {
@ -1422,7 +1420,7 @@
"thumbnail",
"watermark"
],
"time": "2015-04-08 17:43:59"
"time": "2015-04-24 14:50:48"
},
{
"name": "ircmaxell/password-compat",
@ -1652,16 +1650,16 @@
},
{
"name": "laravel/framework",
"version": "v5.0.27",
"version": "v5.0.28",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "4d6330118a295086ce9ff8eed2200d5b67f17688"
"reference": "06a09429322cf53e5bd4587db1060f02a291562e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/4d6330118a295086ce9ff8eed2200d5b67f17688",
"reference": "4d6330118a295086ce9ff8eed2200d5b67f17688",
"url": "https://api.github.com/repos/laravel/framework/zipball/06a09429322cf53e5bd4587db1060f02a291562e",
"reference": "06a09429322cf53e5bd4587db1060f02a291562e",
"shasum": ""
},
"require": {
@ -1731,7 +1729,7 @@
"predis/predis": "~1.0"
},
"suggest": {
"aws/aws-sdk-php": "Required to use the SQS queue driver (~2.4).",
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~2.4).",
"doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).",
"guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers (~5.0).",
"iron-io/iron_mq": "Required to use the iron queue driver (~1.5).",
@ -1774,7 +1772,7 @@
"framework",
"laravel"
],
"time": "2015-04-04 01:34:57"
"time": "2015-04-21 01:44:32"
},
{
"name": "league/flysystem",
@ -1966,16 +1964,16 @@
},
{
"name": "mfauveau/omnipay-pacnet",
"version": "2.0.0",
"version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/mfauveau/omnipay-pacnet.git",
"reference": "84201b2d216c8327f1cba379e123abb5e09b0f74"
"reference": "58465c6d6b579d1e2022d4f6cc5d75ed4905f2bd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mfauveau/omnipay-pacnet/zipball/84201b2d216c8327f1cba379e123abb5e09b0f74",
"reference": "84201b2d216c8327f1cba379e123abb5e09b0f74",
"url": "https://api.github.com/repos/mfauveau/omnipay-pacnet/zipball/58465c6d6b579d1e2022d4f6cc5d75ed4905f2bd",
"reference": "58465c6d6b579d1e2022d4f6cc5d75ed4905f2bd",
"shasum": ""
},
"require": {
@ -2017,7 +2015,7 @@
"purchase",
"raven"
],
"time": "2014-08-19 18:50:39"
"time": "2015-04-17 01:14:08"
},
{
"name": "monolog/monolog",
@ -3494,16 +3492,16 @@
},
{
"name": "omnipay/paymentexpress",
"version": "v2.1.1",
"version": "v2.1.2",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-paymentexpress.git",
"reference": "a6309569a4a4372fe1c9cb464ff2ef57101df46d"
"reference": "bd417f02bacb2128c168956739cd3a902d3ee48c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-paymentexpress/zipball/a6309569a4a4372fe1c9cb464ff2ef57101df46d",
"reference": "a6309569a4a4372fe1c9cb464ff2ef57101df46d",
"url": "https://api.github.com/repos/thephpleague/omnipay-paymentexpress/zipball/bd417f02bacb2128c168956739cd3a902d3ee48c",
"reference": "bd417f02bacb2128c168956739cd3a902d3ee48c",
"shasum": ""
},
"require": {
@ -3553,7 +3551,7 @@
"pxpay",
"pxpost"
],
"time": "2014-09-17 00:37:09"
"time": "2015-04-03 00:20:28"
},
{
"name": "omnipay/paypal",
@ -5235,23 +5233,23 @@
},
{
"name": "phpspec/phpspec",
"version": "2.1.1",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/phpspec.git",
"reference": "66a1df93099282b1514e9e001fcf6e9393f7783d"
"reference": "9727d75919a00455433e867565bc022f0b985a39"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/66a1df93099282b1514e9e001fcf6e9393f7783d",
"reference": "66a1df93099282b1514e9e001fcf6e9393f7783d",
"url": "https://api.github.com/repos/phpspec/phpspec/zipball/9727d75919a00455433e867565bc022f0b985a39",
"reference": "9727d75919a00455433e867565bc022f0b985a39",
"shasum": ""
},
"require": {
"doctrine/instantiator": "~1.0,>=1.0.1",
"doctrine/instantiator": "^1.0.1",
"php": ">=5.3.3",
"phpspec/php-diff": "~1.0.0",
"phpspec/prophecy": "~1.1",
"phpspec/prophecy": "~1.4",
"sebastian/exporter": "~1.0",
"symfony/console": "~2.3",
"symfony/event-dispatcher": "~2.1",
@ -5260,9 +5258,11 @@
"symfony/yaml": "~2.1"
},
"require-dev": {
"behat/behat": "~3.0,>=3.0.11",
"behat/behat": "^3.0.11",
"bossa/phpspec2-expect": "~1.0",
"symfony/filesystem": "~2.1"
"phpunit/phpunit": "~4.4",
"symfony/filesystem": "~2.1",
"symfony/process": "~2.1"
},
"suggest": {
"phpspec/nyan-formatters": "~1.0 Adds Nyan formatters"
@ -5273,7 +5273,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1.x-dev"
"dev-master": "2.2.x-dev"
}
},
"autoload": {
@ -5307,7 +5307,7 @@
"testing",
"tests"
],
"time": "2015-01-09 13:21:45"
"time": "2015-04-18 16:22:51"
},
{
"name": "phpspec/prophecy",

View File

@ -15,6 +15,8 @@ class AddSvLanguage extends Migration {
DB::table('languages')->insert(['name' => 'Swedish', 'locale' => 'sv']);
DB::table('languages')->insert(['name' => 'Spanish - Spain', 'locale' => 'es_ES']);
DB::table('languages')->insert(['name' => 'French - Canada', 'locale' => 'fr_CA']);
DB::table('payment_terms')->insert(['num_days' => -1, 'name' => 'Net 0']);
}
/**
@ -35,6 +37,10 @@ class AddSvLanguage extends Migration {
if ($language = \App\Models\Language::whereLocale('fr_CA')->first()) {
$language->delete();
}
if ($paymentTerm = \App\Models\PaymentTerm::whereName('Net 0')->first()) {
$paymentTerm->delete();
}
}
}

View File

@ -21,6 +21,7 @@ class AddPartialAmountToInvoices extends Migration {
{
$table->boolean('utf8_invoices')->default(false);
$table->boolean('auto_wrap')->default(true);
$table->string('subdomain')->nullable();
});
}
@ -40,6 +41,7 @@ class AddPartialAmountToInvoices extends Migration {
{
$table->dropColumn('utf8_invoices');
$table->dropColumn('auto_wrap');
$table->dropColumn('subdomain');
});
}

View File

@ -103,14 +103,14 @@ class ConstantsSeeder extends Seeder
Size::create(array('name' => '101 - 500'));
Size::create(array('name' => '500+'));
PaymentTerm::create(array('num_days' => 7, 'name' => 'Net 7'));
PaymentTerm::create(array('num_days' => 7, 'name' => 'Net 7'));
PaymentTerm::create(array('num_days' => 10, 'name' => 'Net 10'));
PaymentTerm::create(array('num_days' => 14, 'name' => 'Net 14'));
PaymentTerm::create(array('num_days' => 15, 'name' => 'Net 15'));
PaymentTerm::create(array('num_days' => 30, 'name' => 'Net 30'));
PaymentTerm::create(array('num_days' => 60, 'name' => 'Net 60'));
PaymentTerm::create(array('num_days' => 90, 'name' => 'Net 90'));
Currency::create(array('name' => 'US Dollar', 'code' => 'USD', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'));
Currency::create(array('name' => 'Pound Sterling', 'code' => 'GBP', 'symbol' => '£', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'));
Currency::create(array('name' => 'Euro', 'code' => 'EUR', 'symbol' => '€', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'));

796
public/css/built.css vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -852,4 +852,13 @@ div.checkbox > label {
position: absolute;
margin-left: 25%;
z-index: 9999;
}
.dataTables_length {
padding-left: 20px;
padding-top: 8px;
}
.dataTables_length label {
font-weight: 500;
}

File diff suppressed because one or more lines are too long

View File

@ -633,5 +633,9 @@ return array(
'year_price' => '$50<span> /Year</span>',
],
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
'subdomain' => 'Subdomain',
);

View File

@ -1,209 +0,0 @@
<?php
return [
'title' => 'Facturation en ligne libre',
'description' => 'Invoice Ninja est une solution libre pour la tenue de comptes clients et leur facturation. Avec Invoice Ninja, vous pouvez facilement créer et envoyer de belles factures de n\'importe quel dispositif connecté au web. Vos clients peuvent imprimer leurs factures, les télécharger au format PDF, et même vous payer directement en ligne.',
'invoice_now' => 'Facturer maintenant',
'no_signup_needed' => 'Sans inscription',
'link_blog' => 'Carnet',
'link_about_us' => 'À propos',
'link_contact_us' => 'Contactez-nous',
'link_features' => 'Fonctionalités',
'link_plans' => 'Plans',
'link_compare' => 'Comparer',
'link_testimonials' => 'Témoignages',
'link_faq' => 'FAQ',
'my_account' => 'Mon compte',
'login' => 'Inscription',
'connect_with_us' => 'Connectez avec nous',
'safe_and_secure' => 'Sécuritaire',
'toggle_navigation' => 'Changer de navigation',
'home' => [
'header' => 'THE <span style="color:#2299c0">SIMPLE</span> &amp; <span style="color:#edd71e">FREE</span> WAY TO INVOICE CLIENTS',
'sub_header' => 'It\'s just that easy. Stop spending time on complicated and expensive invoicing.<br>No fuss, just get started and get paid.',
'footer' => '<span>Simple, Intuitive Invoicing,</span>Anywhere.',
'free_always' => 'Gratuit. Toujours.',
'free_always_text' => 'Send unlimited invoices to 500 clients per month and never pay a dime. You are welcome to unlock still more awesome features with our Pro Plan, but our free app is a top-notch product that will do everything you need it to do, without any subscription or fees.',
'open_source' => 'Logiciel libre',
'open_source_text' => 'No mysterious corporate silos here! Just full <a href="https://github.com/hillelcoren/invoice-ninja" target="_blank">source code</a> transparency and a devotion to working with anyone interested to build a better electronic invoicing platform. We even offer a handy <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">zip download</a> for a self-hosted version of Invoice Ninja.',
'live_pdf' => 'Aperçu PDF en ligne',
'live_pdf_text' => 'See how your edited invoice will look as a print-friendly pdf while you make the changes. Our pdf generator works in real time as you make your changes. You can even preview four beautiful preset designs. Just create, save, send, and youre done!',
'online_payments' => 'Paiements en ligne',
'online_payments_text' => 'Invoices sent with our app integrate seamlessly with the gateway credit card processor of your choice, to make it super easy for your clients to send you money with just a few clicks. We play nicely with Authorize.Net, Stripe, PayPal and loads more - 23 in all!',
],
'about' => [
'header' => '<span class="thin">About</span> Invoice Ninja',
'what_is' => 'Qu\'est-ce qu\'Invoice Ninja?',
'team_ninja' => 'L\'équipe Ninja',
'team_ninja_text' => 'Invoice Ninja is managed by a team of seasoned web workers. We launched in early 2014 and have been thrilled by the enthusiastic response weve received from our growing community of users.',
'co_founder' => 'Co-Founder',
'ceo' => 'CEO',
'cto' => '',
'designer' => 'Designer',
'marketing' => 'Marketing',
'shalom_bio' => 'Shalom has specialized in small business development for nearly 10 years. In addition to InvoiceNinja.com Shalom is CEO of a leading tour agency in Israel.',
'hillel_bio' => 'Hillel has been developing enterprise applications for 15 years. His open-source <a href="http://hillelcoren.com/flex-autocomplete/" target="_blank">AutoComplete</a> component has been used by thousands of developers around the world.',
'razi_bio' => 'Razi is a pixel nerd with a great deal of experience in design for web sites and applications. When she isn\'t busy with InvoiceNinja she runs a small web agency in Stockholm called kantorp-wegl.in',
'ben_bio' => 'A veteran digital marketer and content strategist, Ben specializes in building communities around brands that make business easier for freelancers, SMBs and micro-entrepreneurs.',
],
'contact' => [
'header' => 'Questions, demandes spéciales, ou simples salutations?',
'sub_header' => 'Complétez ce formulaire et nous répondrons dans les meilleurs délais. On espère vous lire!',
'other_ways' => 'D\'autres manières de nous contacter',
'name' => 'Nom',
'name_help' => 'Votre nom.',
'email' => 'Courriel',
'email_help' => 'Votre adresse de courriel.',
'message' => 'Message',
'message_help' => 'Votre message.',
'send_message' => 'Envoyer',
],
'features' => [
'header' => '<span class="thin">The</span> Features',
'footer' => 'Like what you see?',
'footer_action' => 'Get started today!',
'open_source' => 'Open Source Platform',
'open_source_text1' => 'Set the code free! Here at Invoice Ninja, were all about creating the best possible app, and inviting scrutiny via full code transparency is a central manifestation of this value.',
'open_source_text2' => 'We firmly believe that being an open source product helps everyone involved. Were looking forward to seeing what the developers out there can do to take Invoice Ninja into new realms of usefulness.',
'free_forever' => 'FREE. Forever.',
'free_forever_text1' => 'Yeah, you read that correctly. You dont have to pay us a cent to use our tools. We know how tough it is to make ends meet as a web-based business, and were bent on providing a top-notch product that will do everything you need it to do, without any subscription or opt-in fees.',
'free_forever_text2' => 'Try Invoice Ninja out. You literally have nothing to lose. Were confident that youll find the experience so positive that youll never need to turn elsewhere.',
'secure' => 'Secure & Private',
'secure_text1' => 'Invoice Ninja has been built from the ground up to keep your data safe. Only you have access to your login & accounting details, & we will never share your transaction data to any third party.',
'secure_text2' => 'Our website operates with 256-bit encryption, which is even more secure than most banking websites. Invoice Ninja uses the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. We feel safe here and have invested heavily in measures to ensure that you do too.',
'live_pdf' => 'Live .PDF View',
'live_pdf_text1' => 'With Invoice Ninja, weve done away with the need for cumbersome multi-click invoice previewing after each save.',
'live_pdf_text2' => 'When you enter the details of your customer and/or invoice in our editor, you can instantly see the results in the pdf preview pane below. Want to see what your invoice would look like in a different layout style? The live pdf can show you four beautiful preset styles in real time too.',
'live_pdf_text3' => 'Just create, save, send, and youre done!',
'online_payments' => 'Online Payments',
'online_payments_text1' => 'Invoice Ninja seamlessly integrates with all of the top internet payment processors and gateways so you can get paid for your work quickly and easily.',
'online_payments_text2' => 'Invoices created with our tools arent just for bookkeeping purposes - they bring in the Benjamins. We also make it super easy to choose the right gateway for the specific needs of your business and are happy to help you to get started working with the gateway of your choice. Whats more, were constantly working on rolling out additional gateway integrations, so if you dont see the one you use here, just let us know, and theres a good chance well add it for you.',
],
'plans' => [
'header' => '<span class="thin">The</span> Plans',
'free' => 'Free',
'unlimited' => 'Unlimited',
'pro_plan' => 'Pro Plan',
'go_pro' => 'Go Pro to Unlock Premium Invoice Ninja Features',
'go_pro_text' => 'We believe that the free version of Invoice Ninja is a truly awesome product loaded with the key features you need to bill your clients electronically. But for those who crave still more Ninja awesomeness, we\'ve unmasked the Invoice Ninja Pro plan, which offers more versatility, power and customization options for just $50 per year.',
'number_clients' => 'Number of clients per account',
'unlimited_invoices' => 'Unlimited client invoices',
'company_logo' => 'Add your company logo',
'live_pdf' => 'Live .PDF invoice creation',
'four_templates' => '4 beautiful invoice templates',
'payments' => 'Accept credit card payments',
'additional_templates' => 'Additional invoice templates',
'multi_user' => 'Multi-user support',
'quotes' => 'Quotes/pro-forma invoices',
'advanced_settings' => 'Advanced invoice settings',
'data_vizualizations' => 'Dynamic data vizualizations',
'email_support' => 'Priority email support',
'remove_created_by' => 'Remove "Created by Invoice Ninja"',
'latest_features' => 'Latest and greatest features',
'pricing' => 'Pricing',
'free_always' => 'Free<span> /Always!</span>',
'year_price' => '$50<span> /Year</span>',
],
'compare' => [
'header' => '<span class="thin">How We</span> Compare',
'free_plan_comparison' => 'Free Plan Comparison',
'paid_plan_comparison' => 'Paid Plan Comparison',
'app' => 'App',
'cost' => 'Cost',
'clients' => 'Clients',
'invoices' => 'Invoices',
'payment_gateways' => 'Payment Gateways',
'custom_logo' => 'Custom Logo',
'multiple_templates' => 'Multiple Templates',
'recurring_payments' => 'Recurring Payments',
'open_source' => 'Open Source',
'per_month' => 'per month',
'per_year' => 'per year',
'free' => 'Free',
'unlimited' => 'Unlimited',
],
'testimonials' => [
'testimonials' => 'testimonials',
'header' => 'Since we launched Invoice Ninja in March of 2014, we\'ve been overwhelmed by a deluge of user love. Here\'s a small taste of the glowing things people have to say about the great experiences the\'ve been having with our free e-invoicing app!',
],
'faq' => [
'header' => '<span class="thin">The</span> FAQs',
'question1' => 'I know it isnt standard ninja practice to reveal too many identity details, but who are you guys exactly?',
'answer1' => 'Were a small team of highly skilled digital journeymen based in Israel. We love open source, we love disrupting the big business status quo, and we love building helpful tools that are easy to use. We believe that everyone elses web-based cash flow tools are unnecessarily expensive, clunky and complicated - and were bent on proving these beliefs with Invoice Ninja.',
'question2' => 'How do I get started using Invoice Ninja?',
'answer2' => 'Just click on the big, yellow "Invoice Now" button on our homepage!',
'question3' => 'Do you offer customer support?',
'answer3' => 'We sure do. Support is super important to us. Feel free to email us at <a href="mailto:support@invoiceninja.com">support@invoiceninja.com</a> with any questions you might have. We almost always reply within one business day.',
'question4' => 'Is Invoice Ninja really free? For how long?',
'answer4' => 'Yes, our basic app is 100% free. Forever and ever. For real. We also offer a paid Pro version of Invoice Ninja (you can learn all about its awesome features <a href="https://www.invoiceninja.com/plans">here</a>), but it\'s important to us that the free version have all of the key features people need to do business.',
'question5' => 'How is Invoice Ninja able to offer this all for free? How are you making any money?',
'answer5' => 'Were mostly in this line of work because we believe its high time that a good electronic invoicing tool be available for free. There isnt much money in it - yet. We do offer a paid <a href="https://www.invoiceninja.com/plans">Pro </a> version of the app that we\'ve souped up with premium features. And when our users open up new accounts with payment processor gateways by clicking on links from our site, we make modest commissions as a gateway affiliate. So if zillions of freelancers and small businesses start running credit card charges through Invoice Ninja, or if scores of users go <a href="https://www.invoiceninja.com/plans">Pro</a>, theres a decent chance we\'ll recover our investment.',
'question6' => 'Really? So does that mean youre not collecting information about me so you can sell me stuff or so that some other company can spam me according to my interests?',
'answer6' => 'No way. Were not mining your data, and were not selling you out. That wouldnt be very ninja of us, would it?',
'question7' => 'But dont you have access to my merchant and banking accounts?',
'answer7' => 'Actually, we dont. When you link an account at a third party financial institution with your Invoice Ninja account, youre essentially giving our app permission to send money to you and nothing more. This is all managed by the tech teams at your financial service providers, who go to great lengths to ensure their integrations cant be exploited or abused.',
'question8' => 'Given that Invoice Ninja is an open source app, how can I be sure that my financial information is safe with you?',
'answer8' => 'There\'s a big difference between “open source" and “open data.” Anyone who wants to use the code that drives Invoice Ninja to create their own products or to make improvements to ours can do so. Its available for anyone who wants to download and work with. But thats just the source code - totally separate from what happens with that code on the Invoice Ninja servers. Youre the only one who has full access to what you\'re doing with our product. For more details on the security of our servers and how we handle our users\' information, please read the next question.',
'question9' => 'So just how secure is this app?',
'answer9' => 'Extremely. Data uploaded by our users runs through connections with 256-bit encryption, which is twice as many encryption bits that most bank websites use. We use the TLS 1.0 cryptographic protocol, AES_256_CBC string encryption, SHA1 message authentication and DHE_RSA key exchanges. Its fancy stuff that we put in place to make sure no one can gain access to your information except you.',
'question10' => 'How do I remove the small "Created by Invoice Ninja” image from the bottom of my invoices?',
'answer10' => 'The amazingly affordable <a href="https://www.invoiceninja.com/plans">Pro</a> version of Invoice Ninja allows you to do this and oh so much more.',
'question11' => 'Can I see what the application looks like with sample data?',
'answer11' => 'Sure, <a href="https://www.invoiceninja.com/demo">click here</a> to try out our demo account.',
'question12' => 'I hear that there\'s a version of Invoice Ninja that I can install myself on my own servers? Where can I learn more about this?',
'answer12' => 'The rumors are true! Full instructions are available <a href="http://hillelcoren.com/invoice-ninja/self-hosting/" target="_blank">here</a>.',
'question13' => 'I\'m seeing the options to assign various statuses to my invoices, clients, credits and payments. What\'s the difference between "active," "archived" and "deleted"?',
'answer13' => 'These three handy statuses for invoices, clients, credits and payments allow you to keep your own cash flow management as straightforward and accessible as possible from your Invoice Ninja dashboard. None of these statuses will actually purge any records from your account - even "deleted" can always be recovered at any point in the future. "Active" means the record will appear in the relevant queue of records. To stash a record away so it\'s still fully operational but no longer cluttering up your interface, simply set it to be "archived." To deactivate a record and render it inaccessible to your clients, mark it "deleted."',
'question14' => 'My question wasn\'t covered by any of the content on this FAQ page. How can I get in touch with you?',
'answer14' => 'Please email us at <a href="mailto:contact@invoiceninja.com">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
'miss_something' => 'Did we miss something?',
'miss_something_text' => 'Please email us at <a href="mailto:contact@invoiceninja.com" style="font-weight: bold">contact@invoiceninja.com</a> with any questions or comments you have. We love hearing from the people who use our app! Well do our best to reply to your email within the business day.',
],
];

View File

@ -34,6 +34,12 @@
<div class="panel-body">
{!! Former::text('name') !!}
@if (Auth::user()->isPro())
{{ Former::setOption('capitalize_translations', false) }}
{!! Former::text('subdomain')->placeholder('texts.www')->onchange('onSubdomainChange()') !!}
@endif
{!! Former::text('id_number') !!}
{!! Former::text('vat_number') !!}
{!! Former::text('work_email') !!}
@ -273,6 +279,14 @@
});
}
function onSubdomainChange() {
var input = $('#subdomain');
var val = input.val();
if (!val) return;
val = val.replace(/[^a-zA-Z0-9_\-]/g, '').toLowerCase().substring(0, {{ MAX_SUBDOMAIN_LENGTH }});
input.val(val);
}
</script>

View File

@ -3,8 +3,13 @@
@section('content')
@parent
{{ Former::open('company/import_export')->addClass('warn-on-exit') }}
{{ Former::legend('import_clients') }}
{!! Former::open('company/import_export')->addClass('col-md-8 col-md-offset-2 warn-on-exit') !!}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{!! trans('texts.import_clients') !!}</h3>
</div>
<div class="panel-body">
@if ($headers)
@ -12,7 +17,9 @@
<input type="checkbox" name="header_checkbox" id="header_checkbox" {{ $hasHeaders ? 'CHECKED' : '' }}> {{ trans('texts.first_row_headers') }}
</label>
<table class="table">
<p>&nbsp;</p>
<table class="table invoice-table">
<thead>
<tr>
<th>{{ trans('texts.column') }}</th>
@ -24,17 +31,24 @@
<tr>
<td>{{ $headers[$i] }}</td>
<td class="col_sample">{{ $data[1][$i] }}</td>
<td>{{ Former::select('map[' . $i . ']')->options($columns, $mapped[$i], true)->raw() }}</td>
<td>{!! Former::select('map[' . $i . ']')->options($columns, $mapped[$i], true)->raw() !!}</td>
</tr>
@endfor
</table>
<p>&nbsp;</p>
<span id="numClients"></span>
@endif
</div>
</div>
{{ Former::actions( Button::lg_primary_submit(trans('texts.import')), '&nbsp;|&nbsp;', link_to('company/import', trans('texts.cancel')) ) }}
{{ Former::close() }}
{!! Former::actions(
Button::success(trans('texts.import'))->submit()->large()->appendIcon(Icon::create('floppy-disk')),
Button::normal(trans('texts.cancel'))->large()->asLinkTo('/company/import_export')->appendIcon(Icon::create('remove-circle'))) !!}
{!! Former::close() !!}
<script type="text/javascript">

View File

@ -1 +1 @@
The requested invoice is no longer available.
The requested invoice is not available.

View File

@ -458,7 +458,7 @@
->fromQuery($currencies, 'name', 'id') !!}
<span data-bind="visible: $root.showMore">
{!! Former::select('payment_terms')->addOption('','0')->data_bind('value: payment_terms')
{!! Former::select('payment_terms')->addOption('','')->data_bind('value: payment_terms')
->fromQuery($paymentTerms, 'name', 'num_days') !!}
{!! Former::select('size_id')->addOption('','')->data_bind('value: size_id')
->fromQuery($sizes, 'name', 'id') !!}
@ -901,9 +901,11 @@
self.setDueDate = function() {
@if ($entityType == ENTITY_INVOICE)
var paymentTerms = parseInt(self.invoice().client().payment_terms());
if (paymentTerms && !self.invoice().due_date())
var paymentTerms = parseInt(self.invoice().client().payment_terms());
if (paymentTerms && paymentTerms != 0 && !self.invoice().due_date())
{
console.log("here");
if (paymentTerms == -1) paymentTerms = 0;
var dueDate = $('#invoice_date').datepicker('getDate');
dueDate.setDate(dueDate.getDate() + paymentTerms);
self.invoice().due_date(dueDate);

View File

@ -37,6 +37,7 @@
->addColumn($columns)
->setUrl(route('api.' . $entityType . 's'))
->setOptions('sPaginationType', 'bootstrap')
->setOptions('aaSorting', [[isset($sortCol) ? $sortCol : '1', 'desc']])
->render('datatable') !!}
{!! Former::close() !!}

View File

@ -44,12 +44,12 @@
/* Set the defaults for DataTables initialisation */
$.extend( true, $.fn.dataTable.defaults, {
"bSortClasses": false,
"sDom": "t<'row-fluid'<'span6'i><'span6'p>>",
"sDom": "t<'row-fluid'<'span6'i><'span6'p>>l",
"sPaginationType": "bootstrap",
"bInfo": true,
"oLanguage": {
'sEmptyTable': "{{ trans('texts.empty_table') }}",
'sLengthMenu': '_MENU_',
'sLengthMenu': '_MENU_ {{ trans('texts.rows') }}',
'sSearch': ''
}
} );

View File

@ -25,12 +25,28 @@ body {
background: #f9f9f9;
border: 1px solid #ebe7e7;
border-radius: 3px;
margin: 6px 0 6px 0;
font-size: 16px;
min-height: 42px !important;
font-weight: 400;
}
div.col-md-3,
div.col-md-5,
div.col-md-6,
div.col-md-7,
div.col-md-9,
div.col-md-12 {
margin: 6px 0 6px 0;
}
span.dropdown-toggle {
border-color: #ebe7e7;
}
.dropdown-toggle {
margin: 0px !important;
}
.container input[placeholder],
.container select[placeholder] {
color: #444444;
@ -128,7 +144,7 @@ header h3 em {
'city' => 'required',
'state' => 'required',
'postal_code' => 'required',
'country' => 'required',
'country_id' => 'required',
'phone' => 'required',
'email' => 'required|email'
)) !!}
@ -137,6 +153,9 @@ header h3 em {
{{ Former::populate($client) }}
{{ Former::populateField('first_name', $contact->first_name) }}
{{ Former::populateField('last_name', $contact->last_name) }}
@if (!$client->country_id && $client->account->country_id)
{{ Former::populateField('country_id', $client->account->country_id) }}
@endif
@endif
<div class="container">
@ -190,24 +209,27 @@ header h3 em {
<h3>{{ trans('texts.billing_address') }} &nbsp;<span class="help">{{ trans('texts.payment_footer1') }}</span></h3>
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
{!! Former::text('address1')->placeholder(trans('texts.address1'))->raw() !!}
</div>
</div>
<div class="row">
<div class="col-md-6">
{!! Former::text('address2')->placeholder(trans('texts.address2'))->raw() !!}
</div>
</div>
<div class="row">
<div class="col-md-6">
{!! Former::text('city')->placeholder(trans('texts.city'))->raw() !!}
</div>
<div class="col-md-6">
{!! Former::text('state')->placeholder(trans('texts.state'))->raw() !!}
</div>
</div>
<div class="row">
<div class="col-md-6">
{!! Former::text('state')->placeholder(trans('texts.state'))->raw() !!}
{!! Former::text('postal_code')->placeholder(trans('texts.postal_code'))->raw() !!}
</div>
<div class="col-md-6">
{!! Former::text('postal_code')->placeholder(trans('texts.postal_code'))->raw() !!}
{!! Former::select('country_id')->placeholder(trans('texts.country_id'))->fromQuery($countries, 'name', 'id')->raw() !!}
</div>
</div>
@ -316,6 +338,8 @@ header h3 em {
$('select').change(function() {
$(this).css({color:'#444444'});
});
$('#country_id').combobox();
});
</script>

View File

@ -93,6 +93,15 @@ table.table thead .sorting_desc:after { content: '' !important}
table.table thead .sorting_asc_disabled:after { content: '' !important }
table.table thead .sorting_desc_disabled:after { content: '' !important }
.dataTables_length {
padding-left: 20px;
padding-top: 8px;
}
.dataTables_length label {
font-weight: 500;
}
@media screen and (min-width: 700px) {
#footer .top {
padding: 27px 0;