Skip to content

Commit

Permalink
Feature/modelos (#427)
Browse files Browse the repository at this point in the history
* feat: add action para entidade

* feat: add template do componente modal salvar modelo

* feat: add regra front gerar modelo

* feat: add redme como usar o componente

* feat: aplica regra apenas para entidade oportunidade

* feat: add requisição componente success

* feat: add trait generate model

* feat: add geração de modelo com especificação se é modelo

* feat: define identificação se é modelo e se é oficial

* feat: define padrão é modelo

* feat: adiciona filtro retornar oportunidades diferente de modelos

* feat: aplica regra no componente apenas para entidade oportunidade

* feat: redireciona para meus modelos

* feat: se modelo habilita ação de somente remover

* feat: muda regra status quando modelo e gera fields e files para os forms

* feat: add testes de validação da geração e sucesso do modelo
  • Loading branch information
vicmagpac authored Aug 23, 2024
1 parent 2f29f5f commit 704d7a3
Show file tree
Hide file tree
Showing 12 changed files with 376 additions and 8 deletions.
10 changes: 10 additions & 0 deletions src/conf/opportunity-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,16 @@ function compareNamesOpportunity ($item1, $item2) {
'label' => \MapasCulturais\i::__('Total de vagas'),
// 'description' => \MapasCulturais\i::__("Quantidades de vagas que esse edital irá disponibilizar."),
),
'isModel' => array(
'type' => 'integer',
'label' => \MapasCulturais\i::__('É modelo?'),
'default_value' => 0
),
'isModelOfficial' => array(
'type' => 'integer',
'label' => \MapasCulturais\i::__('É modelo oficial?'),
),

),
'items' => $items,

Expand Down
1 change: 1 addition & 0 deletions src/core/Controllers/Opportunity.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Opportunity extends EntityController {
Traits\ControllerAPI,
Traits\ControllerAPINested,
Traits\EntityOpportunityDuplicator,
Traits\EntityGenerateModel,
Traits\ControllerEntityActions {
Traits\ControllerEntityActions::PATCH_single as _PATCH_single;
}
Expand Down
163 changes: 163 additions & 0 deletions src/core/Traits/EntityGenerateModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php
namespace MapasCulturais\Traits;

use MapasCulturais\App;
use MapasCulturais\Entities\ProjectOpportunity;
use MapasCulturais\Entity;
use MapasCulturais\Definitions\Metadata AS DefinitionMetadata;

trait EntityGenerateModel {

private ProjectOpportunity $opportunity;
private ProjectOpportunity $opportunityModel;

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

$this->requireAuthentication();
$this->opportunity = $this->requestedEntity;
$this->opportunityModel = $this->generateModel();

$this->generateEvaluationMethods();
$this->generatePhases();
$this->generateMetadata();
$this->generateRegistrationFieldsAndFiles();

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

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

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

$postData = $this->postData;

$name = $postData['name'];
$description = $postData['description'];

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

$this->opportunityModel->setName($name);
$this->opportunityModel->setStatus(-1);
$this->opportunityModel->setShortDescription($description);
$app->em->persist($this->opportunityModel);
$app->em->flush();

return $this->opportunityModel;
}

private function generateEvaluationMethods() : 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->opportunityModel);
$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);
}
}
}

private function generatePhases() : 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->opportunityModel);

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

$newPhase->save(true);

$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);
}
}
}

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

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

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


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

$this->opportunityModel->setMetadata('isModel', 1);
$this->opportunityModel->setMetadata('isModelOfficial', 0);

$this->opportunityModel->saveTerms();
}

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

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

}
}
51 changes: 49 additions & 2 deletions src/cypress/e2e/opportunity/index.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,15 @@ describe("Opportunity Page", () => {
cy.wait(1000);
});

