bug fixes

This commit is contained in:
Hillel Coren 2014-01-02 10:27:48 +02:00
parent 0b8ad35d66
commit fa808f9484
14 changed files with 195 additions and 148 deletions

View File

@ -42,7 +42,7 @@
'required_class' => 'required',
// A facultative text to append to the labels of required fields
'required_text' => '<sup>*</sup>',
'required_text' => '', //'<sup>*</sup>',
// Translations
////////////////////////////////////////////////////////////////////

View File

@ -422,7 +422,7 @@ class AccountController extends \BaseController {
if ($gatewayId)
{
$accountGateway = new AccountGateway;
$accountGateway = AccountGateway::createNew();
$accountGateway->gateway_id = $gatewayId;
$config = new stdClass;

View File

@ -77,6 +77,7 @@ class CreditController extends \BaseController {
'url' => 'credits',
'title' => '- New Credit',
'currencies' => Currency::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
'invoices' => Invoice::scope()->with('client')->where('balance','>',0)->orderBy('invoice_number')->get(),
'clients' => Client::scope()->with('contacts')->orderBy('name')->get());
return View::make('credits.edit', $data);
@ -128,9 +129,12 @@ class CreditController extends \BaseController {
} else {
$credit = Credit::createNew();
}
$invoiceId = Input::get('invoice') && Input::get('invoice') != "-1" ? Invoice::getPrivateId(Input::get('invoice')) : null;
$credit->client_id = Client::getPrivateId(Input::get('client'));
$credit->credit_date = Utils::toSqlDate(Input::get('credit_date'));
$credit->invoice_id = $invoiceId;
$credit->amount = floatval(Input::get('amount'));
$credit->currency_id = Input::get('currency_id') ? Input::get('currency_id') : null;
$credit->save();

View File

@ -145,19 +145,6 @@ class ConfideSetupUsersTable extends Migration {
$t->boolean('visible')->default(true);
});
Schema::create('account_gateways', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id');
$t->unsignedInteger('gateway_id');
$t->timestamps();
$t->text('config');
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('gateway_id')->references('id')->on('gateways');
});
Schema::create('users', function($t)
{
$t->increments('id');
@ -186,6 +173,26 @@ class ConfideSetupUsersTable extends Migration {
$t->unique( array('account_id','public_id') );
});
Schema::create('account_gateways', function($t)
{
$t->increments('id');
$t->unsignedInteger('account_id');
$t->unsignedInteger('user_id');
$t->unsignedInteger('gateway_id');
$t->timestamps();
$t->softDeletes();
$t->text('config');
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$t->foreign('gateway_id')->references('id')->on('gateways');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$t->unsignedInteger('public_id')->index();
$t->unique( array('account_id','public_id') );
});
Schema::create('password_reminders', function($t)
{
$t->string('email');
@ -448,6 +455,7 @@ class ConfideSetupUsersTable extends Migration {
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('user_id');
$t->unsignedInteger('client_id')->index()->nullable();
$t->unsignedInteger('invoice_id')->nullable();
$t->unsignedInteger('contact_id')->nullable();
$t->unsignedInteger('currency_id')->default(1);
$t->timestamps();
@ -460,6 +468,7 @@ class ConfideSetupUsersTable extends Migration {
$t->foreign('account_id')->references('id')->on('accounts');
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
$t->foreign('invoice_id')->references('id')->on('invoices')->onDelete('cascade');
$t->foreign('contact_id')->references('id')->on('contacts');
$t->foreign('user_id')->references('id')->on('users')->onDelete('cascade');;
$t->foreign('currency_id')->references('id')->on('currencies');

View File

@ -1,6 +1,6 @@
<?php
class AccountGateway extends Eloquent
class AccountGateway extends EntityModel
{
public function gateway()
{

View File

@ -207,7 +207,7 @@ class Activity extends Eloquent
if ($credit->invoice_id)
{
$activity->invoice_id = $payment->invoice_id;
$activity->invoice_id = $credit->invoice_id;
$invoice = $credit->invoice;
$invoice->balance = $invoice->amount - $credit->amount;

View File

@ -3,6 +3,8 @@
class EntityModel extends Eloquent
{
protected $softDelete = true;
protected $hidden = ['id', 'created_at', 'deleted_at', 'updated_at'];
public static function createNew($parent = false)
{
$className = get_called_class();

View File

@ -80,7 +80,7 @@ class InvoiceRepository
}
$invoice = (array) $input;
$rules = ['invoice_number' => 'unique:invoices,invoice_number,' . $input->id];
$rules = ['invoice_number' => 'unique:invoices,invoice_number,' . $invoice['invoice_number'] . ',id,account_id,' . \Auth::user()->account_id];
$validator = \Validator::make($invoice, $rules);
if ($validator->fails())

View File

@ -21,6 +21,26 @@
<div class="row">
<div class="col-md-6">
{{ Former::legend('Organization') }}
{{ Former::text('name')->data_bind("attr { placeholder: placeholderName }") }}
{{ Former::text('website') }}
{{ Former::text('work_phone')->label('Phone') }}
{{ Former::legend('Address') }}
{{ Former::text('address1')->label('Street') }}
{{ Former::text('address2')->label('Apt/Floor') }}
{{ Former::text('city') }}
{{ Former::text('state') }}
{{ Former::text('postal_code') }}
{{ Former::select('country_id')->addOption('','')->label('Country')
->fromQuery($countries, 'name', 'id')->select($client ? $client->country_id : '') }}
</div>
<div class="col-md-6">
{{ Former::legend('Contacts') }}
<div data-bind='template: { foreach: contacts,
beforeRemove: hideContact,
@ -55,26 +75,6 @@
{{ Former::textarea('private_notes') }}
</div>
<div class="col-md-6">
{{ Former::legend('Organization') }}
{{ Former::text('name') }}
{{ Former::text('website') }}
{{ Former::text('work_phone')->label('Phone') }}
{{ Former::legend('Address') }}
{{ Former::text('address1')->label('Street') }}
{{ Former::text('address2')->label('Apt/Floor') }}
{{ Former::text('city') }}
{{ Former::text('state') }}
{{ Former::text('postal_code') }}
{{ Former::select('country_id')->addOption('','')->label('Country')
->fromQuery($countries, 'name', 'id')->select($client ? $client->country_id : '') }}
</div>
</div>
@ -99,6 +99,16 @@
function ContactsModel() {
var self = this;
self.contacts = ko.observableArray();
self.placeholderName = ko.computed(function() {
if (self.contacts().length == 0) return '';
var contact = self.contacts()[0];
if (contact.first_name() || contact.last_name()) {
return contact.first_name() + ' ' + contact.last_name();
} else {
return contact.email();
}
});
}
@if ($client)

View File

@ -30,6 +30,7 @@
@endif
{{ Former::select('client')->addOption('', '')->addGroupClass('client-select') }}
{{ Former::select('invoice')->addOption('', '')->addGroupClass('invoice-select') }}
{{ Former::text('amount') }}
{{ Former::text('credit_date')->data_date_format(Session::get(SESSION_DATE_PICKER_FORMAT)) }}
{{ Former::select('currency_id')->addOption('','')->label('Currency')
@ -50,19 +51,18 @@
<script type="text/javascript">
var invoices = {{ $invoices }};
var clients = {{ $clients }};
$(function() {
var $input = $('select#client');
for (var i=0; i<clients.length; i++) {
var client = clients[i];
$input.append(new Option(getClientDisplayName(client), client.public_id));
}
@if ($clientPublicId)
$('select#client').val({{ $clientPublicId }});
@endif
$input.combobox();
populateInvoiceComboboxes();
$('#currency_id').combobox();

View File

@ -49,7 +49,7 @@
<div class="col-lg-8 col-lg-offset-4">
<label for="test" class="checkbox" data-bind="attr: {for: $index() + '_check'}">
<input type="checkbox" value="1" data-bind="checked: send_invoice, attr: {id: $index() + '_check'}">
<span data-bind="text: email.display"/>
<span data-bind="text: first_name() + ' ' + last_name() + ' - ' + email()"/>
</label>
</div>
</div>
@ -231,6 +231,24 @@
<div style="background-color: #F6F6F6" class="row" data-bind="with: client" onkeypress="clientModalEnterClick(event)">
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
{{ Former::legend('Organization') }}
{{ Former::text('name')->data_bind("value: name, valueUpdate: 'afterkeydown', attr { placeholder: name.placeholder }") }}
{{ Former::text('website')->data_bind("value: website, valueUpdate: 'afterkeydown'") }}
{{ Former::text('work_phone')->data_bind("value: work_phone, valueUpdate: 'afterkeydown'")->label('Phone') }}
{{ Former::legend('Address') }}
{{ Former::text('address1')->label('Street')->data_bind("value: address1, valueUpdate: 'afterkeydown'") }}
{{ Former::text('address2')->label('Apt/Floor')->data_bind("value: address2, valueUpdate: 'afterkeydown'") }}
{{ Former::text('city')->data_bind("value: city, valueUpdate: 'afterkeydown'") }}
{{ Former::text('state')->data_bind("value: state, valueUpdate: 'afterkeydown'") }}
{{ Former::text('postal_code')->data_bind("value: postal_code, valueUpdate: 'afterkeydown'") }}
{{ Former::select('country_id')->addOption('','')->label('Country')->addGroupClass('country_select')
->fromQuery($countries, 'name', 'id')->data_bind("dropdown: country_id") }}
</div>
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
{{ Former::legend('Contacts') }}
<div data-bind='template: { foreach: contacts,
@ -266,24 +284,6 @@
{{ Former::textarea('private_notes')->data_bind('value: private_notes') }}
</div>
<div class="col-md-6" style="margin-left:0px;margin-right:0px" >
{{ Former::legend('Organization') }}
{{ Former::text('name')->data_bind("value: name, valueUpdate: 'afterkeydown'") }}
{{ Former::text('website')->data_bind("value: website, valueUpdate: 'afterkeydown'") }}
{{ Former::text('work_phone')->data_bind("value: work_phone, valueUpdate: 'afterkeydown'")->label('Phone') }}
{{ Former::legend('Address') }}
{{ Former::text('address1')->label('Street')->data_bind("value: address1, valueUpdate: 'afterkeydown'") }}
{{ Former::text('address2')->label('Apt/Floor')->data_bind("value: address2, valueUpdate: 'afterkeydown'") }}
{{ Former::text('city')->data_bind("value: city, valueUpdate: 'afterkeydown'") }}
{{ Former::text('state')->data_bind("value: state, valueUpdate: 'afterkeydown'") }}
{{ Former::text('postal_code')->data_bind("value: postal_code, valueUpdate: 'afterkeydown'") }}
{{ Former::select('country_id')->addOption('','')->label('Country')->addGroupClass('country_select')
->fromQuery($countries, 'name', 'id')->data_bind("dropdown: country_id") }}
</div>
</div>
</div>
@ -377,7 +377,8 @@
if (clientId > 0) {
model.loadClient(clientMap[clientId]);
} else {
model.loadClient($.parseJSON(ko.toJSON(new ClientModel())));
model.loadClient($.parseJSON(ko.toJSON(new ClientModel())));
console.log('load blank client');
}
refreshPDF();
}); //.trigger('change');
@ -392,14 +393,14 @@
});
@if ($client)
@if ($client || $invoice)
$('#invoice_number').focus();
@else
$('.client_select input.form-control').focus();
@endif
$('#clientModal').on('shown.bs.modal', function () {
$('#first_name').focus();
$('#email').focus();
}).on('hidden.bs.modal', function () {
if (model.clientBackup) {
model.loadClient(model.clientBackup);
@ -694,14 +695,23 @@
}
self.clientFormComplete = function() {
var isValid = true;
$("input[id='email']").each(function(item, value) {
var email = $(value).val();
if (!email || !isValidEmailAddress(email)) {
isValid = false;
}
});
if (!isValid) {
$('#emailError').css( "display", "inline" );
return;
}
var email = $('#email').val();
var firstName = $('#first_name').val();
var lastName = $('#last_name').val();
var name = $('#name').val();
if (!email || !isValidEmailAddress(email)) {
$('#emailError').css( "display", "inline" );
return;
}
if (self.invoice().client().public_id() == 0) {
self.invoice().client().public_id(-1);
@ -993,6 +1003,15 @@
}
});
self.name.placeholder = ko.computed(function() {
if (self.contacts().length == 0) return '';
var contact = self.contacts()[0];
if (contact.first_name() || contact.last_name()) {
return contact.first_name() + ' ' + contact.last_name();
} else {
return contact.email();
}
});
if (data) {
ko.mapping.fromJS(data, {}, this);
@ -1010,13 +1029,15 @@
self.phone = ko.observable('');
self.send_invoice = ko.observable(false);
/*
self.displayName = ko.computed(function() {
return self.first_name() + ' ' + self.last_name() + ' - ' + self.email();
});
*/
if (data) {
ko.mapping.fromJS(data, {}, this);
}
self.email.display = ko.computed(function() {
return self.first_name() + ' ' + self.last_name() + ' - ' + self.email();
});
}
function TaxRateModel(data) {

View File

@ -54,87 +54,14 @@
var invoices = {{ $invoices }};
var clients = {{ $clients }};
var clientMap = {};
var invoiceMap = {};
var invoicesForClientMap = {};
/*
function compareClient(a,b) {
if (a.name < b.name)
return -1;
if (a.name> b.name)
return 1;
return 0;
}
*/
$(function() {
var $input = $('select#client');
for (var i=0; i<invoices.length; i++) {
var invoice = invoices[i];
var client = invoice.client;
if (!invoicesForClientMap.hasOwnProperty(client.public_id)) {
invoicesForClientMap[client.public_id] = [];
}
invoicesForClientMap[client.public_id].push(invoice);
invoiceMap[invoice.public_id] = invoice;
//clientMap[invoice.public_id] = invoice.client;
}
for (var i=0; i<clients.length; i++) {
var client = clients[i];
clientMap[client.public_id] = client;
}
//clients.sort(compareClient);
$input.append(new Option('', ''));
for (var i=0; i<clients.length; i++) {
var client = clients[i];
$input.append(new Option(getClientDisplayName(client), client.public_id));
}
@if ($clientPublicId)
$('select#client').val({{ $clientPublicId }});
@endif
$input.combobox();
$input.on('change', function(e) {
console.log('client change');
var clientId = $('input[name=client]').val();
var invoiceId = $('input[name=invoice]').val();
var invoice = invoiceMap[invoiceId];
if (invoice && invoice.client.public_id == clientId) {
console.log('values the same:' + $('select#client').prop('selected'))
e.preventDefault();
return;
}
setComboboxValue($('.invoice-select'), '', '');
$invoiceCombobox = $('select#invoice');
$invoiceCombobox.find('option').remove().end().combobox('refresh');
$invoiceCombobox.append(new Option('', ''));
var list = clientId ? (invoicesForClientMap.hasOwnProperty(clientId) ? invoicesForClientMap[clientId] : []) : invoices;
for (var i=0; i<list.length; i++) {
var invoice = list[i];
var client = clientMap[invoice.client.public_id];
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + getClientDisplayName(client) + ' - ' + formatMoney(invoice.balance, invoice.currency_id), invoice.public_id));
}
$('select#invoice').combobox('refresh');
}).trigger('change');
var $input = $('select#invoice').on('change', function(e) {
$clientCombobox = $('select#client');
var invoiceId = $('input[name=invoice]').val();
if (invoiceId) {
var invoice = invoiceMap[invoiceId];
var client = clientMap[invoice.client.public_id];
setComboboxValue($('.client-select'), client.public_id, getClientDisplayName(client));
}
});
$input.combobox();
populateInvoiceComboboxes();
$('#currency_id').combobox();

View File

@ -4,6 +4,11 @@ body > div.container {
}
*/
div.required > label {
font-weight: bold !important;
}
label.checkbox,
label.control-label {
font-weight: normal !important;

View File

@ -724,6 +724,75 @@ function getClientDisplayName(client)
}
function populateInvoiceComboboxes() {
var clientMap = {};
var invoiceMap = {};
var invoicesForClientMap = {};
var $input = $('select#client');
for (var i=0; i<invoices.length; i++) {
var invoice = invoices[i];
var client = invoice.client;
if (!invoicesForClientMap.hasOwnProperty(client.public_id)) {
invoicesForClientMap[client.public_id] = [];
}
invoicesForClientMap[client.public_id].push(invoice);
invoiceMap[invoice.public_id] = invoice;
}
for (var i=0; i<clients.length; i++) {
var client = clients[i];
clientMap[client.public_id] = client;
}
$input.append(new Option('', ''));
for (var i=0; i<clients.length; i++) {
var client = clients[i];
$input.append(new Option(getClientDisplayName(client), client.public_id));
}
$input.combobox();
$input.on('change', function(e) {
console.log('client change');
var clientId = $('input[name=client]').val();
var invoiceId = $('input[name=invoice]').val();
var invoice = invoiceMap[invoiceId];
if (invoice && invoice.client.public_id == clientId) {
console.log('values the same:' + $('select#client').prop('selected'))
e.preventDefault();
return;
}
setComboboxValue($('.invoice-select'), '', '');
$invoiceCombobox = $('select#invoice');
$invoiceCombobox.find('option').remove().end().combobox('refresh');
$invoiceCombobox.append(new Option('', ''));
var list = clientId ? (invoicesForClientMap.hasOwnProperty(clientId) ? invoicesForClientMap[clientId] : []) : invoices;
for (var i=0; i<list.length; i++) {
var invoice = list[i];
var client = clientMap[invoice.client.public_id];
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + getClientDisplayName(client) + ' - ' + formatMoney(invoice.balance, invoice.currency_id), invoice.public_id));
}
$('select#invoice').combobox('refresh');
}).trigger('change');
var $input = $('select#invoice').on('change', function(e) {
$clientCombobox = $('select#client');
var invoiceId = $('input[name=invoice]').val();
if (invoiceId) {
var invoice = invoiceMap[invoiceId];
var client = clientMap[invoice.client.public_id];
setComboboxValue($('.client-select'), client.public_id, getClientDisplayName(client));
if (!parseFloat($('#amount').val())) {
$('#amount').val(formatMoney(invoice.balance, invoice.currency_id, true));
}
}
});
$input.combobox();
}
var CONSTS = {};
CONSTS.INVOICE_STATUS_DRAFT = 1;
CONSTS.INVOICE_STATUS_SENT = 2;