PHRAS-3783 Prod - Order manager - add Download Expiration date (#4191)

* add download expiration date

* add expiration info in mail

* add calendar on order-manager validation

* add a default config on patch if not exist

* fix

* add predifined expireon date

* expiration override

* fix order manager deny and sen in the same time

* patch for todo column

* bump version

record acl admin

fix pusher and date on order

* some improvement

* some fix
This commit is contained in:
Aina Sitraka
2022-12-20 14:42:59 +03:00
committed by GitHub
parent 8c0ff59b8a
commit a892887dd2
36 changed files with 927 additions and 183 deletions

2
.env
View File

@@ -133,7 +133,7 @@ PHRASEANET_DOCKER_REGISTRY=local
# Docker images tag. # Docker images tag.
# @run # @run
PHRASEANET_DOCKER_TAG=4.1.7-rc2 PHRASEANET_DOCKER_TAG=4.1.7-rc3
# Stack Name # Stack Name
# An optionnal Name for the stack # An optionnal Name for the stack

View File

@@ -13,5 +13,5 @@ module.exports = {
setupDir: _root + 'tests/setup/node.js', setupDir: _root + 'tests/setup/node.js',
karmaConf: _root + 'config/karma.conf.js', karmaConf: _root + 'config/karma.conf.js',
// change this version when you change JS file for lazy loading // change this version when you change JS file for lazy loading
assetFileVersion: 74 assetFileVersion: 75
}; };

View File

