Skip to content

Commit

Permalink
Merge pull request #349 from RedeMapas/feature/modelo-de-oportunidade
Browse files Browse the repository at this point in the history
Feature/modelo de oportunidade
  • Loading branch information
lpirola authored Aug 2, 2024
2 parents 2b4f727 + 1c922d5 commit 953aa3d
Show file tree
Hide file tree
Showing 9 changed files with 291 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/core/Controllers/Opportunity.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use MapasCulturais\Entities\EvaluationMethodConfiguration;
use MapasCulturais\Entities\Opportunity as EntitiesOpportunity;
use MapasCulturais\Entities\Registration;
use MapasCulturais\Entity;

/**
* Opportunity Controller
Expand All @@ -32,6 +33,7 @@ class Opportunity extends EntityController {
Traits\ControllerArchive,
Traits\ControllerAPI,
Traits\ControllerAPINested,
Traits\EntityOpportunityDuplicator,
Traits\ControllerEntityActions {
Traits\ControllerEntityActions::PATCH_single as _PATCH_single;
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/Entities/Opportunity.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ abstract class Opportunity extends \MapasCulturais\Entity
*/
protected $avaliableEvaluationFields = [];

function getPublishTimestamp(){
return $this->publishTimestamp;
}

abstract function getSpecializedClassName();

public static function getPropertiesMetadata($include_column_name = false){
Expand Down Expand Up @@ -625,6 +629,8 @@ function setPublishTimestamp($date){
}
}



