1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-12-10 21:24:20 +01:00

async generation of export and download cached csv using hidden iframe

This commit is contained in:
Sylvain 2019-07-31 15:47:02 +02:00
parent fa6a54a422
commit 12d8c65fa2
6 changed files with 62 additions and 27 deletions

View File

@ -905,8 +905,10 @@ Application.Controllers.controller('ClosePeriodModalController', ['$scope', '$ui
} }
]); ]);
Application.Controllers.controller('AccountingExportModalController', ['$scope', '$uibModalInstance', 'Invoice', 'AccountingExport', 'growl', '_t', Application.Controllers.controller('AccountingExportModalController', ['$scope', '$uibModalInstance', 'Invoice', 'Export', 'CSRF', 'growl', '_t',
function ($scope, $uibModalInstance, Invoice, AccountingExport, growl, _t) { function ($scope, $uibModalInstance, Invoice, Export, CSRF, growl, _t) {
// Retrieve Anti-CSRF tokens from cookies
CSRF.setMetaTags();
const SETTINGS = { const SETTINGS = {
acd: { acd: {
@ -920,6 +922,18 @@ Application.Controllers.controller('AccountingExportModalController', ['$scope',
/* PUBLIC SCOPE */ /* PUBLIC SCOPE */
// API URL where the form will be posted
$scope.actionUrl = '/api/accounting/export';
// Form action on the above URL
$scope.method = 'post';
// Anti-CSRF token to inject into the download form
$scope.csrfToken = angular.element('meta[name="csrf-token"]')[0].content;
// API request body to generate the export
$scope.query = null;
// binding to radio button "export to" // binding to radio button "export to"
$scope.exportTarget = { $scope.exportTarget = {
software: null, software: null,
@ -947,8 +961,13 @@ Application.Controllers.controller('AccountingExportModalController', ['$scope',
* Validate the close period creation * Validate the close period creation
*/ */
$scope.ok = function () { $scope.ok = function () {
AccountingExport.export($scope.exportTarget, function(res) { const statusQry = mkQuery();
growl.info(_t('invoices.export_is_running')) $scope.query = statusQry;
Export.status(statusQry).then(function (res) {
if (!res.data.exists) {
growl.success(_t('invoices.export_is_running'));
}
$uibModalInstance.close(res); $uibModalInstance.close(res);
}); });
}; };
@ -964,7 +983,7 @@ Application.Controllers.controller('AccountingExportModalController', ['$scope',
}; };
/** /**
* Will fill the export settings, accordint to the selected software * Will fill the export settings, according to the selected software
*/ */
$scope.fillSettings = function() { $scope.fillSettings = function() {
$scope.exportTarget.settings = SETTINGS[$scope.exportTarget.software]; $scope.exportTarget.settings = SETTINGS[$scope.exportTarget.software];
@ -987,6 +1006,24 @@ Application.Controllers.controller('AccountingExportModalController', ['$scope',
}); });
}; };
/**
* Prepare the query for the export API
* @returns {{extension: *, query: *, category: string, type: string, key: *}}
*/
const mkQuery = function() {
return {
category: 'accounting',
type: 'accounting-software',
extension: $scope.exportTarget.settings.format,
key: $scope.exportTarget.settings.separator,
query: JSON.stringify({
columns: $scope.exportTarget.settings.columns,
encoding: $scope.exportTarget.settings.encoding,
date_format: $scope.exportTarget.settings.dateFormat
})
};
}
// !!! MUST BE CALLED AT THE END of the controller // !!! MUST BE CALLED AT THE END of the controller
return initialize(); return initialize();
}]); }]);

View File

@ -1,12 +0,0 @@
'use strict';
Application.Services.factory('AccountingExport', ['$resource', function ($resource) {
return $resource('/api/accounting',
{}, {
export: {
method: 'POST',
url: '/api/accounting/export'
}
}
);
}]);

View File

@ -78,6 +78,13 @@
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn btn-warning" ng-click="ok()" ng-disabled="!exportForm.$valid" translate>{{ 'confirm' }}</button> <form role="form" ng-submit="ok()" name="exportFormParams" method="post" action="{{ actionUrl }}" class="inline">
<input name="authenticity_token" type="hidden" ng-value="csrfToken"/>
<input name="_method" type="hidden" ng-value="method"/>
<input name="extension" type="hidden" ng-value="query.extension"/>
<input name="key" type="hidden" ng-value="query.key"/>
<input name="query" type="hidden" ng-value="query.query"/>
<input type="submit" class="btn btn-warning" value="{{ 'confirm' | translate }}" formtarget="export-frame"/>
</form>
<button class="btn btn-default" ng-click="cancel()" translate>{{ 'cancel' }}</button> <button class="btn btn-default" ng-click="cancel()" translate>{{ 'cancel' }}</button>
</div> </div>

View File

@ -13,6 +13,7 @@
<div class="col-xs-12 col-sm-12 col-md-3 b-t hide-b-md"> <div class="col-xs-12 col-sm-12 col-md-3 b-t hide-b-md">
<section class="heading-actions wrapper"> <section class="heading-actions wrapper">
<a class="btn btn-default rounded m-t-sm" ng-click="toggleExportModal()"><i class="fa fa-book"></i></a> <a class="btn btn-default rounded m-t-sm" ng-click="toggleExportModal()"><i class="fa fa-book"></i></a>
<iframe name="export-frame" height="0" width="0" class="none" id="accounting-export-frame"></iframe>
<a class="btn btn-lg btn-default rounded m-t-sm text-sm" ng-click="closeAnAccountingPeriod()"><i class="fa fa-calendar-check-o"></i> {{ 'invoices.accounting_periods' | translate }}</a> <a class="btn btn-lg btn-default rounded m-t-sm text-sm" ng-click="closeAnAccountingPeriod()"><i class="fa fa-calendar-check-o"></i> {{ 'invoices.accounting_periods' | translate }}</a>
</section> </section>
</div> </div>
@ -117,7 +118,7 @@
<uib-tab heading="{{ 'invoices.invoicing_settings' | translate }}"> <uib-tab heading="{{ 'invoices.invoicing_settings' | translate }}">
<form class="invoice-placeholder"> <form class="invoice-placeholder">
<div class="invoice-logo" style="background-image: url({{invoice.logo}});"> <div class="invoice-logo">
<img src="data:image/png;base64," data-src="holder.js/100%x100%/text:&#xf03e;/font:FontAwesome/icon" bs-holder ng-if="!invoice.logo" class="img-responsive"> <img src="data:image/png;base64," data-src="holder.js/100%x100%/text:&#xf03e;/font:FontAwesome/icon" bs-holder ng-if="!invoice.logo" class="img-responsive">
<img base-sixty-four-image="invoice.logo" ng-if="invoice.logo && invoice.logo.base64"> <img base-sixty-four-image="invoice.logo" ng-if="invoice.logo && invoice.logo.base64">
<div class="tools-box"> <div class="tools-box">

View File

@ -16,13 +16,9 @@ class API::AccountingExportsController < API::ApiController
category: 'accounting', category: 'accounting',
export_type: 'accounting-software', export_type: 'accounting-software',
user: current_user, user: current_user,
extension: params[:settings][:format], extension: params[:extension],
query: { query: params[:query],
columns: params[:settings][:columns], key: params[:key]
encoding: params[:settings][:encoding],
date_format: params[:settings][:dateFormat]
}.to_json,
key: params[:settings][:separator]
) )
if @export.save if @export.save
render json: { export_id: @export.id }, status: :ok render json: { export_id: @export.id }, status: :ok

View File

@ -28,7 +28,13 @@ class API::ExportsController < API::ApiController
def status def status
authorize Export authorize Export
exports = Export.where(category: params[:category], export_type: params[:type], query: params[:query], key: params[:key]) exports = Export.where(
category: params[:category],
export_type: params[:type],
query: params[:query],
key: params[:key],
extension: params[:extension]
)
export = retrieve_last_export(exports, params[:category], params[:type]) export = retrieve_last_export(exports, params[:category], params[:type])
if export.nil? || !FileTest.exist?(export.file) if export.nil? || !FileTest.exist?(export.file)