@@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ if (__webpack_require__.nc) { /******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ } /******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=74"; /******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=75";
/******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete; /******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() { /******/ function onScriptComplete() {

View File

@@ -96,7 +96,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ if (__webpack_require__.nc) { /******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ } /******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=74"; /******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=75";
/******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete; /******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() { /******/ function onScriptComplete() {

View File

@@ -91,7 +91,7 @@
/******/ if (__webpack_require__.nc) { /******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ } /******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=74"; /******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".js?v=75";
/******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete; /******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() { /******/ function onScriptComplete() {

View File

@@ -91,7 +91,7 @@
/******/ if (__webpack_require__.nc) { /******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc); /******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ } /******/ }
/******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=74"; /******/ script.src = __webpack_require__.p + "lazy-" + ({}[chunkId]||chunkId) + ".min.js?v=75";
/******/ var timeout = setTimeout(onScriptComplete, 120000); /******/ var timeout = setTimeout(onScriptComplete, 120000);
/******/ script.onerror = script.onload = onScriptComplete; /******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() { /******/ function onScriptComplete() {

View File

@@ -65932,15 +65932,21 @@ var orderItem = function orderItem(services) {
//$('.order_row.selected').removeClass('to_be_validated'); //$('.order_row.selected').removeClass('to_be_validated');
}); });
(0, _jquery2.default)('.force_sender', $dialog.getDomElement()).bind('click', function () { // comment on order_item.html.twig , line 171
if (confirm(localeService.t('forceSendDocument'))) { // $('.force_sender', $dialog.getDomElement()).bind('click', function () {
//updateValidation('validated'); // if (confirm(localeService.t('forceSendDocument'))) {
var element_id = []; // //updateValidation('validated');
element_id.push((0, _jquery2.default)(this).closest('.order_row').find('input[name=order_element_id]').val()); // let element_id = [];
var order_id = (0, _jquery2.default)('input[name=order_id]').val(); // element_id.push(
do_send_documents(order_id, element_id, true); // $(this)
} // .closest('.order_row')
}); // .find('input[name=order_element_id]')
// .val()
// );
// let order_id = $('input[name=order_id]').val();
// do_send_documents(order_id, element_id, true);
// }
// });
(0, _jquery2.default)('#userInfo').hover(function () { (0, _jquery2.default)('#userInfo').hover(function () {
var offset = (0, _jquery2.default)('#userInfo').position(); var offset = (0, _jquery2.default)('#userInfo').position();
@@ -66039,6 +66045,56 @@ var orderItem = function orderItem(services) {
} }
}); });
(0, _jquery2.default)('#validation-window .expireOn').datepicker({
beforeShow: function beforeShow(input, inst) {
(0, _jquery2.default)(inst.dpDiv).addClass('expireOn');
},
changeYear: true,
changeMonth: true,
dateFormat: 'yy-mm-dd',
onClose: function onClose(input, inst) {
(0, _jquery2.default)(inst.dpDiv).removeClass('expireOn');
}
});
(0, _jquery2.default)('#expire-menu').menu({
select: function select(event, ui) {
var $input = (0, _jquery2.default)('input[name="expireOn"]:visible');
var expire = (0, _jquery2.default)(ui.item[0]).data('expireon');
if (expire === '') {
// expireon to null = no expiration for the right
$input.val('');
} else {
calculateExpireDate($input, expire);
}
(0, _jquery2.default)(this).hide();
}
}).mouseleave(function (event, ui) {
(0, _jquery2.default)(this).hide();
}).hide();
// click to ... to drop
(0, _jquery2.default)("BUTTON.expireOn-menu").click(function (event, ui) {
(0, _jquery2.default)("#expire-menu").css({
top: event.clientY,
left: event.clientX - 6
}).show();
return false;
});
function calculateExpireDate($input, expire) {
if (expire === null || expire === undefined || expire === '') {
$input.val("");
} else {
var d = new Date();
d.setDate(d.getDate() + parseInt(expire));
var mm = (d.getMonth() + 1 < 10 ? '0' : '') + (d.getMonth() + 1);
var dd = (d.getDate() < 10 ? '0' : '') + d.getDate();
$input.val(d.getFullYear() + '-' + mm + '-' + dd);
}
}
function createBasket($innerDialog) { function createBasket($innerDialog) {
var $form = (0, _jquery2.default)('form', $innerDialog); var $form = (0, _jquery2.default)('form', $innerDialog);
var dialog = $innerDialog.closest('.ui-dialog'); var dialog = $innerDialog.closest('.ui-dialog');
@@ -66102,6 +66158,7 @@ var orderItem = function orderItem(services) {
var submitTitle = window.orderItemData.translatedText.submit; var submitTitle = window.orderItemData.translatedText.submit;
var resetTitle = window.orderItemData.translatedText.reset; var resetTitle = window.orderItemData.translatedText.reset;
var dialog_buttons = {}; var dialog_buttons = {};
dialog_buttons[submitTitle] = function () { dialog_buttons[submitTitle] = function () {
//submit documents //submit documents
submitDocuments((0, _jquery2.default)(this)); submitDocuments((0, _jquery2.default)(this));
@@ -66133,6 +66190,9 @@ var orderItem = function orderItem(services) {
} }
}).dialog('open'); }).dialog('open');
createValidationTable(); createValidationTable();
var $input = (0, _jquery2.default)('input[name="expireOn"]:visible');
var defaultExpire = $input.data('default-expiration');
calculateExpireDate($input, defaultExpire);
} }
function submitDocuments(dialogElem) { function submitDocuments(dialogElem) {
@@ -66155,15 +66215,18 @@ var orderItem = function orderItem(services) {
return elem.elementId; return elem.elementId;
}); });
if (validatedArrayNoForceIds.length > 0 && deniedArrayIds.length > 0) {
do_validate_documents(order_id, validatedArrayNoForceIds, deniedArrayIds);
} else {
if (validatedArrayNoForceIds.length > 0) { if (validatedArrayNoForceIds.length > 0) {
do_send_documents(order_id, validatedArrayNoForceIds, false); do_send_documents(order_id, validatedArrayNoForceIds, false);
} } else if (validatedArrayWithForceIds.length > 0) {
if (validatedArrayWithForceIds.length > 0) {
do_send_documents(order_id, validatedArrayWithForceIds, true); do_send_documents(order_id, validatedArrayWithForceIds, true);
} } else if (deniedArrayIds.length > 0) {
if (deniedArrayIds.length > 0) {
do_deny_documents(order_id, deniedArrayIds); do_deny_documents(order_id, deniedArrayIds);
} }
}
dialogElem.dialog('close'); dialogElem.dialog('close');
} }
@@ -66177,8 +66240,12 @@ var orderItem = function orderItem(services) {
}); });
if (validatedArray.length > 0) { if (validatedArray.length > 0) {
(0, _jquery2.default)("#validation-window:visible .order-expireon-wrap").show();
(0, _jquery2.default)("#validation-window:visible input[name='expireOn']").blur();
var html = ''; var html = '';
html += '<h5>' + window.orderItemData.translatedText.youHaveValidated + ' ' + validatedArray.length + ' ' + window.orderItemData.translatedText.item + (validatedArray.length === 1 ? '' : 's') + '</h5>'; html += '<h5>' + window.orderItemData.translatedText.youHaveValidated + ' ' + validatedArray.length + ' ' + window.orderItemData.translatedText.item + (validatedArray.length === 1 ? '' : 's') + '</h5>';
html += '<table class="validation-table">'; html += '<table class="validation-table">';
_underscore2.default.each(validatedArray, function (elem) { _underscore2.default.each(validatedArray, function (elem) {
html += '<tr>'; html += '<tr>';
@@ -66188,6 +66255,8 @@ var orderItem = function orderItem(services) {
}); });
html += '</table>'; html += '</table>';
(0, _jquery2.default)('.validation-content').append(html); (0, _jquery2.default)('.validation-content').append(html);
} else {
(0, _jquery2.default)("#validation-window:visible .order-expireon-wrap").hide();
} }
if (deniedArray.length > 0) { if (deniedArray.length > 0) {
@@ -66301,11 +66370,9 @@ var orderItem = function orderItem(services) {
function toggleValidationButton() { function toggleValidationButton() {
if (readyForValidation) { if (readyForValidation) {
(0, _jquery2.default)('button.validate').prop('disabled', false); (0, _jquery2.default)('button.validate').show();
(0, _jquery2.default)('button.validate').css('color', '#7CD21C');
} else { } else {
(0, _jquery2.default)('button.validate').prop('disabled', true); (0, _jquery2.default)('button.validate').hide();
(0, _jquery2.default)('button.validate').css('color', '#737373');
} }
} }
@@ -66321,7 +66388,44 @@ var orderItem = function orderItem(services) {
dataType: 'json', dataType: 'json',
data: { data: {
'elements[]': elements_ids, 'elements[]': elements_ids,
force: force ? 1 : 0 force: force ? 1 : 0,
expireOn: (0, _jquery2.default)('input[name="expireOn"]:visible').val()
},
success: function success(data) {
var success = '0';
if (data.success) {
success = '1';
}
var url = '../prod/order/' + order_id + '/?success=' + success + '&action=send';
reloadDialog(url);
},
error: function error() {
(0, _jquery2.default)('button.deny, button.send', cont).prop('disabled', false);
(0, _jquery2.default)('.activity_indicator', cont).hide();
},
timeout: function timeout() {
(0, _jquery2.default)('button.deny, button.send', cont).prop('disabled', false);
(0, _jquery2.default)('.activity_indicator', cont).hide();
}
});
}
function do_validate_documents(order_id, elements_send_ids, elements_deny_ids) {
var cont = $dialog.getDomElement();
(0, _jquery2.default)('button.deny, button.send', cont).prop('disabled', true);
(0, _jquery2.default)('.activity_indicator', cont).show();
_jquery2.default.ajax({
type: 'POST',
url: '../prod/order/' + order_id + '/validate/',
dataType: 'json',
data: {
'elementsSend[]': elements_send_ids,
'elementsDeny[]': elements_deny_ids,
expireOn: (0, _jquery2.default)('input[name="expireOn"]:visible').val()
}, },
success: function success(data) { success: function success(data) {
var success = '0'; var success = '0';
@@ -66414,24 +66518,39 @@ var orderItem = function orderItem(services) {
}, { validated: 0, selectable: 0, waitingForValidation: 0 }); }, { validated: 0, selectable: 0, waitingForValidation: 0 });
var html = ''; var html = '';
if (countObj.validated > 0) { // if (countObj.validated > 0) {
html += '<p>' + window.orderItemData.translatedText.itemsAlreadySent + ': ' + countObj.validated + '</p>'; // html +=
} // '<p>' +
// window.orderItemData.translatedText.itemsAlreadySent +
// ': ' +
// countObj.validated +
// '</p>';
// }
if (countObj.waitingForValidation > 0) { // if (countObj.waitingForValidation > 0) {
html += '<p>' + window.orderItemData.translatedText.itemsWaitingValidation + ': ' + countObj.waitingForValidation + '</p>'; // html +=
} // '<p>' +
// window.orderItemData.translatedText.itemsWaitingValidation +
// ': ' +
// countObj.waitingForValidation +
// '</p>';
// }
//for the remaining items //for the remaining items
var remaining = countObj.selectable - (countObj.validated + countObj.waitingForValidation); var remaining = countObj.selectable - (countObj.validated + countObj.waitingForValidation);
if (remaining > 0) { if (remaining > 0) {
html += '<p>' + window.orderItemData.translatedText.nonSentItems + ': ' + remaining + '</p>'; // html +=
// '<p>' +
// window.orderItemData.translatedText.nonSentItems +
// ': ' +
// remaining +
// '</p>';
(0, _jquery2.default)('#order-action button.deny, #order-action button.send').prop('disabled', false); (0, _jquery2.default)('#order-action button.deny, #order-action button.send').prop('disabled', false);
(0, _jquery2.default)('#order-action button.deny, #order-action button.send').show(); (0, _jquery2.default)('#order-action button.deny, #order-action button.send').show();
} }
(0, _jquery2.default)('#wrapper-multiple #text-content').empty(); // $('#wrapper-multiple #text-content').empty();
(0, _jquery2.default)('#wrapper-multiple #text-content').append(html); // $('#wrapper-multiple #text-content').append(html);
} }
/* * /* *

View File

@@ -65932,15 +65932,21 @@ var orderItem = function orderItem(services) {
//$('.order_row.selected').removeClass('to_be_validated'); //$('.order_row.selected').removeClass('to_be_validated');
}); });
(0, _jquery2.default)('.force_sender', $dialog.getDomElement()).bind('click', function () { // comment on order_item.html.twig , line 171
if (confirm(localeService.t('forceSendDocument'))) { // $('.force_sender', $dialog.getDomElement()).bind('click', function () {
//updateValidation('validated'); // if (confirm(localeService.t('forceSendDocument'))) {
var element_id = []; // //updateValidation('validated');
element_id.push((0, _jquery2.default)(this).closest('.order_row').find('input[name=order_element_id]').val()); // let element_id = [];
var order_id = (0, _jquery2.default)('input[name=order_id]').val(); // element_id.push(
do_send_documents(order_id, element_id, true); // $(this)
} // .closest('.order_row')
}); // .find('input[name=order_element_id]')
// .val()
// );
// let order_id = $('input[name=order_id]').val();
// do_send_documents(order_id, element_id, true);
// }
// });
(0, _jquery2.default)('#userInfo').hover(function () { (0, _jquery2.default)('#userInfo').hover(function () {
var offset = (0, _jquery2.default)('#userInfo').position(); var offset = (0, _jquery2.default)('#userInfo').position();
@@ -66039,6 +66045,56 @@ var orderItem = function orderItem(services) {
} }
}); });
(0, _jquery2.default)('#validation-window .expireOn').datepicker({
beforeShow: function beforeShow(input, inst) {
(0, _jquery2.default)(inst.dpDiv).addClass('expireOn');
},
changeYear: true,
changeMonth: true,
dateFormat: 'yy-mm-dd',
onClose: function onClose(input, inst) {
(0, _jquery2.default)(inst.dpDiv).removeClass('expireOn');
}
});
(0, _jquery2.default)('#expire-menu').menu({
select: function select(event, ui) {
var $input = (0, _jquery2.default)('input[name="expireOn"]:visible');
var expire = (0, _jquery2.default)(ui.item[0]).data('expireon');
if (expire === '') {
// expireon to null = no expiration for the right
$input.val('');
} else {
calculateExpireDate($input, expire);
}
(0, _jquery2.default)(this).hide();
}
}).mouseleave(function (event, ui) {
(0, _jquery2.default)(this).hide();
}).hide();
// click to ... to drop
(0, _jquery2.default)("BUTTON.expireOn-menu").click(function (event, ui) {
(0, _jquery2.default)("#expire-menu").css({
top: event.clientY,
left: event.clientX - 6
}).show();
return false;
});
function calculateExpireDate($input, expire) {
if (expire === null || expire === undefined || expire === '') {
$input.val("");
} else {
var d = new Date();
d.setDate(d.getDate() + parseInt(expire));
var mm = (d.getMonth() + 1 < 10 ? '0' : '') + (d.getMonth() + 1);
var dd = (d.getDate() < 10 ? '0' : '') + d.getDate();
$input.val(d.getFullYear() + '-' + mm + '-' + dd);
}
}
function createBasket($innerDialog) { function createBasket($innerDialog) {
var $form = (0, _jquery2.default)('form', $innerDialog); var $form = (0, _jquery2.default)('form', $innerDialog);
var dialog = $innerDialog.closest('.ui-dialog'); var dialog = $innerDialog.closest('.ui-dialog');
@@ -66102,6 +66158,7 @@ var orderItem = function orderItem(services) {
var submitTitle = window.orderItemData.translatedText.submit; var submitTitle = window.orderItemData.translatedText.submit;
var resetTitle = window.orderItemData.translatedText.reset; var resetTitle = window.orderItemData.translatedText.reset;
var dialog_buttons = {}; var dialog_buttons = {};
dialog_buttons[submitTitle] = function () { dialog_buttons[submitTitle] = function () {
//submit documents //submit documents
submitDocuments((0, _jquery2.default)(this)); submitDocuments((0, _jquery2.default)(this));
@@ -66133,6 +66190,9 @@ var orderItem = function orderItem(services) {
} }
}).dialog('open'); }).dialog('open');
createValidationTable(); createValidationTable();
var $input = (0, _jquery2.default)('input[name="expireOn"]:visible');
var defaultExpire = $input.data('default-expiration');
calculateExpireDate($input, defaultExpire);
} }
function submitDocuments(dialogElem) { function submitDocuments(dialogElem) {
@@ -66155,15 +66215,18 @@ var orderItem = function orderItem(services) {
return elem.elementId; return elem.elementId;
}); });
if (validatedArrayNoForceIds.length > 0 && deniedArrayIds.length > 0) {
do_validate_documents(order_id, validatedArrayNoForceIds, deniedArrayIds);
} else {
if (validatedArrayNoForceIds.length > 0) { if (validatedArrayNoForceIds.length > 0) {
do_send_documents(order_id, validatedArrayNoForceIds, false); do_send_documents(order_id, validatedArrayNoForceIds, false);
} } else if (validatedArrayWithForceIds.length > 0) {
if (validatedArrayWithForceIds.length > 0) {
do_send_documents(order_id, validatedArrayWithForceIds, true); do_send_documents(order_id, validatedArrayWithForceIds, true);
} } else if (deniedArrayIds.length > 0) {
if (deniedArrayIds.length > 0) {
do_deny_documents(order_id, deniedArrayIds); do_deny_documents(order_id, deniedArrayIds);
} }
}
dialogElem.dialog('close'); dialogElem.dialog('close');
} }
@@ -66177,8 +66240,12 @@ var orderItem = function orderItem(services) {
}); });
if (validatedArray.length > 0) { if (validatedArray.length > 0) {
(0, _jquery2.default)("#validation-window:visible .order-expireon-wrap").show();
(0, _jquery2.default)("#validation-window:visible input[name='expireOn']").blur();
var html = ''; var html = '';
html += '<h5>' + window.orderItemData.translatedText.youHaveValidated + ' ' + validatedArray.length + ' ' + window.orderItemData.translatedText.item + (validatedArray.length === 1 ? '' : 's') + '</h5>'; html += '<h5>' + window.orderItemData.translatedText.youHaveValidated + ' ' + validatedArray.length + ' ' + window.orderItemData.translatedText.item + (validatedArray.length === 1 ? '' : 's') + '</h5>';
html += '<table class="validation-table">'; html += '<table class="validation-table">';
_underscore2.default.each(validatedArray, function (elem) { _underscore2.default.each(validatedArray, function (elem) {
html += '<tr>'; html += '<tr>';
@@ -66188,6 +66255,8 @@ var orderItem = function orderItem(services) {
}); });
html += '</table>'; html += '</table>';
(0, _jquery2.default)('.validation-content').append(html); (0, _jquery2.default)('.validation-content').append(html);
} else {
(0, _jquery2.default)("#validation-window:visible .order-expireon-wrap").hide();
} }
if (deniedArray.length > 0) { if (deniedArray.length > 0) {
@@ -66301,11 +66370,9 @@ var orderItem = function orderItem(services) {
function toggleValidationButton() { function toggleValidationButton() {
if (readyForValidation) { if (readyForValidation) {
(0, _jquery2.default)('button.validate').prop('disabled', false); (0, _jquery2.default)('button.validate').show();
(0, _jquery2.default)('button.validate').css('color', '#7CD21C');
} else { } else {
(0, _jquery2.default)('button.validate').prop('disabled', true); (0, _jquery2.default)('button.validate').hide();
(0, _jquery2.default)('button.validate').css('color', '#737373');
} }
} }
@@ -66321,7 +66388,44 @@ var orderItem = function orderItem(services) {
dataType: 'json', dataType: 'json',
data: { data: {
'elements[]': elements_ids, 'elements[]': elements_ids,
force: force ? 1 : 0 force: force ? 1 : 0,
expireOn: (0, _jquery2.default)('input[name="expireOn"]:visible').val()
},
success: function success(data) {
var success = '0';
if (data.success) {
success = '1';
}
var url = '../prod/order/' + order_id + '/?success=' + success + '&action=send';
reloadDialog(url);
},
error: function error() {
(0, _jquery2.default)('button.deny, button.send', cont).prop('disabled', false);
(0, _jquery2.default)('.activity_indicator', cont).hide();
},
timeout: function timeout() {
(0, _jquery2.default)('button.deny, button.send', cont).prop('disabled', false);
(0, _jquery2.default)('.activity_indicator', cont).hide();
}
});
}
function do_validate_documents(order_id, elements_send_ids, elements_deny_ids) {
var cont = $dialog.getDomElement();
(0, _jquery2.default)('button.deny, button.send', cont).prop('disabled', true);
(0, _jquery2.default)('.activity_indicator', cont).show();
_jquery2.default.ajax({
type: 'POST',
url: '../prod/order/' + order_id + '/validate/',
dataType: 'json',
data: {
'elementsSend[]': elements_send_ids,
'elementsDeny[]': elements_deny_ids,
expireOn: (0, _jquery2.default)('input[name="expireOn"]:visible').val()
}, },
success: function success(data) { success: function success(data) {
var success = '0'; var success = '0';
@@ -66414,24 +66518,39 @@ var orderItem = function orderItem(services) {
}, { validated: 0, selectable: 0, waitingForValidation: 0 }); }, { validated: 0, selectable: 0, waitingForValidation: 0 });
var html = ''; var html = '';
if (countObj.validated > 0) { // if (countObj.validated > 0) {
html += '<p>' + window.orderItemData.translatedText.itemsAlreadySent + ': ' + countObj.validated + '</p>'; // html +=
} // '<p>' +
// window.orderItemData.translatedText.itemsAlreadySent +
// ': ' +
// countObj.validated +
// '</p>';
// }
if (countObj.waitingForValidation > 0) { // if (countObj.waitingForValidation > 0) {
html += '<p>' + window.orderItemData.translatedText.itemsWaitingValidation + ': ' + countObj.waitingForValidation + '</p>'; // html +=
} // '<p>' +
// window.orderItemData.translatedText.itemsWaitingValidation +
// ': ' +
// countObj.waitingForValidation +
// '</p>';
// }
//for the remaining items //for the remaining items
var remaining = countObj.selectable - (countObj.validated + countObj.waitingForValidation); var remaining = countObj.selectable - (countObj.validated + countObj.waitingForValidation);
if (remaining > 0) { if (remaining > 0) {
html += '<p>' + window.orderItemData.translatedText.nonSentItems + ': ' + remaining + '</p>'; // html +=
// '<p>' +
// window.orderItemData.translatedText.nonSentItems +
// ': ' +
// remaining +
// '</p>';
(0, _jquery2.default)('#order-action button.deny, #order-action button.send').prop('disabled', false); (0, _jquery2.default)('#order-action button.deny, #order-action button.send').prop('disabled', false);
(0, _jquery2.default)('#order-action button.deny, #order-action button.send').show(); (0, _jquery2.default)('#order-action button.deny, #order-action button.send').show();
} }
(0, _jquery2.default)('#wrapper-multiple #text-content').empty(); // $('#wrapper-multiple #text-content').empty();
(0, _jquery2.default)('#wrapper-multiple #text-content').append(html); // $('#wrapper-multiple #text-content').append(html);
} }
/* * /* *

View File

@@ -2202,6 +2202,22 @@ span.ww_winTitle {
position: absolute; position: absolute;
} }
#ui-datepicker-div.expireOn {
z-index: 999999 !important;
}
#validation-window .ui-widget-content {
background-color: #fff;
}
#validation-window .ui-widget-content a {
color: #282828;
}
#validation-window .ui-widget-content a:hover {
color: #fff;
}
.ui-selectable-helper { .ui-selectable-helper {
border: 1px dotted #cccccc; border: 1px dotted #cccccc;
z-index: 10000; z-index: 10000;
@@ -2376,7 +2392,7 @@ span.ww_winTitle {
} }
#order_manager .order_list .selectable.selected { #order_manager .order_list .selectable.selected {
background-color: #7f7f7f; background-color: #292929;
border: 1px solid #4990e2; border: 1px solid #4990e2;
} }
@@ -2641,8 +2657,8 @@ button.order_launcher.btn {
} }
#order-action { #order-action {
margin-top: 1.2em; margin: 0px 0px 1.2em 30px;
margin-bottom: 1.5em; text-align: left;
} }
#filter_box { #filter_box {
@@ -2843,6 +2859,10 @@ span.action-text i.fa-check {
} }
button.btn.validate { button.btn.validate {
background-color: #5bb75b;
background-image: linear-gradient(to bottom, #62c462, #51a351);
border-color: #51a351 #51a351 #387038;
color: #fff;
margin-bottom: 10px; margin-bottom: 10px;
font-size: 14px; font-size: 14px;
} }

File diff suppressed because one or more lines are too long

View File

@@ -2217,6 +2217,22 @@ span.ww_winTitle {
position: absolute; position: absolute;
} }
#ui-datepicker-div.expireOn {
z-index: 999999 !important;
}
#validation-window .ui-widget-content {
background-color: #fff;
}
#validation-window .ui-widget-content a {
color: #282828;
}
#validation-window .ui-widget-content a:hover {
color: #fff;
}
.ui-selectable-helper { .ui-selectable-helper {
border: 1px dotted #cccccc; border: 1px dotted #cccccc;
z-index: 10000; z-index: 10000;
@@ -2391,7 +2407,7 @@ span.ww_winTitle {
} }
#order_manager .order_list .selectable.selected { #order_manager .order_list .selectable.selected {
background-color: silver; background-color: #9c9c9c;
border: 1px solid #4990e2; border: 1px solid #4990e2;
} }
@@ -2656,8 +2672,8 @@ button.order_launcher.btn {
} }
#order-action { #order-action {
margin-top: 1.2em; margin: 0px 0px 1.2em 30px;
margin-bottom: 1.5em; text-align: left;
} }
#filter_box { #filter_box {
@@ -2858,6 +2874,10 @@ span.action-text i.fa-check {
} }
button.btn.validate { button.btn.validate {
background-color: #5bb75b;
background-image: linear-gradient(to bottom, #62c462, #51a351);
border-color: #51a351 #51a351 #387038;
color: #fff;
margin-bottom: 10px; margin-bottom: 10px;
font-size: 14px; font-size: 14px;
} }

File diff suppressed because one or more lines are too long

View File

@@ -2219,6 +2219,22 @@ span.ww_winTitle {
position: absolute; position: absolute;
} }
#ui-datepicker-div.expireOn {
z-index: 999999 !important;
}
#validation-window .ui-widget-content {
background-color: #fff;
}
#validation-window .ui-widget-content a {
color: #282828;
}
#validation-window .ui-widget-content a:hover {
color: #fff;
}
.ui-selectable-helper { .ui-selectable-helper {
border: 1px dotted #cccccc; border: 1px dotted #cccccc;
z-index: 10000; z-index: 10000;
@@ -2658,8 +2674,8 @@ button.order_launcher.btn {
} }
#order-action { #order-action {
margin-top: 1.2em; margin: 0px 0px 1.2em 30px;
margin-bottom: 1.5em; text-align: left;
} }
#filter_box { #filter_box {
@@ -2860,6 +2876,10 @@ span.action-text i.fa-check {
} }
button.btn.validate { button.btn.validate {
background-color: #5bb75b;
background-image: linear-gradient(to bottom, #62c462, #51a351);
border-color: #51a351 #51a351 #387038;
color: #fff;
margin-bottom: 10px; margin-bottom: 10px;
font-size: 14px; font-size: 14px;
} }

File diff suppressed because one or more lines are too long

View File

@@ -204,20 +204,21 @@ const orderItem = services => {
//$('.order_row.selected').removeClass('to_be_validated'); //$('.order_row.selected').removeClass('to_be_validated');
}); });
$('.force_sender', $dialog.getDomElement()).bind('click', function () { // comment on order_item.html.twig , line 171
if (confirm(localeService.t('forceSendDocument'))) { // $('.force_sender', $dialog.getDomElement()).bind('click', function () {
//updateValidation('validated'); // if (confirm(localeService.t('forceSendDocument'))) {
let element_id = []; // //updateValidation('validated');
element_id.push( // let element_id = [];
$(this) // element_id.push(
.closest('.order_row') // $(this)
.find('input[name=order_element_id]') // .closest('.order_row')
.val() // .find('input[name=order_element_id]')
); // .val()
let order_id = $('input[name=order_id]').val(); // );
do_send_documents(order_id, element_id, true); // let order_id = $('input[name=order_id]').val();
} // do_send_documents(order_id, element_id, true);
}); // }
// });
$('#userInfo').hover( $('#userInfo').hover(
function () { function () {
@@ -335,6 +336,63 @@ const orderItem = services => {
} }
}); });
$('#validation-window .expireOn').datepicker({
beforeShow: (input, inst) => {
$(inst.dpDiv).addClass('expireOn');
},
changeYear: true,
changeMonth: true,
dateFormat: 'yy-mm-dd',
onClose: (input, inst) => {
$(inst.dpDiv).removeClass('expireOn');
},
});
$('#expire-menu')
.menu({
select: function (event, ui) {
const $input = $('input[name="expireOn"]:visible');
const expire = $(ui.item[0]).data('expireon');
if (expire === '') {
// expireon to null = no expiration for the right
$input.val('')
} else {
calculateExpireDate($input, expire);
}
$(this).hide();
}
})
.mouseleave(function (event, ui) {
$(this).hide();
})
.hide();
// click to ... to drop
$("BUTTON.expireOn-menu").click(
function (event, ui) {
$("#expire-menu")
.css({
top: event.clientY,
left: event.clientX - 6
})
.show();
return false;
}
);
function calculateExpireDate($input, expire) {
if (expire === null || expire === undefined || expire === '') {
$input.val("");
} else {
const d = new Date();
d.setDate(d.getDate() + parseInt(expire));
const mm = ((d.getMonth() + 1) < 10 ? '0' : '') + (d.getMonth() + 1);
const dd = (d.getDate() < 10 ? '0' : '') + d.getDate();
$input.val(d.getFullYear() + '-' + mm + '-' + dd);
}
}
function createBasket($innerDialog) { function createBasket($innerDialog) {
let $form = $('form', $innerDialog); let $form = $('form', $innerDialog);
let dialog = $innerDialog.closest('.ui-dialog'); let dialog = $innerDialog.closest('.ui-dialog');
@@ -419,6 +477,7 @@ const orderItem = services => {
let submitTitle = window.orderItemData.translatedText.submit; let submitTitle = window.orderItemData.translatedText.submit;
let resetTitle = window.orderItemData.translatedText.reset; let resetTitle = window.orderItemData.translatedText.reset;
var dialog_buttons = {}; var dialog_buttons = {};
dialog_buttons[submitTitle] = function () { dialog_buttons[submitTitle] = function () {
//submit documents //submit documents
submitDocuments($(this)); submitDocuments($(this));
@@ -452,6 +511,9 @@ const orderItem = services => {
}) })
.dialog('open'); .dialog('open');
createValidationTable(); createValidationTable();
const $input = $('input[name="expireOn"]:visible');
const defaultExpire = $input.data('default-expiration');
calculateExpireDate($input, defaultExpire);
} }
function submitDocuments(dialogElem) { function submitDocuments(dialogElem) {
@@ -488,15 +550,18 @@ const orderItem = services => {
return elem.elementId; return elem.elementId;
}); });
if (validatedArrayNoForceIds.length > 0 && deniedArrayIds.length > 0) {
do_validate_documents(order_id, validatedArrayNoForceIds, deniedArrayIds);
} else {
if (validatedArrayNoForceIds.length > 0) { if (validatedArrayNoForceIds.length > 0) {
do_send_documents(order_id, validatedArrayNoForceIds, false); do_send_documents(order_id, validatedArrayNoForceIds, false);
} } else if (validatedArrayWithForceIds.length > 0) {
if (validatedArrayWithForceIds.length > 0) {
do_send_documents(order_id, validatedArrayWithForceIds, true); do_send_documents(order_id, validatedArrayWithForceIds, true);
} } else if (deniedArrayIds.length > 0){
if (deniedArrayIds.length > 0) {
do_deny_documents(order_id, deniedArrayIds); do_deny_documents(order_id, deniedArrayIds);
} }
}
dialogElem.dialog('close'); dialogElem.dialog('close');
} }
@@ -512,6 +577,9 @@ const orderItem = services => {
}); });
if (validatedArray.length > 0) { if (validatedArray.length > 0) {
$("#validation-window:visible .order-expireon-wrap").show();
$("#validation-window:visible input[name='expireOn']").blur();
let html = ''; let html = '';
html += html +=
'<h5>' + '<h5>' +
@@ -522,6 +590,7 @@ const orderItem = services => {
window.orderItemData.translatedText.item + window.orderItemData.translatedText.item +
(validatedArray.length === 1 ? '' : 's') + (validatedArray.length === 1 ? '' : 's') +
'</h5>'; '</h5>';
html += '<table class="validation-table">'; html += '<table class="validation-table">';
_.each(validatedArray, function (elem) { _.each(validatedArray, function (elem) {
html += '<tr>'; html += '<tr>';
@@ -537,6 +606,8 @@ const orderItem = services => {
}); });
html += '</table>'; html += '</table>';
$('.validation-content').append(html); $('.validation-content').append(html);
} else {
$("#validation-window:visible .order-expireon-wrap").hide();
} }
if (deniedArray.length > 0) { if (deniedArray.length > 0) {
@@ -688,11 +759,9 @@ const orderItem = services => {
function toggleValidationButton() { function toggleValidationButton() {
if (readyForValidation) { if (readyForValidation) {
$('button.validate').prop('disabled', false); $('button.validate').show();
$('button.validate').css('color', '#7CD21C');
} else { } else {
$('button.validate').prop('disabled', true); $('button.validate').hide();
$('button.validate').css('color', '#737373');
} }
} }
@@ -708,7 +777,49 @@ const orderItem = services => {
dataType: 'json', dataType: 'json',
data: { data: {
'elements[]': elements_ids, 'elements[]': elements_ids,
force: force ? 1 : 0 force: force ? 1 : 0,
expireOn: $('input[name="expireOn"]:visible').val()
},
success: function (data) {
let success = '0';
if (data.success) {
success = '1';
}
var url =
'../prod/order/' +
order_id +
'/?success=' +
success +
'&action=send';
reloadDialog(url);
},
error: function () {
$('button.deny, button.send', cont).prop('disabled', false);
$('.activity_indicator', cont).hide();
},
timeout: function () {
$('button.deny, button.send', cont).prop('disabled', false);
$('.activity_indicator', cont).hide();
}
});
}
function do_validate_documents(order_id, elements_send_ids, elements_deny_ids) {
let cont = $dialog.getDomElement();
$('button.deny, button.send', cont).prop('disabled', true);
$('.activity_indicator', cont).show();
$.ajax({
type: 'POST',
url: '../prod/order/' + order_id + '/validate/',
dataType: 'json',
data: {
'elementsSend[]': elements_send_ids,
'elementsDeny[]': elements_deny_ids,
expireOn: $('input[name="expireOn"]:visible').val()
}, },
success: function (data) { success: function (data) {
let success = '0'; let success = '0';
@@ -817,35 +928,35 @@ const orderItem = services => {
); );
let html = ''; let html = '';
if (countObj.validated > 0) { // if (countObj.validated > 0) {
html += // html +=
'<p>' + // '<p>' +
window.orderItemData.translatedText.itemsAlreadySent + // window.orderItemData.translatedText.itemsAlreadySent +
': ' + // ': ' +
countObj.validated + // countObj.validated +
'</p>'; // '</p>';
} // }
if (countObj.waitingForValidation > 0) { // if (countObj.waitingForValidation > 0) {
html += // html +=
'<p>' + // '<p>' +
window.orderItemData.translatedText.itemsWaitingValidation + // window.orderItemData.translatedText.itemsWaitingValidation +
': ' + // ': ' +
countObj.waitingForValidation + // countObj.waitingForValidation +
'</p>'; // '</p>';
} // }
//for the remaining items //for the remaining items
let remaining = let remaining =
countObj.selectable - countObj.selectable -
(countObj.validated + countObj.waitingForValidation); (countObj.validated + countObj.waitingForValidation);
if (remaining > 0) { if (remaining > 0) {
html += // html +=
'<p>' + // '<p>' +
window.orderItemData.translatedText.nonSentItems + // window.orderItemData.translatedText.nonSentItems +
': ' + // ': ' +
remaining + // remaining +
'</p>'; // '</p>';
$('#order-action button.deny, #order-action button.send').prop( $('#order-action button.deny, #order-action button.send').prop(
'disabled', 'disabled',
false false
@@ -855,8 +966,8 @@ const orderItem = services => {
).show(); ).show();
} }
$('#wrapper-multiple #text-content').empty(); // $('#wrapper-multiple #text-content').empty();
$('#wrapper-multiple #text-content').append(html); // $('#wrapper-multiple #text-content').append(html);
} }
/* * /* *

View File

@@ -336,6 +336,20 @@ span.ww_winTitle {
position: absolute; position: absolute;
} }
#ui-datepicker-div.expireOn {
z-index: 999999 !important;
}
#validation-window .ui-widget-content {
background-color: #fff;
a {
color: #282828;
&:hover {
color: #fff;
}
}
}
.ui-selectable-helper { .ui-selectable-helper {
border: 1px dotted #cccccc; border: 1px dotted #cccccc;
z-index: 10000; z-index: 10000;
@@ -508,7 +522,8 @@ span.ww_winTitle {
} }
#order_manager .order_list .selectable.selected { #order_manager .order_list .selectable.selected {
background-color: $darkerBorderColor; //background-color: $darkerBorderColor;
background-color: $darkBackgroundColor;
border: 1px solid #4990e2; border: 1px solid #4990e2;
} }
@@ -766,8 +781,8 @@ button.order_launcher.btn {
} }
#order-action { #order-action {
margin-top: 1.2em; margin : 0px 0px 1.2em 30px;
margin-bottom: 1.5em; text-align: left;
} }
#filter_box { #filter_box {
@@ -966,6 +981,10 @@ span.action-text {
} }
button.btn.validate { button.btn.validate {
background-color : #5bb75b;
background-image: linear-gradient(to bottom,#62c462,#51a351);
border-color: #51a351 #51a351 #387038;
color: #fff;
margin-bottom: 10px; margin-bottom: 10px;
font-size: 14px; font-size: 14px;
//border: 2px solid #f00; //border: 2px solid #f00;

View File

@@ -401,3 +401,9 @@ phraseanet-service:
clientSecret: 239zb7mhzmu8cgg48cgok8ww4ccokw0ck8kwow4ggw80s84koc clientSecret: 239zb7mhzmu8cgg48cgok8ww4ccokw0ck8kwow4ggw80s84koc
clientId: pull-local-test_3pj0iu clientId: pull-local-test_3pj0iu
verify_ssl: true verify_ssl: true
order-manager:
download-hd:
expiration-days: null
expiration-override: false

View File

@@ -55,7 +55,14 @@ class UserController extends Controller
public function listRecordAcl(Request $request) public function listRecordAcl(Request $request)
{ {
$rights = $this->getUserEditHelper($request); $rights = $this->getUserEditHelper($request);
$results = $rights->get_user_records_rights($request->query->get('userId'), $request->query->get('databoxId'), $request->query->get('recordId')); $expireRight = ($request->query->get('expiredRight') == 1) ? true : false ;
$results = $rights->get_user_records_rights(
$request->query->get('userId'),
$request->query->get('databoxId'),
$request->query->get('recordId'),
$request->query->get('type'),
$expireRight
);
return $this->app->json([ return $this->app->json([
'content' => $this->render('admin/user/records_list.html.twig', ['records_acl' => $results['records_acl']]), 'content' => $this->render('admin/user/records_list.html.twig', ['records_acl' => $results['records_acl']]),

View File

@@ -97,6 +97,11 @@ class Order implements ControllerProviderInterface, ServiceProviderInterface
->bind('prod_order_deny') ->bind('prod_order_deny')
->assert('order_id', '\d+'); ->assert('order_id', '\d+');
$controllers->post('/{order_id}/validate/', 'controller.prod.order:validateOrder')
->before($ensureOrdersAdmin)
->bind('prod_order_validate')
->assert('order_id', '\d+');
return $controllers; return $controllers;
} }
} }

View File

@@ -17,7 +17,7 @@ class Version
* @var string * @var string
*/ */
private $number = '4.1.7-rc2'; private $number = '4.1.7-rc3';
/** /**
* @var string * @var string

View File

@@ -265,7 +265,7 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper
]; ];
} }
public function get_user_records_rights($userId = null, $databoxId = null, $recordId = null) public function get_user_records_rights($userId = null, $databoxId = null, $recordId = null, $type = null, $expiredRight = false)
{ {
$rows = []; $rows = [];
$totalCount = 0; $totalCount = 0;
@@ -301,11 +301,20 @@ class Edit extends \Alchemy\Phrasea\Helper\Helper
$params[':record_id'] = $recordId; $params[':record_id'] = $recordId;
} }
if (!empty($type)) {
$whereClause .= " AND rr.case= :case";
$params[':case'] = $type;
}
if ($expiredRight) {
$whereClause .= " AND rr.expire_on < NOW()";
}
$sql = "SELECT rr.sbas_id, rr.record_id, rr.preview, rr.document, rr.`case` as type, \n" $sql = "SELECT rr.sbas_id, rr.record_id, rr.preview, rr.document, rr.`case` as type, \n"
. "IF(TRIM(p.last_name)!='' OR TRIM(p.first_name)!='', \n" . "IF(TRIM(p.last_name)!='' OR TRIM(p.first_name)!='', \n"
. " CONCAT_WS(' ', p.last_name, p.first_name),\n" . " CONCAT_WS(' ', p.last_name, p.first_name),\n"
. " IF(TRIM(p.email)!='', p.email, p.login)\n" . " IF(TRIM(p.email)!='', p.email, p.login)\n"
. ") as pusher_name\n" . ") as pusher_name, rr.expire_on\n"
. " FROM records_rights rr \n" . " FROM records_rights rr \n"
. " INNER JOIN sbas ON sbas.sbas_id = rr.sbas_id\n" . " INNER JOIN sbas ON sbas.sbas_id = rr.sbas_id\n"
. " JOIN Users as p ON p.id = rr.pusher_usr_id\n" . " JOIN Users as p ON p.id = rr.pusher_usr_id\n"

View File

@@ -145,4 +145,12 @@ class OrderRepository extends EntityRepository
return $builder->getQuery()->getSingleScalarResult(); return $builder->getQuery()->getSingleScalarResult();
} }
public function findAllTodo()
{
$qb = $this->createQueryBuilder('o');
$qb->where('o.todo != 0');
return $qb->getQuery()->getResult();
}
} }

View File

@@ -15,7 +15,7 @@ use Alchemy\Phrasea\Model\Entities\Basket;
use Alchemy\Phrasea\Exception\LogicException; use Alchemy\Phrasea\Exception\LogicException;
use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\Entities\User;
class MailInfoOrderDelivered extends AbstractMail class MailInfoOrderDelivered extends AbstractMailWithLink
{ {
/** @var Basket */ /** @var Basket */
private $basket; private $basket;

View File

@@ -144,9 +144,10 @@ class BaseOrderController extends Controller
* @param int $order_id * @param int $order_id
* @param array<int> $elementIds * @param array<int> $elementIds
* @param User $acceptor * @param User $acceptor
* @param \DateTime|null $expireDate
* @return BasketElement[] * @return BasketElement[]
*/ */
protected function doAcceptElements($order_id, $elementIds, User $acceptor) protected function doAcceptElements($order_id, $elementIds, User $acceptor, \DateTime $expireDate = null)
{ {
$elements = $this->findRequestedElements($order_id, $elementIds, $acceptor); $elements = $this->findRequestedElements($order_id, $elementIds, $acceptor);
$order = $this->findOr404($order_id); $order = $this->findOr404($order_id);
@@ -161,7 +162,25 @@ class BaseOrderController extends Controller
$this->assertRequestedElementsWereNotAlreadyAdded($basket, $basketElements); $this->assertRequestedElementsWereNotAlreadyAdded($basket, $basketElements);
$orderValidator->accept($acceptor, $partialOrder); $orderValidator->accept($acceptor, $partialOrder);
$orderValidator->grantHD($basket->getUser(), $basketElements); $expireOn = null;
if ($this->app['conf']->get(['order-manager', 'download-hd', 'expiration-override'], false)) {
if ($expireDate !== null) {
$expireOn = $expireDate->format(DATE_ATOM);
$expireDateTime = $expireDate;
}
} else {
$expirationDays = $this->app['conf']->get(['order-manager', 'download-hd', 'expiration-days'], 15);
try {
$expireDateTime = new \DateTime('+ '. $expirationDays . ' day');
$expireOn = $expireDateTime->format(DATE_ATOM);
} catch (\Exception $e) {
$expireDateTime = null;
$expireOn = null;
}
}
$orderValidator->grantHD($basket->getUser(), $basket->getPusher(), $basketElements, $expireOn);
try { try {
$manager = $this->getEntityManager(); $manager = $this->getEntityManager();
@@ -172,7 +191,7 @@ class BaseOrderController extends Controller
$manager->persist($element); $manager->persist($element);
} }
$delivery = new OrderDelivery($order, $acceptor, count($basketElements), $partialOrder); $delivery = new OrderDelivery($order, $acceptor, count($basketElements), $partialOrder, $expireDateTime);
$this->dispatch(PhraseaEvents::ORDER_DELIVER, new OrderDeliveryEvent($delivery)); $this->dispatch(PhraseaEvents::ORDER_DELIVER, new OrderDeliveryEvent($delivery));
} }

View File

@@ -164,7 +164,17 @@ class ProdOrderController extends BaseOrderController
$elementIds = $request->request->get('elements', []); $elementIds = $request->request->get('elements', []);
$acceptor = $this->getAuthenticatedUser(); $acceptor = $this->getAuthenticatedUser();
$basketElements = $this->doAcceptElements($order_id, $elementIds, $acceptor); if (empty($request->request->get('expireOn'))) {
$expireOn = null;
} else {
try {
$expireOn = new \DateTime($request->request->get('expireOn') . ' 23:59:59');
} catch (\Exception $e) {
$expireOn = null;
}
}
$basketElements = $this->doAcceptElements($order_id, $elementIds, $acceptor, $expireOn);
$success = !empty($basketElements); $success = !empty($basketElements);
@@ -216,5 +226,38 @@ class ProdOrderController extends BaseOrderController
]); ]);
} }
public function validateOrder(Request $request, $order_id)
{
$elementSendIds = $request->request->get('elementsSend', []);
$elementDenyIds = $request->request->get('elementsDeny', []);
$acceptor = $this->getAuthenticatedUser();
if (!empty($elementSendIds)) {
if (empty($request->request->get('expireOn'))) {
$expireOn = null;
} else {
try {
$expireOn = new \DateTime($request->request->get('expireOn') . ' 23:59:59');
} catch (\Exception $e) {
$expireOn = null;
}
}
$basketElements = $this->doAcceptElements($order_id, $elementSendIds, $acceptor, $expireOn);
}
if (!empty($elementDenyIds)) {
$elementsDeny = $this->doDenyElements($order_id, $elementDenyIds, $acceptor);
}
$success = !empty($basketElements) || !empty($elementsDeny);
return $this->app->json([
'success' => $success,
'msg' => $success
? $this->app->trans('Order has been sent')
: $this->app->trans('An error occured while sending, please retry or contact an admin if problem persists'),
'order_id' => $order_id,
]);
}
} }

