Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
d0738c3
feat: adiciona 23 novos campos de entrega para planejamento e monitor…
vitfera Feb 13, 2026
54ce129
feat: implementa 23 novos campos configuráveis para entregas (planeja…
vitfera Feb 13, 2026
9dc4453
fix: move checkboxes de novos campos para seção correta e adiciona co…
vitfera Feb 13, 2026
d3bbcae
feat: torna segmento artístico-cultural configurável no plano de trab…
vitfera Feb 26, 2026
312f668
feat: option to mark as required or optional
lpirola Feb 26, 2026
ff16287
fix: undefined model in mc-select input
lpirola Feb 26, 2026
ff8071a
feat(workplan): exibe obrigatório* nos campos conforme configuração d…
vitfera Feb 26, 2026
865902e
fix(workplan): usa Array.isArray para inicializar paidStaffByRole cor…
vitfera Feb 26, 2026
4178bce
fix(workplan): reordena campos de entrega conforme ordem do painel de…
vitfera Feb 26, 2026
7e8e6b7
fix(workplan): valida novos campos conforme flags de obrigatoriedade …
vitfera Feb 26, 2026
5ca152d
fix(workplan): aplica decode do retorno da api
lpirola Feb 26, 2026
54d1a7c
fix(workplan): adoção do componente mc-tag-list para melhor visualiza…
lpirola Feb 26, 2026
58088ad
fix(workplan): renomeia styles.css para style.css e ajusta layout inl…
vitfera Feb 26, 2026
973657b
fix(workplan): adota mc-tag-list em mais campos
lpirola Feb 26, 2026
b4f159f
feat(workplan): Refinamento no componente de função remenuderada
lpirola Feb 26, 2026
161a56f
fix(workplan): Add missing style
lpirola Feb 26, 2026
d3cbe43
feat(workplan): Separa em blocos melhor organizados
lpirola Feb 27, 2026
07f98d4
fix(workplan): Revisa campos do workplan
lpirola Feb 27, 2026
4fdfe6c
fix(workplan): aplica field__limits nos inputs numéricos de município…
vitfera Feb 27, 2026
ca7b090
fix(workplan): adiciona Acesso, Internacionalização e Reflexão nas op…
vitfera Feb 27, 2026
b12a3ea
fix(workplan): atualiza campos de composição de equipe por gênero com…
vitfera Feb 27, 2026
f1d87be
fix(workplan): atualiza opções de canais de comunicação conforme list…
vitfera Feb 27, 2026
2374903
feat(workplan): adiciona campos executados de composição de equipe, e…
vitfera Feb 27, 2026
2f3275b
fix(workplan): Remove numero do formulario do proponente
lpirola Feb 27, 2026
dc5b8dc
feat: adiciona em mais lugares o uso dos termos dinamicos do plano de…
lpirola Mar 3, 2026
8bcb279
feat(workplan): revisao dos lugares que devem usar o campo dinamico
lpirola Mar 4, 2026
0dbc09e
fix(workplan): oculta título e descrição da meta quando não configura…
vitfera Mar 4, 2026
79ca26c
feat(workplan): adiciona data inicial e final da atividade
lpirola Mar 4, 2026
23c73cc
fix(workplan): atualiza texto da pergunta de imprensa
lpirola Mar 4, 2026
3f8835b
feat(workplan): adiciona novos campos como periodo de realizacao
lpirola Mar 4, 2026
0cd50b6
fix(workplan): error after add new fields
lpirola Mar 5, 2026
be65dd2
fix(workplan): troca label dinâmico de workplanLabel para delivery …
lpirola Mar 5, 2026
ec2ec39
fix(workplan): corrige validação do form registration
lpirola Mar 5, 2026
25909bf
fix(workplan): remove campos do monitoramento que estavam sendo usado…
lpirola Mar 5, 2026
4c44f45
fix(workplan): remove duplicidade do campo gênero na composição da eq…
lpirola Mar 5, 2026
301f382
fix(workplan): corrige flags de visibilidade dos campos executados no…
lpirola Mar 5, 2026
a288628
fix(workplan): adiciona campo communityCoauthorsDetail no formulário …
lpirola Mar 5, 2026
da4456e
fix(workplan): corrige estrutura do bloco communityCoauthorsDetail no…
lpirola Mar 5, 2026
b964af1
fix(workplan): adiciona campo executedPaidStaffByRole no formulário d…
lpirola Mar 5, 2026
81a4c10
fix(workplan): corrige fonte das opções de paidStaffRoleOptions no mo…
lpirola Mar 5, 2026
452450f
fix(workplan): adiciona validação backend para campos core da entrega…
lpirola Mar 5, 2026
cd5a49f
fix(workplan): desacopla obrigatoriedade de numberOfParticipants da f…
lpirola Mar 5, 2026
e09799a
fix(workplan): corrige typo evidenceFiles/evidenceLinks no template d…
lpirola Mar 5, 2026
7da4c21
fix(workplan): adiciona validação backend de monthInitial/End e cultu…
lpirola Mar 5, 2026
8a0c61d
fix(workplan): corrige pontuação nas mensagens de validação do goal
lpirola Mar 5, 2026
c53ec56
fix(workplan): adiciona validação backend de período e receita na ent…
lpirola Mar 5, 2026
f2387c9
fix(workplan): adiciona nome da entrega nas mensagens de erro dos cam…
lpirola Mar 5, 2026
c55267b
fix(workplan): adiciona input de segmentDelivery e condiciona span de…
lpirola Mar 5, 2026
7e22a25
fix(workplan): adiciona validação JS de culturalArtisticSegment no save
lpirola Mar 5, 2026
e1ce726
fix(workplan): corrige mensagem de campo nome e append de erro de ent…
lpirola Mar 5, 2026
04ebcd2
fix(workplan): campos gate e generaterRevenue deixam de ser obrigatórios
lpirola Mar 5, 2026
e321e76
fix(workplan): remove spans de obrigatório dos campos gate no template
lpirola Mar 5, 2026
d5bf33b
fix(workplan): Configura titulo da seçao como item dinamico
lpirola Mar 6, 2026
66c06f7
feat(workplan): Adiciona botões para ativar o tutorial de cada etapa …
lpirola Mar 6, 2026
9d150ce
feat(workplan): Equipara com campos de inscrição
lpirola Mar 12, 2026
395aed9
Convert opportunity-enable-workplan style.css to style.scss
vitfera Mar 17, 2026
0992de4
Make mc-multiselect model prop required instead of defaulting to empt…
vitfera Mar 17, 2026
99fb182
Move opportunity-enable-workplan styles to BaseV2 theme SCSS componen…
vitfera Mar 17, 2026
0ac3e51
fix: exibe tag obrigatório nos campos pai de comunidades, Trans, aces…
vitfera Mar 18, 2026
0e4b5e5
fix(workplan): corrige entrega sumindo após salvar meta e campos gate…
vitfera Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
307 changes: 296 additions & 11 deletions src/modules/OpportunityWorkplan/Entities/Delivery.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,308 @@ public function jsonSerialize(): array
];
}

