mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-26 20:54:21 +01:00
[feature] partial load of invoices list
This commit is contained in:
parent
820d8bba53
commit
3593f293ce
@ -3,15 +3,34 @@
|
||||
##
|
||||
# Controller used in the admin invoices listing page
|
||||
##
|
||||
Application.Controllers.controller "InvoicesController", ["$scope", "$state", 'Invoice', '$uibModal', "growl", "$filter", 'Setting', 'settings', '_t'
|
||||
, ($scope, $state, Invoice, $uibModal, growl, $filter, Setting, settings, _t) ->
|
||||
Application.Controllers.controller "InvoicesController", ["$scope", "$state", 'Invoice', 'invoices', '$uibModal', "growl", "$filter", 'Setting', 'settings', '_t'
|
||||
, ($scope, $state, Invoice, invoices, $uibModal, growl, $filter, Setting, settings, _t) ->
|
||||
|
||||
|
||||
|
||||
### PRIVATE STATIC CONSTANTS ###
|
||||
|
||||
# 10 invoices loaded each time we click on 'load more...'
|
||||
INVOICES_PER_PAGE = 10
|
||||
|
||||
|
||||
|
||||
### PUBLIC SCOPE ###
|
||||
|
||||
## List of all users invoices
|
||||
$scope.invoices = Invoice.query()
|
||||
$scope.invoices = invoices
|
||||
|
||||
# Invoices filters
|
||||
$scope.searchInvoice =
|
||||
date: null
|
||||
name: ''
|
||||
reference: ''
|
||||
|
||||
# currently displayed page of invoices (search results)
|
||||
$scope.page = 1
|
||||
|
||||
# true when all invoices are loaded
|
||||
$scope.noMoreResults = false
|
||||
|
||||
## Default invoices ordering/sorting
|
||||
$scope.orderInvoice = '-reference'
|
||||
@ -61,6 +80,9 @@ Application.Controllers.controller "InvoicesController", ["$scope", "$state", 'I
|
||||
else
|
||||
$scope.orderInvoice = orderBy
|
||||
|
||||
resetSearchInvoice()
|
||||
invoiceSearch()
|
||||
|
||||
|
||||
|
||||
##
|
||||
@ -323,6 +345,26 @@ Application.Controllers.controller "InvoicesController", ["$scope", "$state", 'I
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Callback when any of the filters changes.
|
||||
# Full reload the results list
|
||||
##
|
||||
$scope.handleFilterChange = ->
|
||||
resetSearchInvoice()
|
||||
invoiceSearch()
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Callback for the 'load more' button.
|
||||
# Will load the next results of the current search, if any
|
||||
##
|
||||
$scope.showNextInvoices = ->
|
||||
$scope.page += 1
|
||||
invoiceSearch(true)
|
||||
|
||||
|
||||
|
||||
### PRIVATE SCOPE ###
|
||||
|
||||
##
|
||||
@ -381,6 +423,40 @@ Application.Controllers.controller "InvoicesController", ["$scope", "$state", 'I
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Reinitialize the context of invoices' search to display new results set
|
||||
##
|
||||
resetSearchInvoice = ->
|
||||
$scope.page = 1
|
||||
$scope.noMoreResults = false
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Run a search query with the current parameters set concerning invoices, then affect or concat the results
|
||||
# to $scope.invoices
|
||||
# @param concat {boolean} if true, the result will be append to $scope.invoices instead of being affected
|
||||
##
|
||||
invoiceSearch = (concat) ->
|
||||
Invoice.list {
|
||||
query:
|
||||
number: $scope.searchInvoice.reference
|
||||
customer: $scope.searchInvoice.name
|
||||
date: $scope.searchInvoice.date
|
||||
order_by: $scope.orderInvoice
|
||||
page: $scope.page
|
||||
size: INVOICES_PER_PAGE
|
||||
}, (invoices) ->
|
||||
if (invoices.length < INVOICES_PER_PAGE)
|
||||
$scope.noMoreResults = true
|
||||
|
||||
if concat
|
||||
$scope.invoices = $scope.invoices.concat(invoices)
|
||||
else
|
||||
$scope.invoices = invoices
|
||||
|
||||
|
||||
|
||||
## !!! MUST BE CALLED AT THE END of the controller
|
||||
initialize()
|
||||
]
|
||||
|
@ -127,7 +127,7 @@ Application.Controllers.controller "AdminMembersController", ["$scope", 'members
|
||||
searchText: ''
|
||||
## Members ordering/sorting. Default: not sorted
|
||||
order: 'id'
|
||||
## current displayed page of members
|
||||
## currently displayed page of members
|
||||
page: 1
|
||||
## true when all members where loaded
|
||||
noMore: false
|
||||
@ -186,15 +186,26 @@ Application.Controllers.controller "AdminMembersController", ["$scope", 'members
|
||||
growl.error(_t('unable_to_delete_the_administrator'))
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Callback for the 'load more' button.
|
||||
# Will load the next results of the current search, if any
|
||||
##
|
||||
$scope.showNextMembers = ->
|
||||
$scope.member.page += 1
|
||||
memberSearch(true)
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Callback when the search field content changes: reload the search results
|
||||
##
|
||||
$scope.updateTextSearch = ->
|
||||
resetSearchMember()
|
||||
memberSearch()
|
||||
|
||||
|
||||
|
||||
### PRIVATE SCOPE ###
|
||||
|
||||
##
|
||||
|
@ -669,6 +669,11 @@ angular.module('application.router', ['ui.router']).
|
||||
'invoice_logo'
|
||||
]").$promise
|
||||
]
|
||||
invoices: [ 'Invoice', (Invoice) ->
|
||||
Invoice.list({
|
||||
query: { number: '', customer: '', date: null, order_by: '-reference', page: 1, size: 10 }
|
||||
}).$promise
|
||||
]
|
||||
translations: [ 'Translations', (Translations) ->
|
||||
Translations.query('app.admin.invoices').$promise
|
||||
]
|
||||
|
@ -5,4 +5,8 @@ Application.Services.factory 'Invoice', ["$resource", ($resource)->
|
||||
{id: "@id"},
|
||||
update:
|
||||
method: 'PUT'
|
||||
list:
|
||||
url: '/api/invoices/list'
|
||||
method: 'POST'
|
||||
isArray: true
|
||||
]
|
||||
|
@ -26,7 +26,7 @@
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" translate>{{ 'invoice_#_' }}</span>
|
||||
<input type="text" ng-model="searchInvoice.reference" class="form-control" placeholder="">
|
||||
<input type="text" ng-model="searchInvoice.reference" class="form-control" placeholder="" ng-change="handleFilterChange()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -35,7 +35,7 @@
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" translate>{{ 'customer_' }}</span>
|
||||
<input type="text" ng-model="searchInvoice.name" class="form-control" placeholder="">
|
||||
<input type="text" ng-model="searchInvoice.name" class="form-control" placeholder="" ng-change="handleFilterChange()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -44,7 +44,7 @@
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">{{ "date_" | translate }}</span>
|
||||
<input type="date" ng-model="searchInvoice.date" class="form-control">
|
||||
<input type="date" ng-model="searchInvoice.date" class="form-control" ng-change="handleFilterChange()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -69,7 +69,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="invoice in invoices | filter:searchInvoice | orderBy:orderInvoice">
|
||||
<tr ng-repeat="invoice in invoices">
|
||||
<td>{{ invoice.reference }}</td>
|
||||
<td ng-if="!invoice.is_avoir">{{ invoice.date | amDateFormat:'L LTS' }}</td>
|
||||
<td ng-if="invoice.is_avoir">{{ invoice.date | amDateFormat:'L' }}</td>
|
||||
@ -91,6 +91,9 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="text-center">
|
||||
<button class="btn btn-warning" ng-click="showNextInvoices()" ng-hide="noMoreResults"><i class="fa fa-search-plus" aria-hidden="true"></i> {{ 'display_more_invoices' | translate }}</button>
|
||||
</div>
|
||||
<p ng-if="invoices.length == 0" translate>{{ 'no_invoices_for_now' }}</p>
|
||||
|
||||
</div>
|
||||
|
@ -12,6 +12,51 @@ class API::InvoicesController < API::ApiController
|
||||
send_file File.join(Rails.root, @invoice.file), :type => 'application/pdf', :disposition => 'attachment'
|
||||
end
|
||||
|
||||
def list
|
||||
authorize Invoice
|
||||
|
||||
p = params.require(:query).permit(:number, :customer, :date, :order_by, :page, :size)
|
||||
|
||||
unless p[:page].is_a? Integer
|
||||
render json: {error: 'page must be an integer'}, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
unless p[:size].is_a? Integer
|
||||
render json: {error: 'size must be an integer'}, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
|
||||
direction = (p[:order_by][0] == '-' ? 'DESC' : 'ASC')
|
||||
order_key = (p[:order_by][0] == '-' ? p[:order_by][1, p[:order_by].size] : p[:order_by])
|
||||
|
||||
case order_key
|
||||
when 'reference'
|
||||
order_key = 'invoices.reference'
|
||||
when 'date'
|
||||
order_key = 'invoices.created_at'
|
||||
when 'total'
|
||||
order_key = 'invoices.total'
|
||||
when 'name'
|
||||
order_key = 'profiles.first_name'
|
||||
else
|
||||
order_key = 'invoices.id'
|
||||
end
|
||||
|
||||
@invoices = Invoice.includes(:avoir, :invoiced, invoice_items: [:subscription, :invoice_item], user: [:profile, :trainings])
|
||||
.joins(:user => :profile)
|
||||
.order("#{order_key} #{direction}")
|
||||
.page(p[:page])
|
||||
.per(p[:size])
|
||||
|
||||
# ILIKE => PostgreSQL case-insensitive LIKE
|
||||
@invoices = @invoices.where('invoices.reference LIKE :search', search: "#{p[:number].to_s}%") if p[:number].size > 0
|
||||
@invoices = @invoices.where('profiles.first_name ILIKE :search OR profiles.last_name ILIKE :search', search: "%#{p[:customer]}%") if p[:customer].size > 0
|
||||
@invoices = @invoices.where("date_trunc('day', invoices.created_at) = :search", search: "%#{DateTime.iso8601(p[:date]).to_time.to_date.to_s}%") unless p[:date].nil?
|
||||
|
||||
@invoices
|
||||
|
||||
end
|
||||
|
||||
# only for create avoir
|
||||
def create
|
||||
authorize Invoice
|
||||
|
@ -10,4 +10,8 @@ class InvoicePolicy < ApplicationPolicy
|
||||
def create?
|
||||
user.is_admin?
|
||||
end
|
||||
|
||||
def list?
|
||||
user.is_admin?
|
||||
end
|
||||
end
|
||||
|
12
app/views/api/invoices/list.json.jbuilder
Normal file
12
app/views/api/invoices/list.json.jbuilder
Normal file
@ -0,0 +1,12 @@
|
||||
json.array!(@invoices) do |invoice|
|
||||
json.extract! invoice, :id, :created_at, :reference, :invoiced_type, :user_id, :avoir_date
|
||||
json.total (invoice.total / 100.00)
|
||||
json.url invoice_url(invoice, format: :json)
|
||||
json.name invoice.user.profile.full_name
|
||||
json.has_avoir invoice.has_avoir
|
||||
json.is_avoir invoice.is_a?(Avoir)
|
||||
json.is_subscription_invoice invoice.is_subscription_invoice?
|
||||
json.stripe invoice.stp_invoice_id?
|
||||
json.date invoice.is_a?(Avoir) ? invoice.avoir_date : invoice.created_at
|
||||
json.prevent_refund invoice.prevent_refund?
|
||||
end
|
@ -160,6 +160,7 @@ en:
|
||||
invoice_#: "Invoice #"
|
||||
customer: "Customer"
|
||||
credit_note: "Credit note"
|
||||
display_more_invoices: "Display more invoices..."
|
||||
invoicing_settings: "Invoicing settings"
|
||||
change_logo: "Change logo"
|
||||
john_smith: "John Smith"
|
||||
|
@ -160,6 +160,7 @@ fr:
|
||||
invoice_#: "Facture n°"
|
||||
customer: "Client"
|
||||
credit_note: "Avoir"
|
||||
display_more_invoices: "Afficher plus de factures ..."
|
||||
invoicing_settings: "Paramètres de facturation"
|
||||
change_logo: "Changer le logo"
|
||||
john_smith: "Jean Dupont"
|
||||
|
@ -79,6 +79,7 @@ Rails.application.routes.draw do
|
||||
|
||||
resources :invoices, only: [:index, :show, :create] do
|
||||
get ':id/download', action: 'download', on: :collection
|
||||
post 'list', action: 'list', on: :collection
|
||||
end
|
||||
|
||||
# for admin
|
||||
|
Loading…
x
Reference in New Issue
Block a user