View File

@@ -36,18 +36,22 @@ class OrderDelivery
*/ */
private $partialOrder; private $partialOrder;
private $expireOn;
/** /**
* @param Order $deliveredOrder * @param Order $deliveredOrder
* @param User $manager * @param User $manager
* @param int $quantity * @param int $quantity
* @param \DateTime $expireOn
* @param PartialOrder $partialOrder * @param PartialOrder $partialOrder
*/ */
public function __construct(Order $deliveredOrder, User $manager, $quantity, PartialOrder $partialOrder) public function __construct(Order $deliveredOrder, User $manager, $quantity, PartialOrder $partialOrder, \DateTime $expireOn = null)
{ {
$this->order = $deliveredOrder; $this->order = $deliveredOrder;
$this->admin = $manager; $this->admin = $manager;
$this->quantity = $quantity; $this->quantity = $quantity;
$this->partialOrder = $partialOrder; $this->partialOrder = $partialOrder;
$this->expireOn = $expireOn;
} }
/** /**
@@ -81,4 +85,9 @@ class OrderDelivery
{ {
return $this->partialOrder; return $this->partialOrder;
} }
public function getExpireOn()
{
return $this->expireOn;
}
} }

View File

@@ -100,9 +100,11 @@ class OrderValidator
/** /**
* @param User $user * @param User $user
* @param User $pusher
* @param BasketElement[] $elements * @param BasketElement[] $elements
* @param $expireOn
*/ */
public function grantHD(User $user, $elements) public function grantHD(User $user, User $pusher, $elements, $expireOn)
{ {
Assertion::allIsInstanceOf($elements, BasketElement::class); Assertion::allIsInstanceOf($elements, BasketElement::class);
@@ -114,7 +116,7 @@ class OrderValidator
$element->getRecordId() $element->getRecordId()
); );
$acl->grant_hd_on($recordReference, $user, \ACL::GRANT_ACTION_ORDER); $acl->grant_hd_on($recordReference, $pusher, \ACL::GRANT_ACTION_ORDER, $expireOn);
} }
} }