/**
* Verifica se um campo de metadata é obrigatório
*
* Lógica:
* 1. Se campo não está habilitado (inform) → não é obrigatório
* 2. Se campo está habilitado mas não tem require → é opcional
* 3. Se campo está habilitado E require = true → é obrigatório
* 4. Se campo já tem valor preenchido → considera satisfeito (retorna true)
*
* @param string $metadata_key Nome do campo de metadata
* @return bool Se o campo é obrigatório
*/
public function isMetadataRequired(string $metadata_key):bool {
// Mapeamento completo: campo → [inform, require]
$metadata_map = [
'accessibilityMeasures' => 'workplan_monitoringInformAccessibilityMeasures',
'executedRevenue' => 'workplan_monitoringReportExecutedRevenue',
'priorityAudience' => 'workplan_monitoringInformThePriorityAudience',
'availabilityType' => 'workplan_monitoringInformTheFormOfAvailability',
'numberOfParticipants' => 'workplan_registrationReportTheNumberOfParticipants',
'participantProfile' => 'workplan_monitoringProvideTheProfileOfParticipants',
// MONITORAMENTO - Campos originais
'accessibilityMeasures' => [
'inform' => 'workplan_monitoringInformAccessibilityMeasures',
'require' => 'workplan_monitoringRequireAccessibilityMeasures'
],
'executedRevenue' => [
'inform' => 'workplan_monitoringReportExecutedRevenue',
'require' => 'workplan_monitoringRequireExecutedRevenue'
],
'priorityAudience' => [
'inform' => 'workplan_monitoringInformThePriorityAudience',
'require' => 'workplan_monitoringRequirePriorityAudience'
],
'availabilityType' => [
'inform' => 'workplan_monitoringInformTheFormOfAvailability',
'require' => 'workplan_monitoringRequireAvailabilityType'
],
'numberOfParticipants' => [
'inform' => 'workplan_monitoringInformNumberOfParticipants',
'require' => 'workplan_monitoringRequireNumberOfParticipants'
],
'participantProfile' => [
'inform' => 'workplan_monitoringProvideTheProfileOfParticipants',
'require' => 'workplan_monitoringRequireParticipantProfile'
],

// PLANEJAMENTO - Campos originais
'segmentDelivery' => [
'inform' => 'workplan_registrationInformCulturalArtisticSegment',
'require' => 'workplan_deliveryRequireSegment'
],
'expectedNumberPeople' => [
'inform' => 'workplan_registrationReportTheNumberOfParticipants',
'require' => 'workplan_deliveryRequireExpectedNumberPeople'
],

// PLANEJAMENTO - Novos campos
'artChainLink' => [
'inform' => 'workplan_deliveryInformArtChainLink',
'require' => 'workplan_deliveryRequireArtChainLink'
],
'totalBudget' => [
'inform' => 'workplan_deliveryInformTotalBudget',
'require' => 'workplan_deliveryRequireTotalBudget'
],
'numberOfCities' => [
'inform' => 'workplan_deliveryInformNumberOfCities',
'require' => 'workplan_deliveryRequireNumberOfCities'
],
'numberOfNeighborhoods' => [
'inform' => 'workplan_deliveryInformNumberOfNeighborhoods',
'require' => 'workplan_deliveryRequireNumberOfNeighborhoods'
],
'mediationActions' => [
'inform' => 'workplan_deliveryInformMediationActions',
'require' => 'workplan_deliveryRequireMediationActions'
],
'paidStaffByRole' => [
'inform' => 'workplan_deliveryInformPaidStaffByRole',
'require' => 'workplan_deliveryRequirePaidStaffByRole'
],
'teamCompositionGender' => [
'inform' => 'workplan_deliveryInformTeamComposition',
'require' => 'workplan_deliveryRequireTeamCompositionGender'
],
'teamCompositionRace' => [
'inform' => 'workplan_deliveryInformTeamComposition',
'require' => 'workplan_deliveryRequireTeamCompositionRace'
],
'revenueType' => [
'inform' => 'workplan_deliveryInformRevenueType',
'require' => 'workplan_deliveryRequireRevenueType'
],
'commercialUnits' => [
'inform' => 'workplan_deliveryInformCommercialUnits',
'require' => 'workplan_deliveryRequireCommercialUnits'
],
'unitPrice' => [
'inform' => 'workplan_deliveryInformCommercialUnits',
'require' => 'workplan_deliveryRequireUnitPrice'
],

// Campos detail (condicionais - só obrigatórios se gate = true)
'communityCoauthorsDetail' => [
'inform' => 'workplan_deliveryInformCommunityCoauthors',
'require' => 'workplan_deliveryRequireCommunityCoauthorsDetail',
'gate' => 'hasCommunityCoauthors'
],
'transInclusionActions' => [
'inform' => 'workplan_deliveryInformTransInclusion',
'require' => 'workplan_deliveryRequireTransInclusionActions',
'gate' => 'hasTransInclusionStrategy'
],
'expectedAccessibilityMeasures' => [
'inform' => 'workplan_deliveryInformAccessibilityPlan',
'require' => 'workplan_deliveryRequireExpectedAccessibilityMeasures',
'gate' => 'hasAccessibilityPlan'
],
'environmentalPracticesDescription' => [
'inform' => 'workplan_deliveryInformEnvironmentalPractices',
'require' => 'workplan_deliveryRequireEnvironmentalPracticesDescription',
'gate' => 'hasEnvironmentalPractices'
],
'innovationTypes' => [
'inform' => 'workplan_deliveryInformInnovation',
'require' => 'workplan_deliveryRequireInnovationTypes',
'gate' => 'hasInnovationAction'
],

// Campos independentes
'communicationChannels' => [
'inform' => 'workplan_deliveryInformCommunicationChannels',
'require' => 'workplan_deliveryRequireCommunicationChannels'
],
'documentationTypes' => [
'inform' => 'workplan_deliveryInformDocumentationTypes',
'require' => 'workplan_deliveryRequireDocumentationTypes'
],

// MONITORAMENTO - Novos campos executados
'executedNumberOfCities' => [
'inform' => 'workplan_monitoringInformNumberOfCities',
'require' => 'workplan_monitoringRequireNumberOfCities'
],
'executedNumberOfNeighborhoods' => [
'inform' => 'workplan_monitoringInformNumberOfNeighborhoods',
'require' => 'workplan_monitoringRequireNumberOfNeighborhoods'
],
'executedMediationActions' => [
'inform' => 'workplan_monitoringInformMediationActions',
'require' => 'workplan_monitoringRequireMediationActions'
],
'executedCommercialUnits' => [
'inform' => 'workplan_monitoringInformCommercialUnits',
'require' => 'workplan_monitoringRequireCommercialUnits'
],
'executedUnitPrice' => [
'inform' => 'workplan_monitoringInformCommercialUnits',
'require' => 'workplan_monitoringRequireUnitPrice'
],
'executedPaidStaffByRole' => [
'inform' => 'workplan_monitoringInformPaidStaffByRole',
'require' => 'workplan_monitoringRequirePaidStaffByRole'
],
'executedTeamCompositionGender' => [
'inform' => 'workplan_monitoringInformTeamComposition',
'require' => 'workplan_monitoringRequireTeamCompositionGender'
],
'executedTeamCompositionRace' => [
'inform' => 'workplan_monitoringInformTeamComposition',
'require' => 'workplan_monitoringRequireTeamCompositionRace'
],
'executedArtChainLink' => [
'inform' => 'workplan_monitoringInformArtChainLink',
'require' => 'workplan_monitoringRequireArtChainLink'
],
'executedCommunicationChannels' => [
'inform' => 'workplan_monitoringInformCommunicationChannels',
'require' => 'workplan_monitoringRequireCommunicationChannels'
],
'executedRevenueType' => [
'inform' => 'workplan_monitoringInformRevenueType',
'require' => 'workplan_monitoringRequireRevenueType'
],
'executedSegmentDelivery' => [
'inform' => 'workplan_monitoringInformSegmentDelivery',
'require' => 'workplan_monitoringRequireSegmentDelivery'
],
'executedCommunityCoauthorsDetail' => [
'inform' => 'workplan_monitoringInformCommunityCoauthors',
'require' => 'workplan_monitoringRequireCommunityCoauthorsDetail',
'gate' => 'executedHasCommunityCoauthors'
],
'executedTransInclusionActions' => [
'inform' => 'workplan_monitoringInformTransInclusion',
'require' => 'workplan_monitoringRequireTransInclusionActions',
'gate' => 'executedHasTransInclusionStrategy'
],
'executedExpectedAccessibilityMeasures' => [
'inform' => 'workplan_monitoringInformAccessibilityPlan',
'require' => 'workplan_monitoringRequireExpectedAccessibilityMeasures',
'gate' => 'executedHasAccessibilityPlan'
],
'executedEnvironmentalPracticesDescription' => [
'inform' => 'workplan_monitoringInformEnvironmentalPractices',
'require' => 'workplan_monitoringRequireEnvironmentalPracticesDescription',
'gate' => 'executedHasEnvironmentalPractices'
],
'executedInnovationTypes' => [
'inform' => 'workplan_monitoringInformInnovation',
'require' => 'workplan_monitoringRequireInnovationTypes',
'gate' => 'executedHasInnovationAction'
],
'executedDocumentationTypes' => [
'inform' => 'workplan_monitoringInformDocumentationTypes',
'require' => 'workplan_monitoringRequireDocumentationTypes'
],
];

// Campo não está no mapa → não é obrigatório
if (!isset($metadata_map[$metadata_key])) {
return false;
}

$config = $metadata_map[$metadata_key];
$opportunity = $this->goal->workplan->registration->opportunity->firstPhase;

// Se campo não está habilitado → não é obrigatório
if (!($opportunity->{$config['inform']} ?? false)) {
return false;
}

// Se campo tem gate, verifica se gate está ativo
if (isset($config['gate'])) {
$gate_value = $this->{$config['gate']} ?? null;
// Se gate não for 'true' (string), o detail não é obrigatório
if ($gate_value !== 'true') {
return false;
}
}

// Se é um campo gate (require = null), sempre é obrigatório quando habilitado
if ($config['require'] === null) {
return true;
}

// Se campo já tem valor preenchido, considera satisfeito
if ($this->$metadata_key) {
return true;
}

$opportunity = $this->goal->workplan->registration->opportunity->firstPhase;
$opportunity_metadata = $metadata_map[$metadata_key];

return $opportunity->$opportunity_metadata ?? false;
// Verifica configuração de obrigatoriedade
return $opportunity->{$config['require']} ?? false;
}

