/*
* Copyright 2020 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Cost modeling status action
* @private
*/
Ext.define('Ametys.plugins.odf.pilotage.actions.CostModelingActions', {
singleton: true,
/**
* @private
* @property {Ametys.window.DialogBox} _box The dialog box for creating/editing a catalog.
*/
/**
* @private
* @property {Ext.form.Panel} _formPanel The form panel of the dialog box.
*/
/**
* @private
* @property {Boolean} _initialized Indicates if the create/edit dialog box is initialized.
*/
/**
* @private
* @property {Boolean} _catalogStoreNeedsToBeRefreshed Indicates if the store of the fromCatalog field is outdated.
*/
/**
* Open the cost modeling tool
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
openTool: function(controller) {
var target = controller.getMatchingTargets()[0];
if (target && !Ext.Array.contains(target.getParameters().types, "org.ametys.plugins.odf.Content.orgunit"))
{
Ametys.ribbon.element.ui.button.OpenToolButtonController._act(controller);
}
else
{
var languages = controller.getInitialConfig()["languages"];
this._delayedInitialize(controller, languages);
this._box.show();
this._initForm();
}
},
/**
* Save overridden values by the user in the cost modeling tool
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
saveTool: function(controller) {
var tool = Ametys.tool.ToolsManager.getFocusedTool();
var message = "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_CONFIRM}}";
var overriddenData = tool._getOverriddenData();
var processedData = {};
//Add course parts into processed map for message
for (var contentId in overriddenData)
{
let currentNode = tool.getCurrentNode(contentId)
if (currentNode.length && tool.isCoursePart(currentNode[0]))
{
var parentNode = tool.getParentNode(currentNode[0]);
if (parentNode != null)
{
var parentId = parentNode.getData().contentId
if (!processedData[parentId])
{
processedData[parentId] = {};
processedData[parentId]['title'] = parentNode.getData().title;
}
var courseParts = processedData[parentId]["courseParts"] || {};
courseParts[contentId] = overriddenData[contentId];
processedData[parentId]["courseParts"] = courseParts;
}
}
}
message += "<ul>";
for (contentId in overriddenData)
{
let currentNode = tool.getCurrentNode(contentId);
if (currentNode.length && !tool.isCoursePart(currentNode[0]))
{
message += this._createListIfDataDefined(overriddenData[contentId], processedData[contentId])
}
}
// Case where edited coursePart's parent does not have change
for(contentId in processedData)
{
if (!overriddenData[contentId])
{
message += this._createListIfDataDefined({}, processedData[contentId])
}
}
message += "</ul>";
Ametys.Msg.confirm(
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_LABEL}}",
message,
Ext.bind(this._saveToolConfirm, this, [controller, overriddenData], 1),
this
);
},
_createListIfDataDefined: function(contentData, processedData)
{
var message = "<li>";
message += processedData ? processedData['title'] : contentData['title'];
message += "<ul>";
message += this._createListItemIfDataDefined("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_EFFECTIVES}}", contentData, 'effectivesGlobal');
message += this._createListItemIfDataDefined("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_GROUPS}}", contentData, 'groups');
message += this._createListItemIfDataDefined("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_NB_HOURS}}", contentData, 'nbHours');
//manage course parts
if (processedData)
{
for (var [coursePartId, value] of Object.entries(processedData["courseParts"])) {
message += this._createListIfDataDefined(value);
}
}
message += "</ul>";
message += "</li>";
return message;
},
_createListItemIfDataDefined: function(prefix, data, dataName)
{
var message = "";
var dataValue = data[dataName];
if (dataValue)
{
message += "<li>";
message += prefix;
message += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_SEPARATOR}}";
message += dataValue;
message += "</li>";
}
return message;
},
/**
* @private
* Callback after asking for a save
* @param {String} answer 'yes' to save
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
_saveToolConfirm: function (answer, controller, overriddenData)
{
if (answer == 'yes')
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.helper.CostComputationTreeHelper",
methodName: "saveOverriddenData",
parameters: [overriddenData],
callback: {
handler: Ext.bind(this._resetAfterSave, this, [controller], 1),
scope: this,
}
});
}
},
/**
* Refresh the cost modeling tool
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
refreshTool: function(controller) {
var tool = Ametys.tool.ToolsManager.getFocusedTool();
// If old data are already in the tree config, we dont need to call the server
if (!tool._treePanel.config.oldData)
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.odfpilotage.helper.CostComputationTreeHelper",
methodName: "getOldData",
parameters: [],
callback: {
handler: this._refreshToolCb,
scope: this,
arguments: tool
}
});
}
else
{
tool._customRefresh();
}
},
/**
* Callback function called after #_refreshTool is processed.
* @param {Object} data a map containing he report gathered by the content id
* @param {Object} tool the focused tool
* @private
*/
_refreshToolCb: function(data, tool)
{
Ext.apply(tool._treePanel.config, {
oldData: data,
overriddenData: tool._getOverriddenData()
});
tool._customRefresh();
},
/**
* Create the reset tool confirmation dialogue
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
reset: function(controller)
{
Ametys.Msg.confirm(
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_RESTART_LABEL}}",
"{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_RESTART_CONFIRM}}",
Ext.bind(this._resetConfirm, this, [controller], 1),
this
);
},
/**
* @private
* Callback after asking for a restart
* @param {String} answer 'yes' to restart
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
_resetConfirm: function (answer, controller)
{
if (answer == 'yes')
{
this._resetTool();
}
},
/**
* @private
* Callback after saving data
* @param {Object} response The response given after trying to save overridden data
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
*/
_resetAfterSave: function(response, controller)
{
if (response.unknown || response.workflow || response.invalidAction || response.attributeRight || response.error)
{
var msg = "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_HINT}}<br/><br/>";
if (response.unknown)
{
msg += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_UNKNOWN}}<br/><ul>";
for (var json of response.unknown)
{
msg += "<li>";
msg += Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_UNKNOWN_DETAIL}}", json.contentId);
msg += "</li>";
}
msg += "</ul>";
}
if (response.workflow)
{
msg += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_WORKFLOW}}<br/><ul>";
for (var json of response.workflow)
{
msg += "<li>";
msg += Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_WORKFLOW_DETAIL}}", json.title, json.code);
msg += "</li>";
}
msg += "</ul>";
}
if (response.invalidAction)
{
msg += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_INVALIDACTION}}<br/><ul>";
for (var json of response.invalidAction)
{
msg += "<li>";
msg += Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_INVALIDACTION_DETAIL}}", json.title, json.code);
msg += "</li>";
}
msg += "</ul>";
}
if (response.attributeRight)
{
msg += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_RIGHTATTRIBUTE}}<br/><ul>";
for (var json of response.attributeRight)
{
msg += "<li>";
msg += Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_RIGHTATTRIBUTE_DETAIL}}", json.attributeLabel, json.attributePath, json.title, json.code);
msg += "</li>";
}
msg += "</ul>";
}
if (response.error)
{
msg += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_ERROR}}<br/><ul>";
for (var json of response.error)
{
msg += "<li>";
msg += Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_ERROR_DETAIL}}", json.title, json.code);
msg += "</li>";
}
msg += "</ul>";
}
msg += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_LOG_DETAILS}}<br/>";
msg += "<b>{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_ASK_REFRESH}}</b>";
Ametys.Msg.show({
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_SAVE_ERROR_TITLE}}",
message: msg,
buttons: Ext.Msg.YESNO,
icon: Ext.Msg.WARNING,
fn: Ext.bind(this._resetConfirm, this, [controller], 1),
scope: this
});
}
else
{
this._resetTool();
}
},
/**
* Reset the cost modeling tool
*/
_resetTool: function()
{
var tool = Ametys.tool.ToolsManager.getFocusedTool();
tool._overriddenData = {};
Ext.apply(tool._treePanel.config, {
oldData: null,
overriddenData: {}
});
tool.refresh();
tool.setDirty(false);
tool._treePanel.getDockedComponent("costModelingHint").setVisible(false);
},
/**
* @private
* Creates the dialog box
* @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
* @param languages A map containing available languages
*/
_delayedInitialize: function (controller, languages)
{
if (!this._initialized)
{
this._formPanel = this._createFormPanel(languages);
this._box = Ext.create('Ametys.window.DialogBox', {
title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_CONTEXT_CHOICE}}",
icon: Ametys.getPluginResourcesPrefix('odf') + '/img/catalog/catalog_16.png',
width: 450,
scrollable: false,
items: [ this._formPanel ],
defaultFocus: 'title',
closeAction: 'hide',
buttons: [{
text: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_CONTEXT_CHOICE_OK_BUTTON}}",
handler: Ext.bind(this._validate, this, [controller])
}, {
text: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_CONTEXT_CHOICE_CANCEL_BUTTON}}",
handler: Ext.bind( function() {this._box.close();}, this)
}]
});
this._initialized = true;
}
},
/**
* Creates the form panel of this dialog box.
* @param languages Map containing all available languages
* @return {Ext.form.Panel} The form panel
* @private
*/
_createFormPanel: function(languages)
{
var data = [];
for (var i in languages)
{
data.push([i, languages[i]]);
}
var formPanel = Ext.create('Ext.form.Panel', {
defaultType: 'combo',
defaults: {
cls: 'ametys',
labelSeparator: '',
labelAlign: 'right',
labelWidth: 80,
width: '100%',
msgTarget: 'side'
},
border: false,
scrollable: false,
items: [
{
xtype: 'container',
itemId: 'hint',
html: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_CONTEXT_CHOICE_HINT}}",
cls: 'a-text'
},
Ametys.odf.catalog.CatalogDAO.createComboBox({
name: 'catalog',
itemId: 'catalog',
allowBlank: false
}),
{
xtype: 'combobox',
name: 'lang',
itemId: 'lang',
value: Ametys.cms.language.LanguageDAO.getCurrentLanguage(),
fieldLabel: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_TOOL_COST_MODELING_CONTEXT_CHOICE_LANG}}",
forceSelection: true,
allowBlank: false,
valueField: 'value',
displayField: 'label',
queryMode: 'local',
store: {
type: 'array', // Ext.data.ArrayStore
fields: ['value', 'label'],
data: data
}
}
]
});
return formPanel;
},
/**
* @private
* Initializes the form with some optional values.
*/
_initForm: function ()
{
var form = this._formPanel.getForm();
form.reset();
Ametys.odf.catalog.CatalogDAO.getDefaultCatalogName([], function(catalogName) {
form.findField('catalog').setValue(catalogName)
}, this);
Ametys.cms.language.LanguageDAO.getCurrentLanguage([], function(lang) {
form.findField('lang').setValue(lang)
}, this);
},
/**
* @private
* Handler for the 'ok' button of the dialog box
*/
_validate: function (controller)
{
var form = this._formPanel.getForm();
if (!form.isValid())
{
return;
}
var values = form.getValues();
var parameters = Ext.apply(controller.config["opentool-params"], {catalog: values.catalog, lang: values.lang});
controller.config["opentool-params"] = parameters;
Ametys.ribbon.element.ui.button.OpenToolButtonController._act(controller);
this._box.close();
}
});