View File

@@ -17,7 +17,6 @@ use Alchemy\Phrasea\Model\Entities\User;
use Alchemy\Phrasea\Notification\Deliverer; use Alchemy\Phrasea\Notification\Deliverer;
use Alchemy\Phrasea\Notification\Emitter; use Alchemy\Phrasea\Notification\Emitter;
use Alchemy\Phrasea\Notification\Mail\MailInfoNewOrder; use Alchemy\Phrasea\Notification\Mail\MailInfoNewOrder;
use Alchemy\Phrasea\Notification\Mail\MailInfoOrderCancelled;
use Alchemy\Phrasea\Notification\Mail\MailInfoOrderDelivered; use Alchemy\Phrasea\Notification\Mail\MailInfoOrderDelivered;
use Alchemy\Phrasea\Notification\Receiver; use Alchemy\Phrasea\Notification\Receiver;
use Alchemy\Phrasea\Order\OrderDelivery; use Alchemy\Phrasea\Order\OrderDelivery;
@@ -80,9 +79,8 @@ class MailNotifier implements ValidationNotifier
'LOG' => $token->getValue(), 'LOG' => $token->getValue(),
]); ]);
$mail = MailInfoOrderDelivered::create($this->application, $recipient, $sender, null); $mail = MailInfoOrderDelivered::create($this->application, $recipient, $sender, null, $url, $delivery->getExpireOn());
$mail->setButtonUrl($url);
$mail->setBasket($basket); $mail->setBasket($basket);
$mail->setDeliverer($delivery->getAdmin()); $mail->setDeliverer($delivery->getAdmin());

