Add support for custom fields in billing invoices
Customers (especially in Europe) need the ability to add Tax IDs, VAT IDs, and other custom fields to their invoices. Fixes #106
This commit is contained in:
parent
683d5080d8
commit
e7fa560787
9 changed files with 426 additions and 8 deletions
|
@ -1,3 +1,6 @@
|
|||
.billing-invoices-element .fields-menu {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.billing-invoices-element .invoice-title {
|
||||
padding: 6px;
|
||||
|
@ -22,4 +25,20 @@
|
|||
|
||||
.billing-invoices-element .fa-download {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.billing-invoices-element .fa-trash-o {
|
||||
float: right;
|
||||
margin-top: -3px;
|
||||
margin-right: -14px !important;
|
||||
font-size: 14px;
|
||||
padding: 2px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.billing-invoices-element .invoice-field {
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
}
|
|
@ -9,6 +9,30 @@
|
|||
</div>
|
||||
|
||||
<div ng-show="!loading && invoices.length">
|
||||
<div class="dropdown fields-menu" data-title="Custom Invoice Fields" bs-tooltip>
|
||||
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
|
||||
<i class="fa fa-bars"></i>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu pull-right" role="menu">
|
||||
<li role="presentation" ng-repeat="invoiceField in invoiceFields">
|
||||
<a class="invoice-field" role="menuitem" tabindex="-1" href="javascript:void(0)" >
|
||||
{{ invoiceField.title }}: {{ invoiceField.value }}
|
||||
<i class="fa fa-trash-o btn btn-danger" ng-click="askDeleteField(invoiceField)"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation" class="disabled" ng-if="!invoiceFields.length">
|
||||
<a role="menuitem" tabindex="-1" href="javascript:void(0)">No Custom Fields Defined</a>
|
||||
</li>
|
||||
<li role="presentation" class="divider"></li>
|
||||
<li role="presentation">
|
||||
<a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-click="showCreateField()">
|
||||
<i class="fa fa-plus"></i>Add Custom Invoice Field
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<table class="co-table">
|
||||
<thead>
|
||||
<td>Billing Date/Time</td>
|
||||
|
@ -39,4 +63,23 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Delete Tag Confirm -->
|
||||
<div class="cor-confirm-dialog"
|
||||
dialog-context="createFieldInfo"
|
||||
dialog-action="createCustomField(info.title, info.value, callback)"
|
||||
dialog-title="Create Custom Field"
|
||||
dialog-action-title="Create Field">
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label for="titleInput">Enter Field Title</label>
|
||||
<input id="titleInput" type="text" class="form-control"ng-model="createFieldInfo.title" placeholder="Field Title">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="valueInput">Enter Field Value</label>
|
||||
<input id="valueInput" type="text" class="form-control" ng-model="createFieldInfo.value" placeholder="Field Value">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -15,6 +15,8 @@ angular.module('quay').directive('billingInvoices', function () {
|
|||
},
|
||||
controller: function($scope, $element, $sce, ApiService) {
|
||||
$scope.loading = false;
|
||||
$scope.showCreateField = null;
|
||||
$scope.invoiceFields = [];
|
||||
|
||||
var update = function() {
|
||||
var hasValidUser = !!$scope.user;
|
||||
|
@ -34,11 +36,59 @@ angular.module('quay').directive('billingInvoices', function () {
|
|||
$scope.invoices = [];
|
||||
$scope.loading = false;
|
||||
});
|
||||
|
||||
ApiService.listInvoiceFields($scope.organization).then(function(resp) {
|
||||
$scope.invoiceFields = resp.fields || [];
|
||||
}, function() {
|
||||
$scope.invoiceFields = [];
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$watch('organization', update);
|
||||
$scope.$watch('user', update);
|
||||
$scope.$watch('makevisible', update);
|
||||
|
||||
$scope.showCreateField = function() {
|
||||
$scope.createFieldInfo = {
|
||||
'title': '',
|
||||
'value': ''
|
||||
};
|
||||
};
|
||||
|
||||
$scope.askDeleteField = function(field) {
|
||||
bootbox.confirm('Are you sure you want to delete field ' + field.title + '?', function(r) {
|
||||
if (r) {
|
||||
var params = {
|
||||
'field_uuid': field.uuid
|
||||
};
|
||||
|
||||
ApiService.deleteInvoiceField($scope.organization, null, params).then(function(resp) {
|
||||
$scope.invoiceFields = $.grep($scope.invoiceFields, function(current) {
|
||||
return current.uuid != field.uuid
|
||||
});
|
||||
|
||||
}, ApiService.errorDisplay('Could not delete custom field'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.createCustomField = function(title, value, callback) {
|
||||
var data = {
|
||||
'title': title,
|
||||
'value': value
|
||||
};
|
||||
|
||||
if (!title || !value) {
|
||||
callback(false);
|
||||
bootbox.alert('Missing title or value');
|
||||
return;
|
||||
}
|
||||
|
||||
ApiService.createInvoiceField($scope.organization, data).then(function(resp) {
|
||||
$scope.invoiceFields.push(resp);
|
||||
callback(true);
|
||||
}, ApiService.errorDisplay('Could not create custom field'));
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Reference in a new issue