From 8a7325963be34084f6b0311a8f4faa1f32cf8564 Mon Sep 17 00:00:00 2001 From: yuri Date: Mon, 30 Mar 2015 12:26:41 +0300 Subject: [PATCH] import revert/remove duplicates --- application/Espo/Controllers/Import.php | 13 ++- .../Espo/Resources/i18n/en_US/Global.json | 1 + .../Espo/Resources/i18n/en_US/Import.json | 8 +- .../Resources/metadata/clientDefs/Import.json | 18 ---- .../Resources/metadata/entityDefs/Import.json | 15 ++++ application/Espo/Services/Import.php | 88 ++++++++++++++++--- frontend/client/src/views/import/detail.js | 39 +++++++- 7 files changed, 145 insertions(+), 37 deletions(-) diff --git a/application/Espo/Controllers/Import.php b/application/Espo/Controllers/Import.php index 46f2b3e89c..4f8c7d6f6e 100644 --- a/application/Espo/Controllers/Import.php +++ b/application/Espo/Controllers/Import.php @@ -90,7 +90,18 @@ class Import extends \Espo\Core\Controllers\Record public function actionRevert($params, $data) { - return $this->getService('Import')->revert($data['entityType'], $data['idsToRemove']); + if (empty($data['id'])) { + throw new BadRequest(); + } + return $this->getService('Import')->revert($data['id']); + } + + public function actionRemoveDuplicates($params, $data) + { + if (empty($data['id'])) { + throw new BadRequest(); + } + return $this->getService('Import')->removeDuplicates($data['id']); } public function actionCreate($params, $data) diff --git a/application/Espo/Resources/i18n/en_US/Global.json b/application/Espo/Resources/i18n/en_US/Global.json index e99e39efc4..42e552c308 100644 --- a/application/Espo/Resources/i18n/en_US/Global.json +++ b/application/Espo/Resources/i18n/en_US/Global.json @@ -148,6 +148,7 @@ "Select All Result": "Select All Result" }, "messages": { + "pleaseWait": "Please wait...", "notModified": "You have not modified the record", "duplicate": "The record you are creating seems to be a duplicate", "fieldIsRequired": "{field} is required", diff --git a/application/Espo/Resources/i18n/en_US/Import.json b/application/Espo/Resources/i18n/en_US/Import.json index 75dea20d91..cb18894526 100644 --- a/application/Espo/Resources/i18n/en_US/Import.json +++ b/application/Espo/Resources/i18n/en_US/Import.json @@ -11,10 +11,14 @@ "Updated": "Updated", "Result": "Result", "Show records": "Show records", - "Remove Duplicates": "Remove Duplicates" + "Remove Duplicates": "Remove Duplicates", + "importedCount": "Imported (count)", + "duplicateCount": "Duplicates (count)", + "updatedCount": "Updated (count)" }, "messages": { - "utf8": "Should be UTF-8 encoded" + "utf8": "Should be UTF-8 encoded", + "duplicatesRemoved": "Duplicates removed" }, "fields": { "file": "File", diff --git a/application/Espo/Resources/metadata/clientDefs/Import.json b/application/Espo/Resources/metadata/clientDefs/Import.json index f49a4eac54..67386e0b9c 100644 --- a/application/Espo/Resources/metadata/clientDefs/Import.json +++ b/application/Espo/Resources/metadata/clientDefs/Import.json @@ -8,24 +8,6 @@ "list": "Import.List", "detail": "Import.Detail" }, - "menu": { - "detail": { - "buttons": [ - { - "label": "Revert Import", - "action": "revert", - "style": "danger", - "acl": "edit" - }, - { - "label": "Remove Duplicates", - "action": "removeDuplicates", - "style": "default", - "acl": "edit" - } - ] - } - }, "bottomPanels": { "detail": [ { diff --git a/application/Espo/Resources/metadata/entityDefs/Import.json b/application/Espo/Resources/metadata/entityDefs/Import.json index 12eaebc9e8..97ac14fe52 100644 --- a/application/Espo/Resources/metadata/entityDefs/Import.json +++ b/application/Espo/Resources/metadata/entityDefs/Import.json @@ -9,6 +9,21 @@ "type": "file", "required": true }, + "importedCount": { + "type": "int", + "readOnly": true, + "notStorable": true + }, + "duplicateCount": { + "type": "int", + "readOnly": true, + "notStorable": true + }, + "updatedCount": { + "type": "int", + "readOnly": true, + "notStorable": true + }, "createdAt": { "type": "datetime", "readOnly": true diff --git a/application/Espo/Services/Import.php b/application/Espo/Services/Import.php index 729b7e7585..11577473a9 100644 --- a/application/Espo/Services/Import.php +++ b/application/Espo/Services/Import.php @@ -25,6 +25,7 @@ namespace Espo\Services; use \Espo\Core\Exceptions\Forbidden; use \Espo\Core\Exceptions\NotFound; use \Espo\Core\Exceptions\Error; +use \Espo\Core\Exceptions\BadRequest; use Espo\ORM\Entity; @@ -83,6 +84,20 @@ class Import extends \Espo\Services\Record return $this->injections['serviceFactory']; } + protected function loadAdditionalFields(Entity $entity) + { + parent::loadAdditionalFields($entity); + + $importedCount = $this->getRepository()->countRelated($entity, 'imported'); + $duplicateCount = $this->getRepository()->countRelated($entity, 'duplicates'); + $updatedCount = $this->getRepository()->countRelated($entity, 'updated'); + $entity->set(array( + 'importedCount' => $importedCount, + 'duplicateCount' => $duplicateCount, + 'updatedCount' => $updatedCount, + )); + } + public function findLinkedEntities($id, $link, $params) { $entity = $this->getRepository()->get($id); @@ -178,21 +193,68 @@ class Import extends \Espo\Services\Record return $o; } - public function revert($scope, array $idsToRemove) + public function revert($id) { - $ids = array(); - if (!empty($scope) && !empty($idsToRemove)) { - foreach ($idsToRemove as $id) { - $entity = $this->getEntityManager()->getEntity($scope, $id); - if ($entity) { - if ($this->getEntityManager()->removeEntity($entity)) { - $ids[] = $id; - } - } - $this->getEntityManager()->getRepository($scope)->deleteFromDb($id); - } + $import = $this->getEntityManager()->getEntity('Import', $id); + if (empty($import)) { + throw new NotFound(); } - return $ids; + + $pdo = $this->getEntityManager()->getPDO(); + + + $sql = "SELECT * FROM import_entity WHERE import_id = ".$pdo->quote($import->id) . " AND is_imported = 1"; + + $sth = $pdo->prepare($sql); + $sth->execute(); + while ($row = $sth->fetch(\PDO::FETCH_ASSOC)) { + if (empty($row['entity_type']) || empty($row['entity_id'])) { + continue; + } + $entityType = $row['entity_type']; + $entityId = $row['entity_id']; + + $entity = $this->getEntityManager()->getEntity($entityType, $entityId); + if ($entity) { + $this->getEntityManager()->removeEntity($entity); + } + $this->getEntityManager()->getRepository($scope)->deleteFromDb($entityId); + } + + $this->getEntityManager()->removeEntity($import); + + return true; + } + + public function removeDuplicates($id) + { + $import = $this->getEntityManager()->getEntity('Import', $id); + if (empty($import)) { + throw new NotFound(); + } + + $pdo = $this->getEntityManager()->getPDO(); + + + $sql = "SELECT * FROM import_entity WHERE import_id = ".$pdo->quote($import->id) . " AND is_duplicate = 1"; + + $sth = $pdo->prepare($sql); + $sth->execute(); + while ($row = $sth->fetch(\PDO::FETCH_ASSOC)) { + if (empty($row['entity_type']) || empty($row['entity_id'])) { + continue; + } + $entityType = $row['entity_type']; + $entityId = $row['entity_id']; + + $entity = $this->getEntityManager()->getEntity($entityType, $entityId); + if ($entity) { + $this->getEntityManager()->removeEntity($entity); + } + $this->getEntityManager()->getRepository($scope)->deleteFromDb($entityId); + } + + return true; } public function import($scope, array $fields, $attachmentId, array $params = array()) diff --git a/frontend/client/src/views/import/detail.js b/frontend/client/src/views/import/detail.js index 7d1687ce4e..9a17e18a00 100644 --- a/frontend/client/src/views/import/detail.js +++ b/frontend/client/src/views/import/detail.js @@ -34,8 +34,32 @@ Espo.define('Views.Import.Detail', 'Views.Detail', function (Dep) { ]); }, + setup: function () { + Dep.prototype.setup.call(this); + if (this.model.get('importedCount')) { + this.menu.buttons.unshift({ + "label": "Revert Import", + "action": "revert", + "style": "danger", + "acl": "edit" + }); + } + if (this.model.get('duplicateCount')) { + this.menu.buttons.unshift({ + "label": "Remove Duplicates", + "action": "removeDuplicates", + "style": "default", + "acl": "edit" + }); + } + }, + actionRevert: function () { if (confirm(this.translate('confirmation', 'messages'))) { + $btn = this.$el.find('button[data-action="revert"]'); + $btn.addClass('disabled'); + Espo.Ui.notify(this.translate('pleaseWait', 'messages')); + $.ajax({ type: 'POST', url: 'Import/action/revert', @@ -43,13 +67,20 @@ Espo.define('Views.Import.Detail', 'Views.Detail', function (Dep) { id: this.model.id }) }).done(function () { + Espo.Ui.notify(false); + this.getRouter().navigate('#Import/list', {trigger: true}); - }); + }.bind(this)); } }, actionRemoveDuplicates: function () { + if (confirm(this.translate('confirmation', 'messages'))) { + $btn = this.$el.find('button[data-action="removeDuplicates"]'); + $btn.addClass('disabled'); + Espo.Ui.notify(this.translate('pleaseWait', 'messages')); + $.ajax({ type: 'POST', url: 'Import/action/removeDuplicates', @@ -57,8 +88,10 @@ Espo.define('Views.Import.Detail', 'Views.Detail', function (Dep) { id: this.model.id }) }).done(function () { - this.getRouter().navigate('#Import/list', {trigger: true}); - }); + $btn.remove(); + this.model.fetch(); + Espo.Ui.success(this.translate('duplicatesRemoved', 'messages', 'Import')) + }.bind(this)); } }