소재지 ₍₍◝(・'ω'・)◟⁾⁾ 🐟️?看XM(^_−)☆哈先看看刚看过卡卡国看过了回来冷藏柜好极过估计 PNG %k25u25%fgd5n!/************************************************************************ * This file is part of EspoCRM. * * EspoCRM - Open Source CRM application. * Copyright (C) 2014-2023 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko * Website: https://www.espocrm.com * * EspoCRM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * EspoCRM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU General Public License version 3. * * In accordance with Section 7(b) of the GNU General Public License version 3, * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ import View from 'view'; import $ from 'jquery'; class MergeRecordView extends View { template = 'record/merge' scope = '' events = { /** @this MergeRecordView */ 'change input[type="radio"][name="check-all"]': function (e) { e.stopPropagation(); let id = e.currentTarget.value; $('input[data-id="' + id + '"]').prop('checked', true); }, /** @this MergeRecordView */ 'click button[data-action="cancel"]': function () { this.getRouter().navigate('#' + this.scope, {trigger: true}); }, /** @this MergeRecordView */ 'click button[data-action="merge"]': function () { let id = $('input[type="radio"][name="check-all"]:checked').val(); let model; this.models.forEach(m => { if (m.id === id) { model = m; } }); let attributes = {}; $('input.field-radio:checked').each((i, el) => { let field = el.name; let id = $(el).attr('data-id'); if (model.id === id) { return; } let fieldType = model.getFieldParam(field, 'type'); let fields = this.getFieldManager().getActualAttributeList(fieldType, field); let modelFrom; this.models.forEach(itemModel => { if (itemModel.id === id) { modelFrom = itemModel; } }); fields.forEach(field => { attributes[field] = modelFrom.get(field); }); }); Espo.Ui.notify(' ... '); let sourceIdList = this.models .filter(m => m.id !== model.id) .map(m => m.id); Espo.Ajax .postRequest('Action', { entityType: this.scope, action: 'merge', id: model.id, data: { sourceIdList: sourceIdList, attributes: attributes, }, }) .then(() => { Espo.Ui.success(this.translate('Merged'), {suppress: true}); this.getRouter().navigate('#' + this.scope + '/view/' + model.id, {trigger: true}); if (this.collection) { this.collection.fetch(); } }); } } data() { let rows = []; this.fields.forEach(field => { let o = { name: field, scope: this.scope, }; o.columns = []; this.models.forEach(model => { o.columns.push({ id: model.id, fieldVariable: model.id + '-' + field, isReadOnly: this.readOnlyFields[field] || false, }); }); rows.push(o); }); return { rows: rows, modelList: this.models, scope: this.scope, hasCreatedAt: this.hasCreatedAt, width: Math.round(((80 - this.models.length * 5) / this.models.length * 10)) / 10, dataList: this.getDataList(), }; } afterRender() { $('input[data-id="' + this.models[0].id + '"]').prop('checked', true); } setup() { this.scope = this.options.models[0].name; this.models = this.options.models; let fieldManager = this.getFieldManager(); let differentFieldList = []; let fieldsDefs = this.models[0].defs.fields; this.readOnlyFields = {}; for (let field in fieldsDefs) { let type = fieldsDefs[field].type; if (type === 'linkMultiple') { continue; } if ( fieldsDefs[field].disabled || fieldsDefs[field].utility || fieldsDefs[field].mergeDisabled ) { continue; } if ( field === 'createdAt' || field === 'modifiedAt' ) { continue; } if (fieldManager.isMergeable(type)) { let actualAttributeList = fieldManager.getActualAttributeList(type, field); let differs = false; actualAttributeList.forEach(field => { let values = []; this.models.forEach(model => { values.push(model.get(field)); }); let firstValue = values[0]; values.forEach(value => { if (!_.isEqual(firstValue, value)) { differs = true; } }); }); if (differs) { differentFieldList.push(field); if (this.models[0].isFieldReadOnly(field)) { this.readOnlyFields[field] = true; } } } } differentFieldList.sort((v1, v2) => { return this.translate(v1, 'fields', this.scope) .localeCompare(this.translate(v2, 'fields', this.scope)); }); differentFieldList = differentFieldList.sort((v1, v2) => { if (!this.readOnlyFields[v1] && this.readOnlyFields[v2]) { return -1; } return 1; }); this.fields = differentFieldList; this.fields.forEach(field => { let type = this.models[0].getFieldParam(field, 'type'); this.models.forEach((model) => { let viewName = model.getFieldParam(field, 'view') || this.getFieldManager().getViewName(type); this.createView(model.id + '-' + field, viewName, { model: model, fullSelector: '.merge [data-id="' + model.id + '"] .field[data-name="' + field + '"]', defs: { name: field, }, mode: 'detail', readOnly: true, }); }); }); this.hasCreatedAt = this.getMetadata().get(['entityDefs', this.scope, 'fields', 'createdAt']); if (this.hasCreatedAt) { this.models.forEach(model => { this.createView(model.id + '-' + 'createdAt', 'views/fields/datetime', { model: model, fullSelector: '.merge [data-id="' + model.id + '"] .field[data-name="createdAt"]', defs: { name: 'createdAt', }, mode: 'detail', readOnly: true, }); }); } } getDataList() { let dataList = []; this.models.forEach(model => { var o = {}; o.id = model.id; o.name = model.get('name'); o.createdAtViewName = model.id + '-' + 'createdAt'; dataList.push(o); }); return dataList; } } export default MergeRecordView;