View File

@@ -60,7 +60,7 @@ class PhraseanetExtension extends \Twig_Extension
{ {
return [ return [
// change this version when you change JS file to force the navigation to reload js file // change this version when you change JS file to force the navigation to reload js file
'assetFileVersion' => 74 'assetFileVersion' => 75
]; ];
} }

View File

@@ -221,23 +221,33 @@ class ACL implements cache_cacheableInterface
return false; return false;
} }
public function grant_hd_on(RecordReferenceInterface $record, User $pusher, $action) public function grant_hd_on(RecordReferenceInterface $record, User $pusher, $action, $expireOn = null)
{ {
static $stmt = null; static $stmt = null;
if(!$stmt) { if(!$stmt) {
$sql = "REPLACE INTO records_rights\n" $sql = "REPLACE INTO records_rights\n"
. " (id, usr_id, sbas_id, record_id, document, `case`, pusher_usr_id)\n" . " (id, usr_id, sbas_id, record_id, document, `case`, pusher_usr_id, expire_on)\n"
. " VALUES (null, :usr_id, :sbas_id, :record_id, 1, :case, :pusher)"; . " VALUES (null, :usr_id, :sbas_id, :record_id, 1, :case, :pusher, :expireOn)";
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
} }
if (!empty($expireOn)) {
try {
$expireOn = (new DateTime($expireOn))->format(DATE_ATOM);
} catch (\Exception $e) {
$expireOn = null;
}
}
$params = [ $params = [
':usr_id' => $this->user->getId(), ':usr_id' => $this->user->getId(),
':sbas_id' => $record->getDataboxId(), ':sbas_id' => $record->getDataboxId(),
':record_id' => $record->getRecordId(), ':record_id' => $record->getRecordId(),
':case' => $action, ':case' => $action,
':pusher' => $pusher->getId() ':pusher' => $pusher->getId(),
':expireOn' => $expireOn
]; ];
$stmt->execute($params); $stmt->execute($params);
$stmt->closeCursor(); $stmt->closeCursor();
@@ -1064,11 +1074,10 @@ class ACL implements cache_cacheableInterface
/** /**
* Load if needed the elements which have a HD grant * Load if needed the elements which have a HD grant
* *
* @return Array * @return ACL
*/ */
protected function load_hd_grant() protected function load_hd_grant()
{ {
if ($this->_rights_records_preview) { if ($this->_rights_records_preview) {
return $this; return $this;
} }
@@ -1082,7 +1091,7 @@ class ACL implements cache_cacheableInterface
} catch (\Exception $e) { } catch (\Exception $e) {
} }
$sql = "SELECT sbas_id, record_id, preview, document FROM records_rights WHERE usr_id = :usr_id"; $sql = "SELECT sbas_id, record_id, preview, document, expire_on FROM records_rights WHERE usr_id = :usr_id";
$stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql); $stmt = $this->app->getApplicationBox()->get_connection()->prepare($sql);
$stmt->execute([':usr_id' => $this->user->getId()]); $stmt->execute([':usr_id' => $this->user->getId()]);
@@ -1093,10 +1102,23 @@ class ACL implements cache_cacheableInterface
$this->_rights_records_preview = []; $this->_rights_records_preview = [];
$this->_rights_records_document = []; $this->_rights_records_document = [];
$dateNow = new DateTime("now");
foreach ($rs as $row) { foreach ($rs as $row) {
$currentid = $row["sbas_id"] . "_" . $row["record_id"]; $currentid = $row["sbas_id"] . "_" . $row["record_id"];
if ($row['document'] == '1') if (!empty($row['expire_on'])) {
try {
$expireOn = new DateTime($row['expire_on']);
if ($expireOn < $dateNow) {
continue;
}
} catch (\Exception $e) {
}
}
if ($row['document'] == '1') {
$this->_rights_records_document[$currentid] = $currentid; $this->_rights_records_document[$currentid] = $currentid;
}
$this->_rights_records_preview[$currentid] = $currentid; $this->_rights_records_preview[$currentid] = $currentid;
} }

View File

@@ -0,0 +1,108 @@
<?php
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Configuration\PropertyAccess;
use Alchemy\Phrasea\Model\Repositories\OrderRepository;
use Alchemy\Phrasea\Model\Entities\Order;
class patch_417RC3PHRAS3783 implements patchInterface
{
/** @var string */
private $release = '4.1.7-rc3';
/** @var array */
private $concern = [base::APPLICATION_BOX];
/**
* {@inheritdoc}
*/
public function get_release()
{
return $this->release;
}
/**
* {@inheritdoc}
*/
public function getDoctrineMigrations()
{
return [];
}
/**
* {@inheritdoc}
*/
public function require_all_upgrades()
{
return false;
}
/**
* {@inheritdoc}
*/
public function concern()
{
return $this->concern;
}
/**
* {@inheritdoc}
*/
public function apply(base $base, Application $app)
{
if ($base->get_base_type() === base::DATA_BOX) {
$this->patch_databox($base, $app);
}
elseif ($base->get_base_type() === base::APPLICATION_BOX) {
$this->patch_appbox($base, $app);
}
return true;
}
private function patch_databox(databox $databox, Application $app)
{
}
private function patch_appbox(base $appbox, Application $app)
{
$cnx = $appbox->get_connection();
/** @var PropertyAccess $conf */
$conf = $app['conf'];
// add new conf if not exist
// default value to 15 days ??
// or null for download never expired
if (!$conf->has(['order-manager', 'download-hd', 'expiration-days'])) {
$conf->set(['order-manager', 'download-hd', 'expiration-days'], 15);
}
if (!$conf->has(['order-manager', 'download-hd', 'expiration-override'])) {
$conf->set(['order-manager', 'download-hd', 'expiration-override'], false);
}
// needed to expire existing order download ???
$expirationDays = $app['conf']->get(['order-manager', 'download-hd', 'expiration-days'], 15);
$expireOn = (new \DateTime('+ '. $expirationDays .' day'))->format(DATE_ATOM);
$sql = 'UPDATE `records_rights` SET `expire_on` = :expire_on WHERE `case` = "order" AND `expire_on` IS NULL';
$stmt = $cnx->prepare($sql);
$stmt->execute([':expire_on' => $expireOn]);
$stmt->closeCursor();
// get all todoorder an set column to 0 if all element are processed
/** @var OrderRepository $orderRepository */
$orderRepository = $app['repo.orders'];
/** @var Order $order */
foreach ($orderRepository->findAllTodo() as $order) {
if ($order->getTotalTreatedItems() == $order->getTotal()) {
//all element processed
$order->setTodo(0);
$app['orm.em']->persist($order);
}
}
$app['orm.em']->flush();
}
}

View File

@@ -905,6 +905,14 @@
<comment></comment> <comment></comment>
<collation></collation> <collation></collation>
</field> </field>
<field>
<name>expire_on</name>
<type>datetime</type>
<null>yes</null>
<extra></extra>
<default></default>
<comment></comment>
</field>
</fields> </fields>
<indexes> <indexes>
<index> <index>

View File

@@ -739,6 +739,10 @@
<div id="record_acl_tab"> <div id="record_acl_tab">
<h1>User record acl</h1> <h1>User record acl</h1>
<div style="margin-bottom: 20px;"> <div style="margin-bottom: 20px;">
<label class="checkbox" for="expired-right" style="display:inline-block;margin-right: 30px;">
<input type="checkbox" id="expired-right" name="expired-right" value="1">
expired right
</label>
<select id="acl-databox-filter"> <select id="acl-databox-filter">
<option value="">{{ 'button::choose databox' | trans }}</option> <option value="">{{ 'button::choose databox' | trans }}</option>
{% for databoxId in databoxIds %} {% for databoxId in databoxIds %}
@@ -746,6 +750,13 @@
{% endfor %} {% endfor %}
</select> </select>
<select id="acl-type-filter" style="margin-bottom: 0px;margin-left: 30px;">
<option value="">{{ 'button::choose type' | trans }}</option>
<option value="order">order</option>
<option value="push">push</option>
<option value="validate">validate</option>
</select>
<input type="number" id="acl-record-filter" placeholder="recordId" style="margin-bottom: 0px;margin-left: 30px;"> <input type="number" id="acl-record-filter" placeholder="recordId" style="margin-bottom: 0px;margin-left: 30px;">
</div> </div>
@@ -759,6 +770,7 @@
<th>right on subdef</th> <th>right on subdef</th>
<th>type</th> <th>type</th>
<th>pusher name</th> <th>pusher name</th>
<th>expire on</th>
</tr> </tr>
</thead> </thead>
<tbody id="record_acl_list"> <tbody id="record_acl_list">
@@ -770,6 +782,18 @@
<td>{{ r_a.preview }}</td> <td>{{ r_a.preview }}</td>
<td>{{ r_a.type }}</td> <td>{{ r_a.type }}</td>
<td>{{ r_a.pusher_name }}</td> <td>{{ r_a.pusher_name }}</td>
<td>
{% if r_a.expire_on %}
{{ r_a.expire_on|date('Y-m-d H:i:s') }}
{% if r_a.expire_on|date('Y-m-d H:i:s') > "now"|date('Y-m-d H:i:s') %}
<i class="fa fa-check" aria-hidden="true" style="color:#7cd21c;"></i>
{% else %}
<i class="fa fa-times" aria-hidden="true" style="color:#d1051f;"></i>
{% endif %}
{% else %}
- <i class="fa fa-check" aria-hidden="true" style="color:#7cd21c"></i>
{% endif %}
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@@ -1466,12 +1490,20 @@
}); });
function listRecordAcl() { function listRecordAcl() {
let expiredRight = 0;
if ($("#expired-right").is(":checked"))
{
expiredRight = 1;
}
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: "/admin/users/records-acl/", url: "/admin/users/records-acl/",
data: { data: {
databoxId : $("#acl-databox-filter").val(), databoxId : $("#acl-databox-filter").val(),
recordId : $("#acl-record-filter").val(), recordId : $("#acl-record-filter").val(),
expiredRight: expiredRight,
type: $("#acl-type-filter").val(),
userId: {{ main_user.getId() }} userId: {{ main_user.getId() }}
}, },
success: function (data) { success: function (data) {
@@ -1521,6 +1553,14 @@
listRecordAcl(); listRecordAcl();
}); });
$("#expired-right").on('change', function () {
listRecordAcl();
});
$("#acl-type-filter").on('change', function () {
listRecordAcl();
});
$("#basket-databox-filter").on('change', function() { $("#basket-databox-filter").on('change', function() {
listRecordBasket(); listRecordBasket();
}); });