it("Garante geração de modelo da oportunidade", () => {
it("Garante duplicação da oportunidade", () => {
cy.visit("/autenticacao/");
loginWith("Admin@local", "mapas123");

cy.wait(1000);

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

cy.contains("Salvar modelo");
cy.contains("Duplicar 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();
Expand All @@ -170,4 +170,51 @@ describe("Opportunity Page", () => {

cy.get('.panel-entity-card__header > .left > .panel-entity-card__header--info > .panel-entity-card__header--info-link > .mc-title').contains("[Cópia]");
});

it("Garante preenchimento obrigatório na geração de modelo baseado em uma 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('.col-12 > .button').click();

cy.get('.modal__content > :nth-child(3) > :nth-child(1) > input').should('be.visible').clear();

cy.get(':nth-child(3) > textarea').should('be.visible').clear();

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

cy.contains('Todos os campos são obrigatorio');
});

it("Garante geração de modelo baseado em uma 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('.col-12 > .button').click();

cy.contains("Salvar modelo");
cy.contains("Para salvar um modelo, preencha os campos abaixo.");
cy.contains("Nome do modelo");
cy.contains("Breve descrição do modelo");
cy.contains("Salvar modelo");

cy.get('.modal__content > :nth-child(3) > :nth-child(1) > input').should('be.visible').clear().type('Nome do modelo');

cy.get(':nth-child(3) > textarea').should('be.visible').type('Descrição do modelo');

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

cy.visit("/minhas-oportunidades/#mymodels");
cy.wait(1000);
cy.contains("Nome do modelo");
});
});
9 changes: 7 additions & 2 deletions src/modules/Entities/components/entity-actions/template.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
$this->import('
mc-confirm-button
mc-loading
opportunity-create-model
');
?>
<div v-if="!empty" class="entity-actions">
Expand Down Expand Up @@ -47,16 +48,20 @@
<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") ?>
<?php i::_e("Duplicar modelo") ?>
</button>
</template>
<template #message="message">
<h4><b><?php i::_e('Salvar modelo'); ?></b></h4>
<h4><b><?php i::_e('Duplicar 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>
<div v-if="entity.currentUserPermissions?.modify && entity.status != -2 && entity.__objectType == 'opportunity'">
<opportunity-create-model :entity="entity" classes="col-12"></opportunity-create-model>
</div>

<?php $this->applyTemplateHook('entity-actions--primary', 'end') ?>
</div>
<?php $this->applyTemplateHook('entity-actions--leftGroupBtn', 'after'); ?>
Expand Down
11 changes: 11 additions & 0 deletions src/modules/Entities/components/opportunity-create-model/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Componente `<opportunity-create-model>`

### Importando componente
```PHP
<?php
$this->import('opportunity-create-model');
?>
```
### Exemplos de uso
```HTML
<opportunity-create-model :entity="entity"></opportunity-create-model>
62 changes: 62 additions & 0 deletions src/modules/Entities/components/opportunity-create-model/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
app.component('opportunity-create-model', {
template: $TEMPLATES['opportunity-create-model'],
setup() {
const messages = useMessages();
const text = Utils.getTexts('opportunity-create-model')
return { text, messages }
},
props: {
entity: {
type: Entity,
required: true,
},
},

data() {
let sendSuccess = false;
let formData = {
name: this.entity.name,
description: '',
}

return { sendSuccess, formData }
},

methods: {
async save() {
this.__processing = this.text('Gerando modelo...');

const api = new API(this.entity.__objectType);

let objt = this.formData;
objt.entityId = this.entity.id;

let error = null;

if (error = this.validade(objt)) {
let mess = "";
mess = this.text('Todos os campos são obrigatorio');
this.messages.error(mess);
return;
}

await api.POST(`/opportunity/generatemodel/${objt.entityId}`, objt).then(res => {
this.messages.success(this.text('Modelo gerado com sucesso'));
this.sendSuccess = true;
window.location.href = '/minhas-oportunidades/#mymodels';
});
},
validade(objt) {
let result = null;
let ignore = [];

Object.keys(objt).forEach(function (item) {
if (!objt[item] && !ignore.includes(item)) {
result = item;
return;
}
});
return result;
},
},
});
Loading

0 comments on commit 704d7a3

Please sign in to comment.