/**
* Valida campo JSON do tipo array de objetos
* Ex: paidStaffByRole = [{role, quantity, totalValue}, ...]
*
* @param string $field Nome do campo
* @return bool Se o campo tem conteúdo válido
*/
protected function validateJsonArrayField(string $field): bool {
$value = $this->$field;
if (!$value) return false;

$decoded = is_string($value) ? json_decode($value, true) : $value;
return is_array($decoded) && count($decoded) > 0;
}

/**
* Valida campo JSON do tipo objeto
* Ex: teamCompositionGender = {cisMale: 5, cisFemale: 8, ...}
*
* @param string $field Nome do campo
* @return bool Se o campo tem conteúdo válido
*/
protected function validateJsonObjectField(string $field): bool {
$value = $this->$field;
if (!$value) return false;

$decoded = is_string($value) ? json_decode($value, true) : $value;
return is_array($decoded) && count($decoded) > 0;
}

/**
* Valida campo multiselect (array)
*
* @param string $field Nome do campo
* @return bool Se o campo tem ao menos uma opção selecionada
*/
protected function validateMultiselectField(string $field): bool {
$value = $this->$field;
if (!$value) return false;

$array = is_string($value) ? json_decode($value, true) : $value;
return is_array($array) && count($array) > 0;
}

/**
* Valida campo select (não pode ser null ou vazio)
*
* @param string $field Nome do campo
* @return bool Se o campo tem valor selecionado
*/
protected function validateSelectField(string $field): bool {
$value = $this->$field;
return !is_null($value) && $value !== '';
}
}
}
Loading
Loading