View File

@@ -6,6 +6,18 @@
<td>{{ r_a.preview }}</td> <td>{{ r_a.preview }}</td>
<td>{{ r_a.type }}</td> <td>{{ r_a.type }}</td>
<td>{{ r_a.pusher_name }}</td> <td>{{ r_a.pusher_name }}</td>
<td>
{% if r_a.expire_on %}
{{ r_a.expire_on|date('Y-m-d H:i:s') }}
{% if r_a.expire_on|date('Y-m-d H:i:s') > "now"|date('Y-m-d H:i:s') %}
<i class="fa fa-check" aria-hidden="true" style="color:#7cd21c;"></i>
{% else %}
<i class="fa fa-times" aria-hidden="true" style="color:#d1051f;"></i>
{% endif %}
{% else %}
- <i class="fa fa-check" aria-hidden="true" style="color:#7cd21c"></i>
{% endif %}
</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -314,6 +314,13 @@
</div> </div>
</div> </div>
<div class="control-group">
<label class="control-label" for="usr_mail"> {{ 'admin::compte-utilisateur email' | trans }}</label>
<div class="controls">
<input class="required" type="text" name="usr_mail" id="usr_mail" value="{{ app.getAuthenticatedUser().getEmail() }}"/>
</div>
</div>
<div class="control-group"> <div class="control-group">
<label class="control-label" for="sexe">{{ 'Civility' | trans }}</label> <label class="control-label" for="sexe">{{ 'Civility' | trans }}</label>
<div class="controls"> <div class="controls">
@@ -339,13 +346,6 @@
</div> </div>
</div> </div>
<div class="control-group">
<label class="control-label" for="usr_mail"> {{ 'admin::compte-utilisateur email' | trans }}</label>
<div class="controls">
<input class="required" type="text" name="usr_mail" id="usr_mail" value="{{ app.getAuthenticatedUser().getEmail() }}"/>
</div>
</div>
<div class="control-group"> <div class="control-group">
<label class="control-label" for="usr_tel">{{ 'admin::compte-utilisateur telephone' | trans }}</label> <label class="control-label" for="usr_tel">{{ 'admin::compte-utilisateur telephone' | trans }}</label>
<div class="controls"> <div class="controls">
@@ -388,13 +388,6 @@
</div> </div>
</div> </div>
<div class="control-group">
<label class="control-label" for="usr_fax">{{ 'admin::compte-utilisateur fax' | trans }}</label>
<div class="controls">
<input type="text" id="usr_fax" name="fax" value="{{ app.getAuthenticatedUser().getFax() }}"/>
</div>
</div>
{% if app['conf'].get(['registry', 'actions', 'tou-validation-required-for-export']) == true %} {% if app['conf'].get(['registry', 'actions', 'tou-validation-required-for-export']) == true %}
<div class="well-small acceptDl-info"> <div class="well-small acceptDl-info">
<label for="TOU_acceptOrder" class="checkbox"> <label for="TOU_acceptOrder" class="checkbox">
@@ -406,7 +399,7 @@
</div> </div>
{% endif %} {% endif %}
<div class="form_actions buttons_line"> <div class="form_actions buttons_line" style="margin-left: 30px;">
<button type="button" class="order_button btn btn-primary">{{ 'boutton::commander' | trans }}</button> <button type="button" class="order_button btn btn-primary">{{ 'boutton::commander' | trans }}</button>
<img class="order_button_loader" src="/assets/common/images/icons/loader404040.gif" style="visibility:hidden;margin:0 5px;"/> <img class="order_button_loader" src="/assets/common/images/icons/loader404040.gif" style="visibility:hidden;margin:0 5px;"/>
<button type="button" class="close_button btn btn-inverse">{{ 'boutton::annuler' | trans }}</button> <button type="button" class="close_button btn btn-inverse">{{ 'boutton::annuler' | trans }}</button>

