diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 45500006703c..d8402d4a1496 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -12,6 +12,7 @@ use Validator; use View; use stdClass; use Cache; +use Response; use App\Models\User; use App\Models\Activity; diff --git a/app/Http/Controllers/AccountGatewayController.php b/app/Http/Controllers/AccountGatewayController.php index cce6922350cb..29002f8727b1 100644 --- a/app/Http/Controllers/AccountGatewayController.php +++ b/app/Http/Controllers/AccountGatewayController.php @@ -70,6 +70,8 @@ class AccountGatewayController extends BaseController $data['title'] = trans('texts.edit_gateway') . ' - ' . $accountGateway->gateway->name; $data['config'] = $configFields; $data['paymentTypeId'] = $accountGateway->getPaymentType(); + $data['selectGateways'] = Gateway::where('id', '=', $accountGateway->gateway_id)->get(); + return View::make('accounts.account_gateway', $data); } @@ -94,6 +96,7 @@ class AccountGatewayController extends BaseController $data['url'] = 'gateways'; $data['method'] = 'POST'; $data['title'] = trans('texts.add_gateway'); + $data['selectGateways'] = Gateway::where('payment_library_id', '=', 1)->where('id', '!=', GATEWAY_PAYPAL_EXPRESS)->where('id', '!=', GATEWAY_PAYPAL_EXPRESS)->orderBy('name')->get(); return View::make('accounts.account_gateway', $data); } @@ -127,7 +130,6 @@ class AccountGatewayController extends BaseController $account->load('account_gateways'); $currentGateways = $account->account_gateways; $gateways = Gateway::where('payment_library_id', '=', 1)->orderBy('name')->get(); - $selectGateways = Gateway::where('payment_library_id', '=', 1)->where('id', '!=', GATEWAY_PAYPAL_EXPRESS)->where('id', '!=', GATEWAY_PAYPAL_EXPRESS)->orderBy('name')->get(); foreach ($gateways as $gateway) { $gateway->fields = $gateway->getFields(); @@ -147,7 +149,6 @@ class AccountGatewayController extends BaseController 'accountGateway' => $accountGateway, 'config' => false, 'gateways' => $gateways, - 'selectGateways' => $selectGateways, 'creditCardTypes' => $creditCards, 'tokenBillingOptions' => $tokenBillingOptions, 'showBreadcrumbs' => false, @@ -174,8 +175,15 @@ class AccountGatewayController extends BaseController public function save($accountGatewayPublicId = false) { $rules = array(); + $paymentType = Input::get('payment_type_id'); $gatewayId = Input::get('gateway_id'); + if ($paymentType == PAYMENT_TYPE_PAYPAL) { + $gatewayId = GATEWAY_PAYPAL_EXPRESS; + } elseif ($paymentType == PAYMENT_TYPE_BITCOIN) { + $gatewayId = GATEWAY_BITPAY; + } + if (!$gatewayId) { Session::flash('error', trans('validation.required', ['attribute' => 'gateway'])); return Redirect::to('gateways/create') @@ -206,25 +214,28 @@ class AccountGatewayController extends BaseController ->withInput(); } else { $account = Account::with('account_gateways')->findOrFail(Auth::user()->account_id); + $oldConfig = null; if ($accountGatewayPublicId) { $accountGateway = AccountGateway::scope($accountGatewayPublicId)->firstOrFail(); + $oldConfig = json_decode($accountGateway->config); } else { $accountGateway = AccountGateway::createNew(); $accountGateway->gateway_id = $gatewayId; } - $isMasked = false; - $config = new stdClass(); foreach ($fields as $field => $details) { $value = trim(Input::get($gateway->id.'_'.$field)); - + // if the new value is masked use the original value if ($value && $value === str_repeat('*', strlen($value))) { - $isMasked = true; + $value = $oldConfig->$field; + } + if (!$value && ($field == 'testMode' || $field == 'developerMode')) { + // do nothing + } else { + $config->$field = $value; } - - $config->$field = $value; } $cardCount = 0; @@ -234,19 +245,12 @@ class AccountGatewayController extends BaseController } } - // if the values haven't changed don't update the config - if ($isMasked && $accountGatewayPublicId) { - $accountGateway->accepted_credit_cards = $cardCount; + $accountGateway->accepted_credit_cards = $cardCount; + $accountGateway->config = json_encode($config); + + if ($accountGatewayPublicId) { $accountGateway->save(); - // if there's an existing config for this gateway update it - } elseif (!$isMasked && $accountGatewayPublicId && $accountGateway->gateway_id == $gatewayId) { - $accountGateway->accepted_credit_cards = $cardCount; - $accountGateway->config = json_encode($config); - $accountGateway->save(); - // otherwise, create a new gateway config } else { - $accountGateway->config = json_encode($config); - $accountGateway->accepted_credit_cards = $cardCount; $account->account_gateways()->save($accountGateway); } diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php index 3cfa1cfdb9c8..ddef45e053a3 100644 --- a/app/Http/Controllers/AppController.php +++ b/app/Http/Controllers/AppController.php @@ -95,6 +95,7 @@ class AppController extends BaseController // Artisan::call('migrate:rollback', array('--force' => true)); // Debug Purposes Artisan::call('migrate', array('--force' => true)); Artisan::call('db:seed', array('--force' => true)); + Artisan::call('optimize', array('--force' => true)); $firstName = trim(Input::get('first_name')); $lastName = trim(Input::get('last_name')); @@ -159,6 +160,7 @@ class AppController extends BaseController try { Artisan::call('migrate', array('--force' => true)); Artisan::call('db:seed', array('--force' => true)); + Artisan::call('optimize', array('--force' => true)); } catch (Exception $e) { Response::make($e->getMessage(), 500); } @@ -172,6 +174,7 @@ class AppController extends BaseController if (!Utils::isNinja()) { try { Artisan::call('migrate', array('--force' => true)); + Artisan::call('optimize', array('--force' => true)); Cache::flush(); } catch (Exception $e) { Response::make($e->getMessage(), 500); diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index d2b1205023c5..fa3bf91b2ddf 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -204,7 +204,8 @@ class ClientController extends BaseController private function save($publicId = null) { $rules = array( - 'email' => 'required', + 'email' => 'email|required_without:first_name', + 'first_name' => 'required_without:email', ); $validator = Validator::make(Input::all(), $rules); diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index 75bc5696726f..735b080ee8d6 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -262,7 +262,7 @@ class PaymentController extends BaseController $card = new CreditCard($data); return [ - 'amount' => $invoice->balance, + 'amount' => ($invoice->partial ? $invoice->partial : $invoice->balance), 'card' => $card, 'currency' => $currencyCode, 'returnUrl' => URL::to('complete'), @@ -304,7 +304,7 @@ class PaymentController extends BaseController $data = [ 'showBreadcrumbs' => false, 'url' => 'payment/'.$invitationKey, - 'amount' => $invoice->balance, + 'amount' => ($invoice->partial ? $invoice->partial : $invoice->balance), 'invoiceNumber' => $invoice->invoice_number, 'client' => $client, 'contact' => $invitation->contact, @@ -603,12 +603,17 @@ class PaymentController extends BaseController $payment->invitation_id = $invitation->id; $payment->account_gateway_id = $accountGateway->id; $payment->invoice_id = $invoice->id; - $payment->amount = $invoice->balance; + $payment->amount = $invoice->partial ? $invoice->partial : $invoice->balance; $payment->client_id = $invoice->client_id; $payment->contact_id = $invitation->contact_id; $payment->transaction_reference = $ref; $payment->payment_date = date_create()->format('Y-m-d'); + if ($invoice->partial) { + $invoice->partial = 0; + $invoice->save(); + } + if ($payerId) { $payment->payer_id = $payerId; } diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index ead3f9fa38b7..d5a54b7cfb11 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -99,6 +99,7 @@ class Invoice extends EntityModel 'custom_value2', 'custom_taxes1', 'custom_taxes2', + 'partial', ]); $this->client->setVisible([ diff --git a/app/Ninja/Repositories/ClientRepository.php b/app/Ninja/Repositories/ClientRepository.php index d4569bea4b47..2a5276787723 100644 --- a/app/Ninja/Repositories/ClientRepository.php +++ b/app/Ninja/Repositories/ClientRepository.php @@ -34,7 +34,10 @@ class ClientRepository public function getErrors($data) { $contact = isset($data['contacts']) ? (array) $data['contacts'][0] : (isset($data['contact']) ? $data['contact'] : []); - $validator = \Validator::make($contact, ['email' => 'required|email']); + $validator = \Validator::make($contact, [ + 'email' => 'email|required_without:first_name', + 'first_name' => 'required_without:email', + ]); if ($validator->fails()) { return $validator->messages(); } diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php index 10631eb15112..658109520f09 100644 --- a/app/Ninja/Repositories/InvoiceRepository.php +++ b/app/Ninja/Repositories/InvoiceRepository.php @@ -182,7 +182,10 @@ class InvoiceRepository public function getErrors($input) { $contact = (array) $input->client->contacts[0]; - $rules = ['email' => 'required|email']; + $rules = [ + 'email' => 'email|required_without:first_name', + 'first_name' => 'required_without:email', + ]; $validator = \Validator::make($contact, $rules); if ($validator->fails()) { @@ -238,6 +241,7 @@ class InvoiceRepository $invoice->discount = round(Utils::parseFloat($data['discount']), 2); $invoice->is_amount_discount = $data['is_amount_discount'] ? true : false; $invoice->invoice_number = trim($data['invoice_number']); + $invoice->partial = round(Utils::parseFloat($data['partial']), 2); $invoice->is_recurring = $data['is_recurring'] && !Utils::isDemo() ? true : false; $invoice->invoice_date = isset($data['invoice_date_sql']) ? $data['invoice_date_sql'] : Utils::toSqlDate($data['invoice_date']); diff --git a/database/migrations/2014_10_01_141248_add_company_vat_number.php b/database/migrations/2014_10_01_141248_add_company_vat_number.php index b93a217712ed..4222b2ee15fd 100644 --- a/database/migrations/2014_10_01_141248_add_company_vat_number.php +++ b/database/migrations/2014_10_01_141248_add_company_vat_number.php @@ -17,7 +17,7 @@ class AddCompanyVatNumber extends Migration { $table->string('vat_number')->nullable(); }); - Schema::table('clients', function($table) + Schema::table('clients', function($table) { $table->string('vat_number')->nullable(); }); @@ -34,7 +34,8 @@ class AddCompanyVatNumber extends Migration { { $table->dropColumn('vat_number'); }); - Schema::table('clients', function($table) + + Schema::table('clients', function($table) { $table->dropColumn('vat_number'); }); diff --git a/database/migrations/2015_04_16_122647_add_partial_amount_to_invoices.php b/database/migrations/2015_04_16_122647_add_partial_amount_to_invoices.php new file mode 100644 index 000000000000..eed323094502 --- /dev/null +++ b/database/migrations/2015_04_16_122647_add_partial_amount_to_invoices.php @@ -0,0 +1,34 @@ +decimal('partial', 13, 2)->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('invoices', function($table) + { + $table->dropColumn('partial'); + }); + } + +} diff --git a/public/css/built.css b/public/css/built.css index ec54314db7d6..05b1105590f9 100644 --- a/public/css/built.css +++ b/public/css/built.css @@ -2900,6 +2900,7 @@ body.modal-open { overflow:inherit; padding-right:inherit !important; } .radio input[type="radio"], .checkbox input[type="checkbox"] { margin-left: 0; + padding-left: 0px !important; margin-right: 5px; height: inherit; width: inherit; @@ -2908,3 +2909,7 @@ body.modal-open { overflow:inherit; padding-right:inherit !important; } position: relative; margin-top: 3px; } + +div.checkbox > label { + padding-left: 0px !important; +} \ No newline at end of file diff --git a/public/css/style.css b/public/css/style.css index 963e607370c6..05e67cd404b3 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -792,6 +792,7 @@ body.modal-open { overflow:inherit; padding-right:inherit !important; } .radio input[type="radio"], .checkbox input[type="checkbox"] { margin-left: 0; + padding-left: 0px !important; margin-right: 5px; height: inherit; width: inherit; @@ -800,3 +801,7 @@ body.modal-open { overflow:inherit; padding-right:inherit !important; } position: relative; margin-top: 3px; } + +div.checkbox > label { + padding-left: 0px !important; +} \ No newline at end of file diff --git a/public/js/built.js b/public/js/built.js index 48468f6878dd..61231868d7ed 100644 --- a/public/js/built.js +++ b/public/js/built.js @@ -32490,7 +32490,11 @@ function calculateAmounts(invoice) { total += roundToTwo(invoice.custom_value2); } - invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance)); + if (NINJA.parseFloat(invoice.partial)) { + invoice.balance_amount = roundToTwo(invoice.partial); + } else { + invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance)); + } invoice.discount_amount = discount; invoice.tax_amount = tax; invoice.has_taxes = hasTaxes; diff --git a/public/js/script.js b/public/js/script.js index 4b0d64875d6a..b20175cdce0c 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -967,7 +967,11 @@ function calculateAmounts(invoice) { total += roundToTwo(invoice.custom_value2); } - invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance)); + if (NINJA.parseFloat(invoice.partial)) { + invoice.balance_amount = roundToTwo(invoice.partial); + } else { + invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance)); + } invoice.discount_amount = discount; invoice.tax_amount = tax; invoice.has_taxes = hasTaxes; diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 58015e6e3b43..96bf0896684e 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -589,5 +589,7 @@ return array( 'payment_type_credit_card' => 'Credit card', 'payment_type_paypal' => 'PayPal', 'payment_type_bitcoin' => 'Bitcoin', - + 'knowledge_base' => 'Knowledge Base', + 'partial' => 'Partial', + ); diff --git a/resources/views/accounts/account_gateway.blade.php b/resources/views/accounts/account_gateway.blade.php index a30f8af7f469..92f55fac213f 100644 --- a/resources/views/accounts/account_gateway.blade.php +++ b/resources/views/accounts/account_gateway.blade.php @@ -21,6 +21,8 @@ @endif @endforeach @endif + @else + {!! Former::populateField('gateway_id', GATEWAY_AUTHORIZE_NET) !!} @endif {!! Former::select('payment_type_id') @@ -28,7 +30,7 @@ ->addGroupClass('payment-type-option') ->onchange('setPaymentType()') !!} - {!! Former::select('gateway_id')->addOption('', '') + {!! Former::select('gateway_id') ->dataClass('gateway-dropdown') ->addGroupClass('gateway-option') ->fromQuery($selectGateways, 'name', 'id') @@ -42,7 +44,7 @@ @if (in_array($field, ['solutionType', 'landingPage', 'headerImageUrl', 'brandName'])) {{-- do nothing --}} @elseif ($field == 'testMode' || $field == 'developerMode') - {{-- Former::checkbox($gateway->id.'_'.$field)->label(Utils::toSpaceCase($field))->text('Enable') --}} + {!! Former::checkbox($gateway->id.'_'.$field)->label(Utils::toSpaceCase($field))->text('Enable')->value('true') !!} @elseif ($field == 'username' || $field == 'password') {!! Former::text($gateway->id.'_'.$field)->label('API '. ucfirst(Utils::toSpaceCase($field))) !!} @else diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index c7a15dfe3a85..a505e43543e6 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -72,6 +72,7 @@
{!! link_to('/forgot', trans('texts.forgot_password')) !!} + {!! link_to(NINJA_WEB_URL.'/knowledgebase/', trans('texts.knowledge_base'), ['target' => '_blank', 'class' => 'pull-right']) !!}
diff --git a/resources/views/client.blade.php b/resources/views/client.blade.php index 499c8a30976f..2dd313456b74 100644 --- a/resources/views/client.blade.php +++ b/resources/views/client.blade.php @@ -4,8 +4,8 @@ {!! Former::legend('Organization') !!} {!! Former::text('name') !!} - {!! Former::text('id_number') !!} - {!! Former::text('vat_number') !!} + {!! Former::text('id_number') !!} + {!! Former::text('vat_number') !!} {!! Former::text('work_phone')->label('Phone') !!} {!! Former::textarea('notes') !!} diff --git a/resources/views/clients/edit.blade.php b/resources/views/clients/edit.blade.php index c667a001c9dd..20012b0223ef 100644 --- a/resources/views/clients/edit.blade.php +++ b/resources/views/clients/edit.blade.php @@ -7,11 +7,8 @@ @section('content')