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
|
# Controller used in the admin invoices listing page
|
||||||
##
|
##
|
||||||
Application.Controllers.controller "InvoicesController", ["$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, $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 ###
|
### PUBLIC SCOPE ###
|
||||||
|
|
||||||
## List of all users invoices
|
## 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
|
## Default invoices ordering/sorting
|
||||||
$scope.orderInvoice = '-reference'
|
$scope.orderInvoice = '-reference'
|
||||||
@ -61,6 +80,9 @@ Application.Controllers.controller "InvoicesController", ["$scope", "$state", 'I
|
|||||||
else
|
else
|
||||||
$scope.orderInvoice = orderBy
|
$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 ###
|
### 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
|
## !!! MUST BE CALLED AT THE END of the controller
|
||||||
initialize()
|
initialize()
|
||||||
]
|
]
|
||||||
|
@ -127,7 +127,7 @@ Application.Controllers.controller "AdminMembersController", ["$scope", 'members
|
|||||||
searchText: ''
|
searchText: ''
|
||||||
## Members ordering/sorting. Default: not sorted
|
## Members ordering/sorting. Default: not sorted
|
||||||
order: 'id'
|
order: 'id'
|
||||||
## current displayed page of members
|
## currently displayed page of members
|
||||||
page: 1
|
page: 1
|
||||||
## true when all members where loaded
|
## true when all members where loaded
|
||||||
noMore: false
|
noMore: false
|
||||||
@ -186,15 +186,26 @@ Application.Controllers.controller "AdminMembersController", ["$scope", 'members
|
|||||||
growl.error(_t('unable_to_delete_the_administrator'))
|
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.showNextMembers = ->
|
||||||
$scope.member.page += 1
|
$scope.member.page += 1
|
||||||
memberSearch(true)
|
memberSearch(true)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Callback when the search field content changes: reload the search results
|
||||||
|
##
|
||||||
$scope.updateTextSearch = ->
|
$scope.updateTextSearch = ->
|
||||||
resetSearchMember()
|
resetSearchMember()
|
||||||
memberSearch()
|
memberSearch()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### PRIVATE SCOPE ###
|
### PRIVATE SCOPE ###
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -669,6 +669,11 @@ angular.module('application.router', ['ui.router']).
|
|||||||
'invoice_logo'
|
'invoice_logo'
|
||||||
]").$promise
|
]").$promise
|
||||||
]
|
]
|
||||||
|
invoices: [ 'Invoice', (Invoice) ->
|
||||||
|
Invoice.list({
|
||||||
|
query: { number: '', customer: '', date: null, order_by: '-reference', page: 1, size: 10 }
|
||||||
|
}).$promise
|
||||||
|
]
|
||||||
translations: [ 'Translations', (Translations) ->
|
translations: [ 'Translations', (Translations) ->
|
||||||
Translations.query('app.admin.invoices').$promise
|
Translations.query('app.admin.invoices').$promise
|
||||||
]
|
]
|
||||||
|
@ -5,4 +5,8 @@ Application.Services.factory 'Invoice', ["$resource", ($resource)->
|
|||||||
{id: "@id"},
|
{id: "@id"},
|
||||||
update:
|
update:
|
||||||
method: 'PUT'
|
method: 'PUT'
|
||||||
|
list:
|
||||||
|
url: '/api/invoices/list'
|
||||||
|
method: 'POST'
|
||||||
|
isArray: true
|
||||||
]
|
]
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-addon" translate>{{ 'invoice_#_' }}</span>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-addon" translate>{{ 'customer_' }}</span>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<span class="input-group-addon">{{ "date_" | translate }}</span>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -69,7 +69,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="invoice in invoices | filter:searchInvoice | orderBy:orderInvoice">
|
<tr ng-repeat="invoice in invoices">
|
||||||
<td>{{ invoice.reference }}</td>
|
<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 LTS' }}</td>
|
||||||
<td ng-if="invoice.is_avoir">{{ invoice.date | amDateFormat:'L' }}</td>
|
<td ng-if="invoice.is_avoir">{{ invoice.date | amDateFormat:'L' }}</td>
|
||||||
@ -91,6 +91,9 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</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>
|
<p ng-if="invoices.length == 0" translate>{{ 'no_invoices_for_now' }}</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,6 +12,51 @@ class API::InvoicesController < API::ApiController
|
|||||||
send_file File.join(Rails.root, @invoice.file), :type => 'application/pdf', :disposition => 'attachment'
|
send_file File.join(Rails.root, @invoice.file), :type => 'application/pdf', :disposition => 'attachment'
|
||||||
end
|
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
|
# only for create avoir
|
||||||
def create
|
def create
|
||||||
authorize Invoice
|
authorize Invoice
|
||||||
|
@ -10,4 +10,8 @@ class InvoicePolicy < ApplicationPolicy
|
|||||||
def create?
|
def create?
|
||||||
user.is_admin?
|
user.is_admin?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def list?
|
||||||
|
user.is_admin?
|
||||||
|
end
|
||||||
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 #"
|
invoice_#: "Invoice #"
|
||||||
customer: "Customer"
|
customer: "Customer"
|
||||||
credit_note: "Credit note"
|
credit_note: "Credit note"
|
||||||
|
display_more_invoices: "Display more invoices..."
|
||||||
invoicing_settings: "Invoicing settings"
|
invoicing_settings: "Invoicing settings"
|
||||||
change_logo: "Change logo"
|
change_logo: "Change logo"
|
||||||
john_smith: "John Smith"
|
john_smith: "John Smith"
|
||||||
|
@ -160,6 +160,7 @@ fr:
|
|||||||
invoice_#: "Facture n°"
|
invoice_#: "Facture n°"
|
||||||
customer: "Client"
|
customer: "Client"
|
||||||
credit_note: "Avoir"
|
credit_note: "Avoir"
|
||||||
|
display_more_invoices: "Afficher plus de factures ..."
|
||||||
invoicing_settings: "Paramètres de facturation"
|
invoicing_settings: "Paramètres de facturation"
|
||||||
change_logo: "Changer le logo"
|
change_logo: "Changer le logo"
|
||||||
john_smith: "Jean Dupont"
|
john_smith: "Jean Dupont"
|
||||||
|
@ -79,6 +79,7 @@ Rails.application.routes.draw do
|
|||||||
|
|
||||||
resources :invoices, only: [:index, :show, :create] do
|
resources :invoices, only: [:index, :show, :create] do
|
||||||
get ':id/download', action: 'download', on: :collection
|
get ':id/download', action: 'download', on: :collection
|
||||||
|
post 'list', action: 'list', on: :collection
|
||||||
end
|
end
|
||||||
|
|
||||||
# for admin
|
# for admin
|
||||||
|
Loading…
x
Reference in New Issue
Block a user