View File

@@ -26,6 +26,32 @@
<div style="display:none;position:relative;" id="validation-window" > <div style="display:none;position:relative;" id="validation-window" >
<div class="box"> <div class="box">
<div class="order-expireon-wrap">
<span class="ui-helper-hidden-accessible"><input type="text"/></span>
<span>{{ 'prod::order-manager download expire on' | trans }}:</span>
<span style="font-size: 0;">
{% set canOverride = app['conf'].get(['order-manager', 'download-hd', 'expiration-override']) ? true : false %}
<input type="text" class="expireOn btn" name="expireOn" autocomplete="off"
style="width: 100px; margin: 0;background-image: none; border-right: 0;border-top-right-radius: 0;border-bottom-right-radius: 0;"
{% if not canOverride %} disabled {% endif %}
data-default-expiration="{{ app['conf'].get(['order-manager', 'download-hd', 'expiration-days']) }}"
/>
<button class="expireOn-menu"
style="border-radius: 0px 13px 13px 0px;height: 30px;border: 1px solid transparent;"
{% if not canOverride %} disabled {% endif %} >
<i class="fa fa-ellipsis-h"></i>
</button>
</span>
<ul id="expire-menu"
style="position:fixed; z-index: 999999; width:80px; height:auto; display:block; top:-1000px;">
<li data-expireon="+7"><a href="#">7 days</a></li>
<li data-expireon="+15"><a href="#">15 days</a></li>
<li data-expireon="+20"><a href="#">20 days</a></li>
<li data-expireon="+30"><a href="#">30 days</a></li>
<li data-expireon="+60"><a href="#">60 days</a></li>
<li data-expireon=""><a href="#">no limitation</a></li>
</ul>
</div>
<div class="validation-content" style="float:left; width:100%;margin-top:10px;"> <div class="validation-content" style="float:left; width:100%;margin-top:10px;">
</div> </div>
</div> </div>
@@ -103,8 +129,8 @@
</td> </td>
</tr> </tr>
</table> </table>
<button class="btn validate outline" disabled><i class="fa fa-check-circle-o" <button class="btn validate outline" style="display:none;"><i class="fa fa-check-circle-o" aria-hidden="true">
aria-hidden="true"></i>{{ 'order-manager::order-item: validate' |trans }} </i>{{ 'order-manager::order-item: validate' |trans }}
</button> </button>
<div class="order-list-container"> <div class="order-list-container">
<div class="order_list" style="width:40%;float:left"> <div class="order_list" style="width:40%;float:left">
@@ -146,7 +172,7 @@
{% trans %}Forcer l'envoi du document{% endtrans %} {% trans %}Forcer l'envoi du document{% endtrans %}
{% endset %} {% endset %}
<img style="cursor:help;" src="/assets/common/images/icons/delete.png" title="{% spaceless %}{{title|e}}{% endspaceless %}" /> <img style="cursor:help;" src="/assets/common/images/icons/delete.png" title="{% spaceless %}{{title|e}}{% endspaceless %}" />
<img style="cursor:pointer;" class="force_sender" src="/assets/common/images/icons/reload.png" title="{% spaceless %}{{title_send|e}}{% endspaceless %}" /> {# <img style="cursor:pointer;" class="force_sender" src="/assets/common/images/icons/reload.png" title="{% spaceless %}{{title_send|e}}{% endspaceless %}" />#}
{% else %} {% else %}
{% set title %} {% set title %}
{% trans with {'%name%' : name} %}Document envoye par %name%{% endtrans %} {% trans with {'%name%' : name} %}Document envoye par %name%{% endtrans %}
@@ -207,14 +233,6 @@
</div> </div>
</div> </div>
<div id="wrapper-multiple"> <div id="wrapper-multiple">
<div id="preview-layout-multiple">
<span class="title">0</span>
<h4 class="sub-title">{{ 'order-manager::order-item: selected-records' | trans }}</h4>
<img class="record record_image imgTips zoomable thumb" oncontextMenu="return(false);"
style="width:150px;height:150px;"
src="/assets/common/images/icons/substitution/image_jpg.png" ondragstart="return false;"/>
<div id="text-content"></div>
</div>
<div id="order-action" style="color:#333;"> <div id="order-action" style="color:#333;">
<button class="btn deny outline"><i class="fa fa-times" <button class="btn deny outline"><i class="fa fa-times"
aria-hidden="true"></i>{{ 'Deny' | trans }}</button> aria-hidden="true"></i>{{ 'Deny' | trans }}</button>
@@ -227,6 +245,15 @@
<img src="/assets/common/images/icons/loader000000.gif" class="activity_indicator" style="display:none;"/> <img src="/assets/common/images/icons/loader000000.gif" class="activity_indicator" style="display:none;"/>
<input name="order_id" type="hidden" value="{{ order.getId() }}" /> <input name="order_id" type="hidden" value="{{ order.getId() }}" />
</div> </div>
<div id="preview-layout-multiple">
<span class="title">0</span>
<h4 class="sub-title">{{ 'order-manager::order-item: selected-records' | trans }}</h4>
<img class="record record_image imgTips zoomable thumb" oncontextMenu="return(false);"
style="width:150px;height:150px;"
src="/assets/common/images/icons/substitution/image_jpg.png" ondragstart="return false;"/>
<div id="text-content"></div>
</div>
</div> </div>
<div id="wrapper-no-item"> <div id="wrapper-no-item">
<img style="width:150px;height:150px;" src="/assets/common/images/icons/substitution/image_jpg.png"> <img style="width:150px;height:150px;" src="/assets/common/images/icons/substitution/image_jpg.png">