function setOwnerEntity($entity){
if (empty($entity)) {
return;
Expand Down
219 changes: 219 additions & 0 deletions src/core/Traits/EntityOpportunityDuplicator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
<?php
namespace MapasCulturais\Traits;

use MapasCulturais\App;
use MapasCulturais\Entities\ProjectOpportunity;
use MapasCulturais\Entity;

trait EntityOpportunityDuplicator {

private ProjectOpportunity $opportunity;
private ProjectOpportunity $newOpportunity;

function ALL_duplicate(){
$app = App::i();

$this->requireAuthentication();
$this->opportunity = $this->requestedEntity;
$this->newOpportunity = $this->cloneOpportunity();


$this->duplicateEvaluationMethods();
$this->duplicatePhases();
$this->duplicateMetadata();
$this->duplicateRegistrationFieldsAndFiles();
$this->duplicateMetalist();
$this->duplicateFiles();
$this->duplicateAgentRelations();
$this->duplicateSealsRelations();

$this->newOpportunity->save(true);

if($this->isAjax()){
$this->json($this->opportunity);
}else{
$app->redirect($app->request->getReferer());
}
}

private function cloneOpportunity() : ProjectOpportunity
{
$app = App::i();

$this->newOpportunity = clone $this->opportunity;

$dateTime = new \DateTime();
$now = $dateTime->format('d-m-Y H:i:s');
$name = $this->opportunity->name;
$this->newOpportunity->setName("$name - [Cópia][$now]");
$this->newOpportunity->setStatus(Entity::STATUS_DRAFT);
$app->em->persist($this->newOpportunity);
$app->em->flush();

return $this->newOpportunity;
}

private function duplicateEvaluationMethods() : void
{
$app = App::i();

// duplica o método de avaliação para a oportunidade primária
$evaluationMethodConfigurations = $app->repo('EvaluationMethodConfiguration')->findBy([
'opportunity' => $this->opportunity
]);
foreach ($evaluationMethodConfigurations as $evaluationMethodConfiguration) {
$newMethodConfiguration = clone $evaluationMethodConfiguration;
$newMethodConfiguration->setOpportunity($this->newOpportunity);
$newMethodConfiguration->save(true);

// duplica os metadados das configurações do modelo de avaliação
foreach ($evaluationMethodConfiguration->getMetadata() as $metadataKey => $metadataValue) {
$newMethodConfiguration->setMetadata($metadataKey, $metadataValue);
$newMethodConfiguration->save(true);
}

foreach ($evaluationMethodConfiguration->getAgentRelations() as $agentRelation_) {
$agentRelation = clone $agentRelation_;
$agentRelation->owner = $newMethodConfiguration;
$agentRelation->save(true);
}
}
}

private function duplicatePhases() : void
{
$app = App::i();

$phases = $app->repo('Opportunity')->findBy([
'parent' => $this->opportunity
]);
foreach ($phases as $phase) {
if (!$phase->getMetadata('isLastPhase')) {
$newPhase = clone $phase;
$newPhase->setParent($this->newOpportunity);

// duplica os metadados das fases
foreach ($phase->getMetadata() as $metadataKey => $metadataValue) {
if (!is_null($metadataValue) && $metadataValue != '') {
$newPhase->setMetadata($metadataKey, $metadataValue);
$newPhase->save(true);
}
}

$newPhase->save(true);

// duplica os modelos de avaliações das fases
$evaluationMethodConfigurations = $app->repo('EvaluationMethodConfiguration')->findBy([
'opportunity' => $phase
]);

foreach ($evaluationMethodConfigurations as $evaluationMethodConfiguration) {
$newMethodConfiguration = clone $evaluationMethodConfiguration;
$newMethodConfiguration->setOpportunity($newPhase);
$newMethodConfiguration->save(true);

// duplica os metadados das configurações do modelo de avaliação para a fase
foreach ($evaluationMethodConfiguration->getMetadata() as $metadataKey => $metadataValue) {
$newMethodConfiguration->setMetadata($metadataKey, $metadataValue);
$newMethodConfiguration->save(true);
}

foreach ($evaluationMethodConfiguration->getAgentRelations() as $agentRelation_) {
$agentRelation = clone $agentRelation_;
$agentRelation->owner = $newMethodConfiguration;
$agentRelation->save(true);
}
}
}

if ($phase->getMetadata('isLastPhase')) {
$publishDate = $phase->getPublishTimestamp();
}
}

if (isset($publishDate)) {
$phases = $app->repo('Opportunity')->findBy([
'parent' => $this->newOpportunity
]);

foreach ($phases as $phase) {
if ($phase->getMetadata('isLastPhase')) {
$phase->setPublishTimestamp($publishDate);
$phase->save(true);
}
}
}
}

private function duplicateMetadata() : void
{
foreach ($this->opportunity->getMetadata() as $metadataKey => $metadataValue) {
if (!is_null($metadataValue) && $metadataValue != '') {
$this->newOpportunity->setMetadata($metadataKey, $metadataValue);
}
}

$this->newOpportunity->setTerms(['area' => $this->opportunity->terms['area']]);
$this->newOpportunity->setTerms(['tag' => $this->opportunity->terms['tag']]);
$this->newOpportunity->saveTerms();
}

private function duplicateRegistrationFieldsAndFiles() : void
{
foreach ($this->opportunity->getRegistrationFieldConfigurations() as $registrationFieldConfiguration) {
$fieldConfiguration = clone $registrationFieldConfiguration;
$fieldConfiguration->setOwnerId($this->newOpportunity->getId());
$fieldConfiguration->save(true);
}

foreach ($this->opportunity->getRegistrationFileConfigurations() as $registrationFileConfiguration) {
$fileConfiguration = clone $registrationFileConfiguration;
$fileConfiguration->setOwnerId($this->newOpportunity->getId());
$fileConfiguration->save(true);
}

}

private function duplicateMetalist() : void
{
foreach ($this->opportunity->getMetaLists() as $metaList_) {
foreach ($metaList_ as $metaList__) {
$metalist = clone $metaList__;
$metalist->setOwner($this->newOpportunity);

$metalist->save(true);
}
}
}

private function duplicateFiles() : void
{
$app = App::i();

$opportunityFiles = $app->repo('OpportunityFile')->findBy([
'owner' => $this->opportunity
]);

foreach ($opportunityFiles as $opportunityFile) {
$newMethodOpportunityFile = clone $opportunityFile;
$newMethodOpportunityFile->owner = $this->newOpportunity;
$newMethodOpportunityFile->save(true);
}
}

private function duplicateAgentRelations() : void
{
foreach ($this->opportunity->getAgentRelations() as $agentRelation_) {
$agentRelation = clone $agentRelation_;
$agentRelation->owner = $this->newOpportunity;
$agentRelation->save(true);
}
}

private function duplicateSealsRelations() : void
{
foreach ($this->opportunity->getSealRelations() as $sealRelation) {
$this->newOpportunity->createSealRelation($sealRelation->seal, true, true);
}
}
}
22 changes: 22 additions & 0 deletions src/cypress/e2e/opportunity/index.cy.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { clearAllFilters } = require("../../commands/clearAllFilters");
const { checkFilterCountOf } = require("../../commands/checkFilterCountOf");
const { loginWith } = require("../../commands/login");

describe("Opportunity Page", () => {
beforeEach(() => {
Expand Down Expand Up @@ -150,4 +151,25 @@ describe("Opportunity Page", () => {

cy.wait(1000);
});

it("Garante geração de modelo da oportunidade", () => {
cy.visit("/autenticacao/");
loginWith("Admin@local", "mapas123");
cy.get(':nth-child(4) > :nth-child(1) > a').click();
cy.get('.right > .button--primary').click();

cy.wait(1000);

cy.get('.rowBtn > :nth-child(6)').click();

cy.contains("Salvar modelo");
cy.contains("Todas as configurações atuais da oportunidade, incluindo o vínculo com a entidade associada e os campos de formulário criados, serão duplicadas.");

cy.get('.modal__action > .button--primary').click();
cy.wait(3000);

cy.visit("/minhas-oportunidades/#draft");

cy.get('.panel-entity-card__header > .left > .panel-entity-card__header--info > .panel-entity-card__header--info-link > .mc-title').contains("[Cópia]");
});
});
6 changes: 6 additions & 0 deletions src/modules/Components/assets/js/components-base/API.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ class API {
}
}

async duplicateEntity(entity) {
if (entity[this.$PK]) {
return this.POST(entity.getUrl('duplicate'));
}
}

async unpublishEntity(entity) {
if (entity[this.$PK]) {
return this.POST(entity.getUrl('unpublish'));
Expand Down
16 changes: 16 additions & 0 deletions src/modules/Components/assets/js/components-base/Entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,22 @@ class Entity {
}
}

async duplicate(removeFromLists) {
this.__processing = this.text('duplicando');

try {
const res = await this.API.duplicateEntity(this);
return this.doPromise(res, (entity) => {
this.sendMessage(this.text('entidade duplicada'));
this.populate(entity);

window.open('/minhas-oportunidades/#draft', '_blank').focus();
});
} catch (error) {
return this.doCatch(error);
}
}

async archive(removeFromLists) {
this.__processing = this.text('arquivando');

Expand Down
1 change: 1 addition & 0 deletions src/modules/Components/components/mc-entity/texts.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
'criando' => i::__('Criando'),
'salvando' => i::__('Salvando a entidade'),
'publicando' => i::__('Publicando a entidade'),
'duplicando' => i::__('Duplicando a entidade'),
'arquivando' => i::__('Arquivando a entidade'),
'excluindo' => i::__('Excluindo a entidade'),
'excluindo definitivamente' => i::__('Excluindo a entidade definitivamente'),
Expand Down
13 changes: 13 additions & 0 deletions src/modules/Entities/components/entity-actions/template.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@
<?php i::_e('Você está certo que deseja excluir?') ?>
</template>
</mc-confirm-button>
<mc-confirm-button v-if="entity.currentUserPermissions?.modify && entity.status != -2 && entity.__objectType == 'opportunity'" @confirm="entity.duplicate()" no="Cancelar" yes="Continuar">
<template #button="modal">
<button @click="modal.open()" class="button button--icon button--sm">
<?php i::_e("Salvar modelo") ?>
</button>
</template>
<template #message="message">
<h4><b><?php i::_e('Salvar modelo'); ?></b></h4>
<br>
<p><?php i::_e('Todas as configurações atuais da oportunidade, incluindo o vínculo<br> com a entidade associada e os campos de formulário criados, serão<br> duplicadas.') ?></p>
<p><?php i::_e('Deseja continuar?') ?></p>
</template>
</mc-confirm-button>
<?php $this->applyTemplateHook('entity-actions--primary', 'end') ?>
</div>
<?php $this->applyTemplateHook('entity-actions--leftGroupBtn', 'after'); ?>
Expand Down
6 changes: 6 additions & 0 deletions src/modules/Panel/components/panel--entity-actions/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ app.component('panel--entity-actions', {
const promise = entity.archive();
this.$emit('archived', {entity, modal, promise});
},

duplicateEntity(modal) {
const entity = this.entity;
const promise = entity.duplicate();
this.$emit('duplicate', {entity, modal, promise});
},

deleteEntity(modal) {
const entity = this.entity;
Expand Down

0 comments on commit 953aa3d

Please sign in to comment.