Commit 3c5e22872b1a828e22b9fea0aae4b054729004e7

Authored by Eder Soares
Committed by GitHub
2 parents a7df2f5a 832b6d1b
Exists in 2.8 and in 7 other branches 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7

Merge pull request #621 from portabilis/portabilis-patch-2019-07-14

[2.1] Portabilis patch 14/07/2019
Showing 36 changed files with 503 additions and 77 deletions   Show diff stats
app/Http/Middleware/ChangeAppName.php
... ... @@ -21,7 +21,7 @@ class ChangeAppName
21 21 'app.nickname' => url('/'),
22 22 'app.slug' => DB::getDefaultConnection(),
23 23 'app.url' => $request->getBasePath(),
24   - 'honeybadger.environment_name' => $request->getHost(),
  24 + 'honeybadger.environment_name' => config('app.env'),
25 25 ]);
26 26  
27 27 return $next($request);
... ...
app/Models/LegacyEvaluationRuleGradeYear.php 0 → 100644
... ... @@ -0,0 +1,33 @@
  1 +<?php
  2 +
  3 +namespace App\Models;
  4 +
  5 +use Illuminate\Database\Eloquent\Model;
  6 +
  7 +class LegacyEvaluationRuleGradeYear extends Model
  8 +{
  9 + /**
  10 + * @var string
  11 + */
  12 + protected $table = 'modules.regra_avaliacao_serie_ano';
  13 +
  14 + /**
  15 + * @var string
  16 + */
  17 + protected $primaryKey = 'serie_id';
  18 +
  19 + /**
  20 + * @var array
  21 + */
  22 + protected $fillable = [
  23 + 'serie_id',
  24 + 'regra_avaliacao_id',
  25 + 'regra_avaliacao_diferenciada_id',
  26 + 'ano_letivo',
  27 + ];
  28 +
  29 + /**
  30 + * @var bool
  31 + */
  32 + public $timestamps = false;
  33 +}
... ...
app/Models/LegacyOrganization.php 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +<?php
  2 +
  3 +namespace App\Models;
  4 +
  5 +use Illuminate\Database\Eloquent\Model;
  6 +
  7 +class LegacyOrganization extends Model
  8 +{
  9 + /**
  10 + * @var string
  11 + */
  12 + protected $table = 'cadastro.juridica';
  13 +
  14 + /**
  15 + * @var string
  16 + */
  17 + protected $primaryKey = 'idpes';
  18 +
  19 + /**
  20 + * @var array
  21 + */
  22 + protected $fillable = [
  23 + 'idpes',
  24 + 'cnpj',
  25 + 'insc_estadual',
  26 + 'idpes_rev',
  27 + 'data_rev',
  28 + 'origem_gravacao',
  29 + 'idpes_cad',
  30 + 'data_cad',
  31 + 'operacao',
  32 + 'idsis_rev',
  33 + 'idsis_cad',
  34 + 'fantasia',
  35 + 'capital_social',
  36 + ];
  37 +
  38 + /**
  39 + * @var bool
  40 + */
  41 + public $timestamps = false;
  42 +}
... ...
app/Models/LegacySchoolClass.php
... ... @@ -52,6 +52,7 @@ class LegacySchoolClass extends Model
52 52 'ref_ref_cod_escola',
53 53 'ref_ref_cod_serie',
54 54 'ref_cod_curso',
  55 + 'visivel',
55 56 ];
56 57  
57 58 /**
... ...
app/Models/LegacySchoolCourse.php 0 → 100644
... ... @@ -0,0 +1,49 @@
  1 +<?php
  2 +
  3 +namespace App\Models;
  4 +
  5 +use Illuminate\Database\Eloquent\Model;
  6 +
  7 +class LegacySchoolCourse extends Model
  8 +{
  9 + /**
  10 + * @var string
  11 + */
  12 + protected $table = 'pmieducar.escola_curso';
  13 +
  14 + /**
  15 + * @var string
  16 + */
  17 + protected $primaryKey = 'ref_cod_escola';
  18 +
  19 + /**
  20 + * @var array
  21 + */
  22 + protected $fillable = [
  23 + 'ref_cod_escola',
  24 + 'ref_cod_curso',
  25 + 'ref_usuario_exc',
  26 + 'ref_usuario_cad',
  27 + 'data_cadastro',
  28 + 'data_exclusao',
  29 + 'ativo',
  30 + 'autorizacao',
  31 + 'anos_letivos',
  32 + 'updated_at',
  33 + ];
  34 +
  35 + /**
  36 + * @var bool
  37 + */
  38 + public $timestamps = false;
  39 +
  40 + public function school()
  41 + {
  42 + return $this->belongsTo(LegacySchool::class, 'ref_cod_escola');
  43 + }
  44 +
  45 + public function course()
  46 + {
  47 + return $this->belongsTo(LegacyCourse::class, 'ref_cod_curso');
  48 + }
  49 +}
... ...
app/Models/LegacySchoolGrade.php
... ... @@ -25,6 +25,7 @@ class LegacySchoolGrade extends Model
25 25 'ref_cod_serie',
26 26 'ref_usuario_cad',
27 27 'data_cadastro',
  28 + 'anos_letivos',
28 29 ];
29 30  
30 31 /**
... ...
app/Process.php
... ... @@ -14,5 +14,6 @@ class Process
14 14 const MENU_CONFIGURATIONS = 25;
15 15  
16 16 const ENROLLMENT_HISTORY = 1001;
  17 + const ATTENDED_CANDIDATE = 1002;
17 18 const UNDO_STUDENT_UNIFICATION = 2001;
18 19 }
... ...
app/Services/SchoolClassService.php
... ... @@ -2,6 +2,7 @@
2 2  
3 3 namespace App\Services;
4 4  
  5 +use App\Models\LegacyLevel;
5 6 use App\Models\LegacySchoolClass;
6 7  
7 8 class SchoolClassService
... ... @@ -38,4 +39,26 @@ class SchoolClassService
38 39  
39 40 return $isAvailable;
40 41 }
  42 +
  43 + /**
  44 + * Valida se é obrigatório preencher o boletim diferenciado da turma.
  45 + * Caso a série tenha regra de avaliação diferenciada configurada
  46 + *
  47 + * @param integer $levelId
  48 + * @param integer $academicYear
  49 + * @return bool
  50 + */
  51 + public function isRequiredAlternativeReportCard($levelId, $academicYear): bool
  52 + {
  53 + $evaluationRule = LegacyLevel::findOrFail($levelId)->evaluationRules()
  54 + ->wherePivot('ano_letivo', $academicYear)
  55 + ->get()
  56 + ->first();
  57 +
  58 + if (empty($evaluationRule->regra_diferenciada_id)) {
  59 + return false;
  60 + }
  61 +
  62 + return true;
  63 + }
41 64 }
... ...
composer.json
... ... @@ -3,7 +3,7 @@
3 3 "description": "Software livre de gestão escolar",
4 4 "type": "project",
5 5 "license": "GPL-2.0-or-later",
6   - "version": "2.1.18",
  6 + "version": "2.1.19",
7 7 "keywords": [
8 8 "Portabilis",
9 9 "i-Educar"
... ...
composer.lock
... ... @@ -4,20 +4,20 @@
4 4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 5 "This file is @generated automatically"
6 6 ],
7   - "content-hash": "d08a1ef983128315307662a8b4f624e2",
  7 + "content-hash": "88a086a204348825091688b3c294925e",
8 8 "packages": [
9 9 {
10 10 "name": "aws/aws-sdk-php",
11   - "version": "3.104.1",
  11 + "version": "3.107.1",
12 12 "source": {
13 13 "type": "git",
14 14 "url": "https://github.com/aws/aws-sdk-php.git",
15   - "reference": "295706ab2134bf842837fa0b0162ff3aef8b0aa4"
  15 + "reference": "ccd3d13ae49a45bdf6a394d701f207c276dbf05a"
16 16 },
17 17 "dist": {
18 18 "type": "zip",
19   - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/295706ab2134bf842837fa0b0162ff3aef8b0aa4",
20   - "reference": "295706ab2134bf842837fa0b0162ff3aef8b0aa4",
  19 + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/ccd3d13ae49a45bdf6a394d701f207c276dbf05a",
  20 + "reference": "ccd3d13ae49a45bdf6a394d701f207c276dbf05a",
21 21 "shasum": ""
22 22 },
23 23 "require": {
... ... @@ -87,7 +87,7 @@
87 87 "s3",
88 88 "sdk"
89 89 ],
90   - "time": "2019-07-03T18:08:50+00:00"
  90 + "time": "2019-07-12T18:07:41+00:00"
91 91 },
92 92 {
93 93 "name": "cocur/slugify",
... ... @@ -2434,16 +2434,16 @@
2434 2434 },
2435 2435 {
2436 2436 "name": "opis/closure",
2437   - "version": "3.3.0",
  2437 + "version": "3.3.1",
2438 2438 "source": {
2439 2439 "type": "git",
2440 2440 "url": "https://github.com/opis/closure.git",
2441   - "reference": "f846725591203098246276b2e7b9e8b7814c4965"
  2441 + "reference": "92927e26d7fc3f271efe1f55bdbb073fbb2f0722"
2442 2442 },
2443 2443 "dist": {
2444 2444 "type": "zip",
2445   - "url": "https://api.github.com/repos/opis/closure/zipball/f846725591203098246276b2e7b9e8b7814c4965",
2446   - "reference": "f846725591203098246276b2e7b9e8b7814c4965",
  2445 + "url": "https://api.github.com/repos/opis/closure/zipball/92927e26d7fc3f271efe1f55bdbb073fbb2f0722",
  2446 + "reference": "92927e26d7fc3f271efe1f55bdbb073fbb2f0722",
2447 2447 "shasum": ""
2448 2448 },
2449 2449 "require": {
... ... @@ -2491,7 +2491,7 @@
2491 2491 "serialization",
2492 2492 "serialize"
2493 2493 ],
2494   - "time": "2019-05-31T20:04:32+00:00"
  2494 + "time": "2019-07-09T21:58:11+00:00"
2495 2495 },
2496 2496 {
2497 2497 "name": "paragonie/random_compat",
... ... @@ -2706,16 +2706,16 @@
2706 2706 },
2707 2707 {
2708 2708 "name": "phpoffice/phpspreadsheet",
2709   - "version": "1.8.1",
  2709 + "version": "1.8.2",
2710 2710 "source": {
2711 2711 "type": "git",
2712 2712 "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
2713   - "reference": "352c7002fefe4e4037d02654d853a1b09520946f"
  2713 + "reference": "0c1346a1956347590b7db09533966307d20cb7cc"
2714 2714 },
2715 2715 "dist": {
2716 2716 "type": "zip",
2717   - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/352c7002fefe4e4037d02654d853a1b09520946f",
2718   - "reference": "352c7002fefe4e4037d02654d853a1b09520946f",
  2717 + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/0c1346a1956347590b7db09533966307d20cb7cc",
  2718 + "reference": "0c1346a1956347590b7db09533966307d20cb7cc",
2719 2719 "shasum": ""
2720 2720 },
2721 2721 "require": {
... ... @@ -2796,7 +2796,7 @@
2796 2796 "xls",
2797 2797 "xlsx"
2798 2798 ],
2799   - "time": "2019-07-01T20:46:51+00:00"
  2799 + "time": "2019-07-08T21:21:25+00:00"
2800 2800 },
2801 2801 {
2802 2802 "name": "predis/predis",
... ... @@ -4163,7 +4163,7 @@
4163 4163 },
4164 4164 {
4165 4165 "name": "Gert de Pagter",
4166   - "email": "BackEndTea@gmail.com"
  4166 + "email": "backendtea@gmail.com"
4167 4167 }
4168 4168 ],
4169 4169 "description": "Symfony polyfill for ctype functions",
... ... @@ -5012,16 +5012,16 @@
5012 5012 },
5013 5013 {
5014 5014 "name": "zendframework/zend-diactoros",
5015   - "version": "2.1.2",
  5015 + "version": "2.1.3",
5016 5016 "source": {
5017 5017 "type": "git",
5018 5018 "url": "https://github.com/zendframework/zend-diactoros.git",
5019   - "reference": "37bf68b428850ee26ed7c3be6c26236dd95a95f1"
  5019 + "reference": "279723778c40164bcf984a2df12ff2c6ec5e61c1"
5020 5020 },
5021 5021 "dist": {
5022 5022 "type": "zip",
5023   - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/37bf68b428850ee26ed7c3be6c26236dd95a95f1",
5024   - "reference": "37bf68b428850ee26ed7c3be6c26236dd95a95f1",
  5023 + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/279723778c40164bcf984a2df12ff2c6ec5e61c1",
  5024 + "reference": "279723778c40164bcf984a2df12ff2c6ec5e61c1",
5025 5025 "shasum": ""
5026 5026 },
5027 5027 "require": {
... ... @@ -5074,7 +5074,7 @@
5074 5074 "psr",
5075 5075 "psr-7"
5076 5076 ],
5077   - "time": "2019-04-29T21:11:00+00:00"
  5077 + "time": "2019-07-10T16:13:25+00:00"
5078 5078 }
5079 5079 ],
5080 5080 "packages-dev": [
... ... @@ -5684,16 +5684,16 @@
5684 5684 },
5685 5685 {
5686 5686 "name": "laravel/dusk",
5687   - "version": "v5.2.0",
  5687 + "version": "v5.3.0",
5688 5688 "source": {
5689 5689 "type": "git",
5690 5690 "url": "https://github.com/laravel/dusk.git",
5691   - "reference": "4339d153abc18c536616beb8b1c674c67c5720ca"
  5691 + "reference": "17bcb092516805e68d598035f6315bcb9845bbe7"
5692 5692 },
5693 5693 "dist": {
5694 5694 "type": "zip",
5695   - "url": "https://api.github.com/repos/laravel/dusk/zipball/4339d153abc18c536616beb8b1c674c67c5720ca",
5696   - "reference": "4339d153abc18c536616beb8b1c674c67c5720ca",
  5695 + "url": "https://api.github.com/repos/laravel/dusk/zipball/17bcb092516805e68d598035f6315bcb9845bbe7",
  5696 + "reference": "17bcb092516805e68d598035f6315bcb9845bbe7",
5697 5697 "shasum": ""
5698 5698 },
5699 5699 "require": {
... ... @@ -5745,7 +5745,7 @@
5745 5745 "testing",
5746 5746 "webdriver"
5747 5747 ],
5748   - "time": "2019-06-25T15:14:19+00:00"
  5748 + "time": "2019-07-11T21:05:48+00:00"
5749 5749 },
5750 5750 {
5751 5751 "name": "laravel/telescope",
... ...
config/assets.php
... ... @@ -14,7 +14,7 @@ return [
14 14 |
15 15 */
16 16  
17   - 'version' => '0.0.24',
  17 + 'version' => '0.0.26',
18 18  
19 19 /*
20 20 |--------------------------------------------------------------------------
... ...
config/honeybadger.php
... ... @@ -13,7 +13,7 @@ return [
13 13 'version' => env('APP_VERSION'),
14 14 'hostname' => gethostname(),
15 15 'project_root' => base_path(),
16   - 'environment_name' => config('app.nickname'),
  16 + 'environment_name' => config('app.env'),
17 17 'handlers' => [
18 18 'exception' => true,
19 19 'error' => true,
... ...
database/factories/LegacyEvaluationRuleGradeYearFactory.php 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +<?php
  2 +
  3 +use App\Models\LegacyEvaluationRule;
  4 +use App\Models\LegacyLevel;
  5 +use Faker\Generator as Faker;
  6 +
  7 +$factory->define(App\Models\LegacyEvaluationRuleGradeYear::class, function (Faker $faker) {
  8 + return [
  9 + 'serie_id' => factory(LegacyLevel::class)->create(),
  10 + 'regra_avaliacao_id' => factory(LegacyEvaluationRule::class)->create(),
  11 + 'regra_avaliacao_diferenciada_id' => null,
  12 + 'ano_letivo' => '{' . now()->year . '}',
  13 + ];
  14 +});
... ...
database/factories/LegacyOrganizationFactory.php 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +<?php
  2 +
  3 +use App\Models\LegacyOrganization;
  4 +use App\Models\LegacyPerson;
  5 +use App\Models\LegacyUser;
  6 +use Faker\Generator as Faker;
  7 +
  8 +$factory->define(LegacyOrganization::class, function (Faker $faker) {
  9 +
  10 + $person = factory(LegacyPerson::class)->create([
  11 + 'nome' => $faker->company,
  12 + ]);
  13 +
  14 + return [
  15 + 'idpes' => $person,
  16 + 'cnpj' => $faker->numerify('##############'),
  17 + 'insc_estadual' => $faker->numerify('########'),
  18 + 'origem_gravacao' => $faker->randomElement(['M', 'U', 'C', 'O']),
  19 + 'idpes_cad' => factory(LegacyUser::class)->state('unique')->make(),
  20 + 'data_cad' => now(),
  21 + 'operacao' => $faker->randomElement(['I', 'A', 'E']),
  22 + 'idsis_cad' => 1,
  23 + 'fantasia' => $person->name,
  24 + ];
  25 +});
... ...
database/factories/LegacySchoolClassFactory.php
1 1 <?php
2 2  
  3 +use App\Models\LegacyEvaluationRuleGradeYear;
  4 +use App\Models\LegacyInstitution;
3 5 use App\Models\LegacySchoolClass;
4 6 use App\Models\LegacySchoolClassType;
5 7 use App\Models\LegacySchoolGrade;
... ... @@ -9,6 +11,10 @@ use Faker\Generator as Faker;
9 11 $factory->define(LegacySchoolClass::class, function (Faker $faker) {
10 12  
11 13 $schoolGrade = factory(LegacySchoolGrade::class)->create();
  14 + $evaluationRule = factory(LegacyEvaluationRuleGradeYear::class)->create([
  15 + 'serie_id' => $schoolGrade->grade,
  16 + 'ano_letivo' => now()->year,
  17 + ]);
12 18  
13 19 return [
14 20 'ref_usuario_cad' => factory(LegacyUser::class)->state('unique')->make(),
... ... @@ -20,8 +26,10 @@ $factory-&gt;define(LegacySchoolClass::class, function (Faker $faker) {
20 26 'ref_ref_cod_escola' => $schoolGrade->school_id,
21 27 'ref_ref_cod_serie' => $schoolGrade->grade_id,
22 28 'ref_cod_curso' => $schoolGrade->grade->course_id,
  29 + 'ref_cod_instituicao' => factory(LegacyInstitution::class)->state('unique')->make(),
23 30 'dias_semana' => [2, 3, 4, 5, 6],
24   - 'ano' => date('Y'),
  31 + 'ano' => now()->year,
  32 + 'visivel' => true,
25 33 ];
26 34 });
27 35  
... ...
database/factories/LegacySchoolCourseFactory.php 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +<?php
  2 +
  3 +use App\Models\LegacyCourse;
  4 +use App\Models\LegacySchool;
  5 +use App\Models\LegacySchoolCourse;
  6 +use App\Models\LegacyUser;
  7 +use Faker\Generator as Faker;
  8 +
  9 +$factory->define(LegacySchoolCourse::class, function (Faker $faker) {
  10 + return [
  11 + 'ref_cod_escola' => factory(LegacySchool::class)->create(),
  12 + 'ref_cod_curso' => factory(LegacyCourse::class)->create(),
  13 + 'ref_usuario_cad' => factory(LegacyUser::class)->state('unique')->make(),
  14 + 'data_cadastro' => now(),
  15 + 'ativo' => 1,
  16 + 'autorizacao' => $faker->sentence,
  17 + 'anos_letivos' => '{' . now()->format('Y') . '}',
  18 + ];
  19 +});
... ...
database/factories/LegacySchoolFactory.php
... ... @@ -2,6 +2,7 @@
2 2  
3 3 use App\Models\LegacyEducationNetwork;
4 4 use App\Models\LegacyInstitution;
  5 +use App\Models\LegacyOrganization;
5 6 use App\Models\LegacySchool;
6 7 use App\Models\LegacyUser;
7 8 use Faker\Generator as Faker;
... ... @@ -13,5 +14,6 @@ $factory-&gt;define(LegacySchool::class, function (Faker $faker) {
13 14 'ref_cod_escola_rede_ensino' => factory(LegacyEducationNetwork::class)->create(),
14 15 'sigla' => $faker->asciify(),
15 16 'data_cadastro' => now(),
  17 + 'ref_idpes' => factory(LegacyOrganization::class)->create(),
16 18 ];
17 19 });
... ...
database/factories/LegacySchoolGradeFactory.php
... ... @@ -2,15 +2,22 @@
2 2  
3 3 use App\Models\LegacyLevel;
4 4 use App\Models\LegacySchool;
  5 +use App\Models\LegacySchoolCourse;
5 6 use App\Models\LegacySchoolGrade;
6 7 use App\Models\LegacyUser;
7 8 use Faker\Generator as Faker;
8 9  
9 10 $factory->define(LegacySchoolGrade::class, function (Faker $faker) {
  11 +
  12 + $schoolCourse = factory(LegacySchoolCourse::class)->create();
  13 +
10 14 return [
11   - 'ref_cod_escola' => factory(LegacySchool::class)->create(),
12   - 'ref_cod_serie' => factory(LegacyLevel::class)->create(),
  15 + 'ref_cod_escola' => $schoolCourse->school,
  16 + 'ref_cod_serie' => factory(LegacyLevel::class)->create([
  17 + 'ref_cod_curso' => $schoolCourse->course,
  18 + ]),
13 19 'ref_usuario_cad' => factory(LegacyUser::class)->state('unique')->make(),
14 20 'data_cadastro' => now(),
  21 + 'anos_letivos' => $schoolCourse->anos_letivos,
15 22 ];
16 23 });
... ...
database/migrations/2019_07_01_100000_add_column_media_recuperacao_paralela.php 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +<?php
  2 +
  3 +use Illuminate\Support\Facades\Schema;
  4 +use Illuminate\Database\Schema\Blueprint;
  5 +use Illuminate\Database\Migrations\Migration;
  6 +
  7 +class AddColumnMediaRecuperacaoParalela extends Migration
  8 +{
  9 + /**
  10 + * Run the migrations.
  11 + *
  12 + * @return void
  13 + */
  14 + public function up()
  15 + {
  16 + Schema::table('modules.regra_avaliacao', function (Blueprint $table) {
  17 + $table->smallInteger('calcula_media_rec_paralela')->default(0);
  18 + });
  19 + }
  20 +
  21 + /**
  22 + * Reverse the migrations.
  23 + *
  24 + * @return void
  25 + */
  26 + public function down()
  27 + {
  28 + Schema::table('modules.regra_avaliacao', function (Blueprint $table) {
  29 + $table->dropColumn('calcula_media_rec_paralela');
  30 + });
  31 + }
  32 +}
... ...
ieducar/intranet/agenda.php
... ... @@ -41,7 +41,7 @@ class clsIndex extends clsBase
41 41 function Formular()
42 42 {
43 43 $this->SetTitulo( "{$this->_instituicao} Agenda Particular" );
44   - $this->processoAp = "345";
  44 + $this->processoAp = '0';
45 45 $this->addEstilo( "agenda" );
46 46 $this->addScript( "agenda" );
47 47 $this->addEstilo('localizacaoSistema');
... ...
ieducar/intranet/educar_ano_letivo_modulo_cad.php
... ... @@ -540,6 +540,7 @@ class indice extends clsCadastro
540 540 'visivel',
541 541 'turma_turno_id',
542 542 'tipo_boletim',
  543 + 'tipo_boletim_diferenciado',
543 544 'ano',
544 545 'dias_semana',
545 546 'atividades_complementares',
... ... @@ -562,6 +563,7 @@ class indice extends clsCadastro
562 563 $turmaDestino->ano = $anoDestino;
563 564 $turmaDestino->ref_usuario_cad = $this->pessoa_logada;
564 565 $turmaDestino->ref_usuario_exc = $this->pessoa_logada;
  566 + $turmaDestino->visivel = dbBool($turmaOrigem['visivel']);
565 567 $turmaDestinoId = $turmaDestino->cadastra();
566 568  
567 569 $this->copiarComponenteCurricularTurma($turmaOrigem['cod_turma'], $turmaDestinoId);
... ...
ieducar/intranet/educar_escola_lst.php
... ... @@ -140,6 +140,7 @@ class indice extends clsListagem
140 140 } else {
141 141 $obj_escola->setLimite( $this->limite );
142 142 }
  143 + $obj_escola->setOrderby('nome');
143 144 $lista = $obj_escola->lista(
144 145 null,
145 146 null,
... ...
ieducar/intranet/educar_turma_cad.php
... ... @@ -842,6 +842,30 @@ class indice extends clsCadastro
842 842 return $service->isAvailableName($nome, $curso, $serie, $escola, $ano, $id);
843 843 }
844 844  
  845 + /**
  846 + * Valida o campo Boletim Diferenciado
  847 + *
  848 + * @param $levelId
  849 + * @param $academicYear
  850 + * @param $alternativeReportCard
  851 + * @return bool
  852 + */
  853 + public function temBoletimDiferenciado($levelId, $academicYear, $alternativeReportCard)
  854 + {
  855 +
  856 + if ($alternativeReportCard) {
  857 + return true;
  858 + }
  859 +
  860 + $service = new SchoolClassService();
  861 +
  862 + if ($service->isRequiredAlternativeReportCard($levelId, $academicYear)) {
  863 + return false;
  864 + }
  865 +
  866 + return true;
  867 + }
  868 +
845 869 public function Novo()
846 870 {
847 871 if (!$this->canCreateTurma($this->ref_cod_escola, $this->ref_cod_serie, $this->turma_turno_id)) {
... ... @@ -862,6 +886,12 @@ class indice extends clsCadastro
862 886 return false;
863 887 }
864 888  
  889 + if (!$this->temBoletimDiferenciado($this->ref_cod_serie, $this->ano_letivo, $this->tipo_boletim_diferenciado)) {
  890 + $this->mensagem = 'O campo \'<b>Boletim diferenciado</b>\' é obrigatório quando a regra de avaliação da série possui regra diferenciada definida.';
  891 +
  892 + return false;
  893 + }
  894 +
865 895 $this->ref_cod_instituicao_regente = $this->ref_cod_instituicao;
866 896  
867 897 $this->multiseriada = isset($this->multiseriada) ? 1 : 0;
... ... @@ -939,6 +969,12 @@ class indice extends clsCadastro
939 969 return false;
940 970 }
941 971  
  972 + if (!$this->temBoletimDiferenciado($dadosTurma['ref_ref_cod_serie'], $dadosTurma['ano'], $this->tipo_boletim_diferenciado)) {
  973 + $this->mensagem = 'O campo \'<b>Boletim diferenciado</b>\' é obrigatório quando a regra de avaliação da série possui regra diferenciada definida.';
  974 +
  975 + return false;
  976 + }
  977 +
942 978 if (!$this->verificaTurno()) {
943 979 return false;
944 980 }
... ... @@ -1882,6 +1918,7 @@ $pagina-&gt;MakeAll();
1882 1918  
1883 1919 if (document.getElementById('padrao_ano_escolar').value == 0) {
1884 1920 setModuleAndPhasesVisibility(true);
  1921 + buscaEtapasDaEscola();
1885 1922 }
1886 1923 }
1887 1924  
... ...
ieducar/intranet/scripts/etapas.js
... ... @@ -390,7 +390,11 @@ $j(function () {
390 390 $select.focus(function () {
391 391 that.setCurrentModule();
392 392 }).change(function () {
393   - that.setupModule();
  393 + if ($j('#tipoacao').val() === 'Novo') {
  394 + that.initModule();
  395 + } else {
  396 + that.setupModule();
  397 + }
394 398 })
395 399 },
396 400 countRows: function () {
... ...
ieducar/lib/Portabilis/Controller/ReportCoreController.php
... ... @@ -228,7 +228,7 @@ class Portabilis_Controller_ReportCoreController extends Core_Controller_Page_Ed
228 228 public function addValidationError($message)
229 229 {
230 230 $this->validationErrors[] = [
231   - 'message' => utf8_encode($message)
  231 + 'message' => $message
232 232 ];
233 233 }
234 234  
... ...
ieducar/modules/Api/Views/DiarioController.php
... ... @@ -225,18 +225,23 @@ class DiarioController extends ApiCoreController
225 225 continue;
226 226 }
227 227  
  228 + $regra = $serviceBoletim->getRegra();
  229 +
228 230 $valor = $notaTurmaAlunoDisciplina['nota'];
229 231 $notaRecuperacao = $notaTurmaAlunoDisciplina['recuperacao'];
230 232 $nomeCampoRecuperacao = $this->defineCampoTipoRecuperacao($matriculaId);
231 233 $valor = $this->truncate($valor, 4);
232 234  
233 235 $recuperacaoEspecifica = $nomeCampoRecuperacao == 'notaRecuperacaoEspecifica';
  236 + $recuperacaoParalela = $nomeCampoRecuperacao == 'notaRecuperacaoParalela';
234 237  
235   - $notaAposRecuperacao = (($notaRecuperacao > $valor) ? $notaRecuperacao : $valor);
  238 + if (is_numeric($notaRecuperacao) && $recuperacaoParalela && $regra->calculaMediaRecParalela) {
  239 + $valorNota = (floatval($notaRecuperacao) + floatval($valor)) / 2;
  240 + } else {
  241 + $notaAposRecuperacao = $notaRecuperacao > $valor ? $notaRecuperacao : $valor;
236 242  
237   - $valorNota = $recuperacaoEspecifica ? $valor : $notaAposRecuperacao;
238   -
239   - $regra = $serviceBoletim->getRegra();
  243 + $valorNota = $recuperacaoEspecifica ? $valor : $notaAposRecuperacao;
  244 + }
240 245  
241 246 if ($etapa == 'Rc' && $valorNota > $regra->notaMaximaExameFinal) {
242 247 $this->messenger->append("A nota {$valorNota} está acima da configurada para nota máxima para exame que é {$regra->notaMaximaExameFinal}.", 'error');
... ... @@ -272,7 +277,8 @@ class DiarioController extends ApiCoreController
272 277 'componenteCurricular' => $componenteCurricularId,
273 278 'nota' => $valorNota,
274 279 'etapa' => $etapa,
275   - 'notaOriginal' => $valor];
  280 + 'notaOriginal' => $valor
  281 + ];
276 282  
277 283 if (!empty($nomeCampoRecuperacao)) {
278 284 $array_nota[$nomeCampoRecuperacao] = $notaRecuperacao;
... ... @@ -324,18 +330,25 @@ class DiarioController extends ApiCoreController
324 330 }
325 331 }
326 332  
  333 + if (! $serviceBoletim = $this->serviceBoletim($turmaId, $alunoId)) {
  334 + continue;
  335 + }
  336 +
  337 + $regra = $serviceBoletim->getRegra();
  338 +
327 339 $notaRecuperacao = $notaTurmaAlunoDisciplina['recuperacao'];
328 340 $nomeCampoRecuperacao = $this->defineCampoTipoRecuperacao($matriculaId);
329 341  
330 342 $recuperacaoEspecifica = $nomeCampoRecuperacao == 'notaRecuperacaoEspecifica';
331   - $notaAposRecuperacao = (($notaRecuperacao > $notaOriginal) ? $notaRecuperacao : $notaOriginal);
332   - $valorNota = is_null($recuperacaoEspecifica) ? $notaOriginal : $notaAposRecuperacao;
  343 + $recuperacaoParalela = $nomeCampoRecuperacao == 'notaRecuperacaoParalela';
333 344  
334   - if (! $serviceBoletim = $this->serviceBoletim($turmaId, $alunoId)) {
335   - continue;
336   - }
  345 + if (is_numeric($notaRecuperacao) && $recuperacaoParalela && $regra->calculaMediaRecParalela) {
  346 + $valorNota = (floatval($notaRecuperacao) + floatval($notaOriginal)) / 2;
  347 + } else {
  348 + $notaAposRecuperacao = $notaRecuperacao > $notaOriginal ? $notaRecuperacao : $notaOriginal;
337 349  
338   - $regra = $serviceBoletim->getRegra();
  350 + $valorNota = is_null($recuperacaoEspecifica) ? $notaOriginal : $notaAposRecuperacao;
  351 + }
339 352  
340 353 if ($valorNota > $regra->notaMaximaGeral) {
341 354 $this->messenger->append("A nota {$valorNota} está acima da configurada para nota máxima para exame que é {$regra->notaMaximaGeral}.", 'error');
... ... @@ -349,7 +362,8 @@ class DiarioController extends ApiCoreController
349 362 'nota' => $valorNota,
350 363 'etapa' => $etapa,
351 364 'notaOriginal' => $notaOriginal,
352   - $nomeCampoRecuperacao => $notaRecuperacao];
  365 + $nomeCampoRecuperacao => $notaRecuperacao
  366 + ];
353 367  
354 368 $nota = new Avaliacao_Model_NotaComponente($array_nota);
355 369  
... ...
ieducar/modules/Api/Views/EscolaController.php
... ... @@ -185,7 +185,8 @@ class EscolaController extends ApiCoreController
185 185 {
186 186 $sql = 'SELECT sequencial AS etapa,
187 187 data_inicio,
188   - data_fim
  188 + data_fim,
  189 + dias_letivos
189 190 FROM pmieducar.ano_letivo_modulo
190 191 WHERE ref_ano = $1
191 192 AND ref_ref_cod_escola = $2
... ... @@ -193,12 +194,42 @@ class EscolaController extends ApiCoreController
193 194  
194 195 $etapas = [];
195 196 $etapas = $this->fetchPreparedQuery($sql, [$ano, $escola]);
196   - $attrs = ['etapa', 'data_inicio', 'data_fim'];
  197 + $attrs = ['etapa', 'data_inicio', 'data_fim', 'dias_letivos'];
197 198 $etapas = Portabilis_Array_Utils::filterSet($etapas, $attrs);
198 199  
199 200 return ['etapas' => $etapas];
200 201 }
201 202  
  203 + private function getModuloDaEscola($ano, $escola)
  204 + {
  205 + $sql = '
  206 + SELECT max(ref_cod_modulo) as modulo
  207 + FROM pmieducar.ano_letivo_modulo
  208 + WHERE ref_ano = $1
  209 + AND ref_ref_cod_escola = $2
  210 + ';
  211 + $modulo = $this->fetchPreparedQuery($sql, [$ano, $escola], false, 'first-line');
  212 +
  213 + return $modulo['modulo'];
  214 + }
  215 +
  216 + protected function getEtapasDaEscolaPorAno()
  217 + {
  218 + if ($this->canGetEtapasDaEscolaPorAno()) {
  219 + $ano = $this->getRequest()->ano;
  220 + $escolaId = $this->getRequest()->escola_id;
  221 + $dadosDasEtapas = $this->getEtapasAnoEscola($ano, $escolaId);
  222 + $dadosDasEtapas['modulo'] = $this->getModuloDaEscola($ano, $escolaId);
  223 +
  224 + return $dadosDasEtapas;
  225 + }
  226 + }
  227 +
  228 + protected function canGetEtapasDaEscolaPorAno()
  229 + {
  230 + return $this->validatesPresenceOf('ano') && $this->validatesPresenceOf('escola_id');
  231 + }
  232 +
202 233 private function getEtapasTurmasAnoEscola($ano, $escola)
203 234 {
204 235 $sql_turmas = 'SELECT DISTINCT tm.ref_cod_turma as turma_id, m.nm_tipo as descricao
... ... @@ -617,6 +648,8 @@ class EscolaController extends ApiCoreController
617 648 $this->appendResponse($this->getEscolas());
618 649 } elseif ($this->isRequestFor('get', 'etapas-por-escola')) {
619 650 $this->appendResponse($this->getEtapasPorEscola());
  651 + } elseif ($this->isRequestFor('get', 'etapas-da-escola-por-ano')) {
  652 + $this->appendResponse($this->getEtapasDaEscolaPorAno());
620 653 } elseif ($this->isRequestFor('get', 'info-escolas')) {
621 654 $this->appendResponse($this->getInformacaoEscolas());
622 655 } elseif ($this->isRequestFor('get', 'escolas-multiple-search')) {
... ...
ieducar/modules/Avaliacao/Views/DiarioApiController.php
... ... @@ -515,14 +515,21 @@ class DiarioApiController extends ApiCoreController
515 515 $notaOriginal = $this->getNotaOriginal();
516 516 $notaRecuperacaoParalela = urldecode($this->getRequest()->att_value);
517 517  
518   - $notaNova = (($notaRecuperacaoParalela > $notaOriginal) ? $notaRecuperacaoParalela : $notaOriginal);
  518 + $regra = $this->getRegraAvaliacao();
  519 +
  520 + if ($regra['calcula_media_rec_paralela']) {
  521 + $notaNova = (floatval($notaRecuperacaoParalela) + floatval($notaOriginal)) / 2;
  522 + } else {
  523 + $notaNova = $notaRecuperacaoParalela > $notaOriginal ? $notaRecuperacaoParalela : $notaOriginal;
  524 + }
519 525  
520 526 $nota = new Avaliacao_Model_NotaComponente(array(
521 527 'componenteCurricular' => $this->getRequest()->componente_curricular_id,
522 528 'etapa' => $this->getRequest()->etapa,
523 529 'nota' => $notaNova,
524   - 'notaRecuperacaoParalela' => urldecode($this->getRequest()->att_value),
525   - 'notaOriginal' => $notaOriginal));
  530 + 'notaRecuperacaoParalela' => $notaRecuperacaoParalela,
  531 + 'notaOriginal' => $notaOriginal)
  532 + );
526 533  
527 534 $this->serviceBoletim()->addNota($nota);
528 535 $this->trySaveServiceBoletim();
... ... @@ -555,7 +562,7 @@ class DiarioApiController extends ApiCoreController
555 562 'componenteCurricular' => $this->getRequest()->componente_curricular_id,
556 563 'etapa' => $this->getRequest()->etapa,
557 564 'nota' => $notaOriginal,
558   - 'notaRecuperacaoEspecifica' => urldecode($this->getRequest()->att_value),
  565 + 'notaRecuperacaoEspecifica' => $notaRecuperacaoParalela,
559 566 'notaOriginal' => $notaOriginal));
560 567  
561 568 $this->serviceBoletim()->addNota($nota);
... ... @@ -663,7 +670,7 @@ class DiarioApiController extends ApiCoreController
663 670 'componenteCurricular' => $this->getRequest()->componente_curricular_id,
664 671 'etapa' => $this->getRequest()->etapa,
665 672 'nota' => $notaOriginal,
666   - 'notaRecuperacaoEspecifica' => $notaRecuperacaoEspecifica,
  673 + 'notaRecuperacaoEspecifica' => null,
667 674 'notaOriginal' => $notaOriginal));
668 675  
669 676 $this->serviceBoletim()->addNota($nota);
... ... @@ -688,7 +695,7 @@ class DiarioApiController extends ApiCoreController
688 695 'componenteCurricular' => $this->getRequest()->componente_curricular_id,
689 696 'etapa' => $this->getRequest()->etapa,
690 697 'nota' => $notaOriginal,
691   - 'notaRecuperacaoParalela' => $notaRecuperacaoParalela,
  698 + 'notaRecuperacaoParalela' => null,
692 699 'notaOriginal' => $notaOriginal));
693 700  
694 701 $this->serviceBoletim()->addNota($nota);
... ... @@ -1660,6 +1667,7 @@ class DiarioApiController extends ApiCoreController
1660 1667 } elseif ($tipoRecuperacaoParalela == RegraAvaliacao_Model_TipoRecuperacaoParalela::USAR_POR_ETAPA) {
1661 1668 $itensRegra['tipo_recuperacao_paralela'] = 'por_etapa';
1662 1669 $itensRegra['media_recuperacao_paralela'] = $this->serviceBoletim()->getRegra()->get('mediaRecuperacaoParalela');
  1670 + $itensRegra['calcula_media_rec_paralela'] = $this->serviceBoletim()->getRegra()->get('calculaMediaRecParalela');
1663 1671 } elseif ($tipoRecuperacaoParalela == RegraAvaliacao_Model_TipoRecuperacaoParalela::USAR_POR_ETAPAS_ESPECIFICAS) {
1664 1672 $itensRegra['tipo_recuperacao_paralela'] = 'etapas_especificas';
1665 1673  
... ...
ieducar/modules/Cadastro/Assets/Javascripts/Turma.js
... ... @@ -199,6 +199,32 @@ $j(&#39;#tipo_mediacao_didatico_pedagogico&#39;).on(&#39;change&#39;, function(){
199 199 }
200 200 }).trigger('change');
201 201  
  202 +function buscaEtapasDaEscola() {
  203 + var urlApi = getResourceUrlBuilder.buildUrl('/module/Api/Escola', 'etapas-da-escola-por-ano', {
  204 + escola_id : $j('#ref_cod_escola').val(),
  205 + ano : new Date().getFullYear()
  206 + });
  207 +
  208 + var options = {
  209 + url : urlApi,
  210 + dataType : 'json',
  211 + success : function(dataResponse){
  212 + $j('#ref_cod_modulo').val(dataResponse.modulo).trigger('change');
  213 + preencheEtapasNaTurma(dataResponse.etapas);
  214 + }
  215 + };
  216 +
  217 + getResources(options);
  218 +}
  219 +
  220 +function preencheEtapasNaTurma(etapas) {
  221 + $j.each( etapas, function( key, etapa ) {
  222 + $j('input[name^="data_inicio[' + key + '"]').val(formatDate(etapa.data_inicio));
  223 + $j('input[name^="data_fim[' + key + '"]').val(formatDate(etapa.data_fim));
  224 + $j('input[name^="dias_letivos[' + key + '"]').val(etapa.dias_letivos);
  225 + });
  226 +}
  227 +
202 228 $j(document).ready(function() {
203 229  
204 230 // on click das abas
... ...
ieducar/modules/Portabilis/Assets/Javascripts/Frontend/Inputs/MultipleSearch.js
... ... @@ -71,11 +71,27 @@ var multipleSearchHelper = {
71 71 };
72 72  
73 73 var updateChozen = function(input, values){
74   - $j.each(values, function(index, value){
75   - input.append('<option value="' + index + '"> ' + value + '</option>');
  74 + var orderedList = [];
  75 +
  76 + for (let prop in values) {
  77 + orderedList.push({
  78 + label:values[prop],
  79 + value: prop
  80 + });
  81 + }
  82 + orderedList = orderedList.sort(function (a,b) {
  83 + return a.label > b.label ? 1 : -1
76 84 });
  85 +
  86 + for (let option in orderedList) {
  87 + if (orderedList[option ].value !== undefined) {
  88 + input.append('<option value="' + orderedList[option].value + '"> ' + orderedList[option].label + '</option>');
  89 + }
  90 + }
  91 +
77 92 input.trigger("chosen:updated");
78 93 };
  94 +
79 95 var clearValues = function(input){
80 96 input.empty();
81 97 input.trigger("chosen:updated");
... ...
ieducar/modules/Portabilis/Assets/Javascripts/Utils.js
... ... @@ -249,6 +249,15 @@ function safeUtf8Decode(s) {
249 249 return stringUtils.toUtf8(s);
250 250 }
251 251  
  252 +function formatDate(data) {
  253 + data = new Date(data + ' 00:00');
  254 + var dia = data.getDate().toString().padStart(2, "0");
  255 + var mes = (data.getMonth()+1).toString().padStart(2, "0");
  256 + var ano = data.getFullYear();
  257 +
  258 + return dia + '/' + mes + '/' + ano;
  259 +}
  260 +
252 261 // feedback messages
253 262  
254 263 // #TODO migrar todas referencias de "handleMessages([{type*" para "messageUtils.<type>"
... ...
ieducar/modules/RegraAvaliacao/Assets/Javascripts/RegraAvaliacao.js
... ... @@ -38,9 +38,11 @@ $j(function(){
38 38 function tipoRecuperacaoParalelaChange(){
39 39 if($j(this).val() == 1 ) {
40 40 $j('#mediaRecuperacaoParalela').closest('tr').show();
  41 + $j('#calculaMediaRecParalela').closest('tr').show();
41 42 }else{
42 43 $j('#mediaRecuperacaoParalela').val("");
43 44 $j('#mediaRecuperacaoParalela').closest('tr').hide();
  45 + $j('#calculaMediaRecParalela').closest('tr').hide();
44 46 }
45 47  
46 48 if($j(this).val() == 2){
... ... @@ -62,9 +64,9 @@ $j(&#39;[name^=&quot;recuperacao[excluir]&quot;]&#39;).on(&#39;change&#39;, function(){
62 64 $j(this).val('');
63 65 });
64 66  
65   -$j('#notaGeralPorEtapa, #aprovaMediaDisciplina, #reprovacaoAutomatica, #definirComponentePorEtapa').on('change', function(){
  67 +$j('#notaGeralPorEtapa, #aprovaMediaDisciplina, #reprovacaoAutomatica, #definirComponentePorEtapa, #calculaMediaRecParalela').on('change', function(){
66 68 if($j(this).is(':checked'))
67 69 $j(this).val('1');
68 70 else
69 71 $j(this).val('0');
70   -});
71 72 \ No newline at end of file
  73 +});
... ...
ieducar/modules/RegraAvaliacao/Model/Regra.php
... ... @@ -37,6 +37,7 @@ class RegraAvaliacao_Model_Regra extends CoreExt_Entity
37 37 'aprovaMediaDisciplina' => null,
38 38 'reprovacaoAutomatica' => null,
39 39 'regraDiferenciada' => null,
  40 + 'calculaMediaRecParalela' => null,
40 41 ];
41 42  
42 43 protected $_dataTypes = [
... ...
ieducar/modules/RegraAvaliacao/Model/RegraDataMapper.php
... ... @@ -6,9 +6,10 @@ require_once &#39;FormulaMedia/Model/TipoFormula.php&#39;;
6 6  
7 7 class RegraAvaliacao_Model_RegraDataMapper extends CoreExt_DataMapper
8 8 {
9   -
10 9 protected $_entityClass = 'RegraAvaliacao_Model_Regra';
  10 +
11 11 protected $_tableName = 'regra_avaliacao';
  12 +
12 13 protected $_tableSchema = 'modules';
13 14  
14 15 protected $_attributeMap = [
... ... @@ -26,6 +27,7 @@ class RegraAvaliacao_Model_RegraDataMapper extends CoreExt_DataMapper
26 27 'mediaRecuperacao' => 'media_recuperacao',
27 28 'tipoRecuperacaoParalela' => 'tipo_recuperacao_paralela',
28 29 'mediaRecuperacaoParalela' => 'media_recuperacao_paralela',
  30 + 'calculaMediaRecParalela' => 'calcula_media_rec_paralela',
29 31 'notaMaximaGeral' => 'nota_maxima_geral',
30 32 'notaMinimaGeral' => 'nota_minima_geral',
31 33 'notaMaximaExameFinal' => 'nota_maxima_exame_final',
... ...
ieducar/modules/RegraAvaliacao/Views/EditController.php
... ... @@ -56,6 +56,10 @@ class EditController extends Core_Controller_Page_EditController
56 56 do aluno, aceita até 3 casas decimais. Exemplos: 5,00; 6,725, 6.<br >
57 57 Desconsidere esse campo caso selecione o tipo de nota "conceitual"'
58 58 ],
  59 + 'calculaMediaRecParalela' => [
  60 + 'label' => 'Calcular a média',
  61 + 'help' => 'A média da etapa será calculada a partir da soma da nota da etapa mais a nota da recuperação divido por dois.'
  62 + ],
59 63 'formulaMedia' => [
60 64 'label' => 'Fórmula de cálculo da média',
61 65 'help' => '',
... ... @@ -266,20 +270,6 @@ class EditController extends Core_Controller_Page_EditController
266 270 : null;
267 271 }
268 272  
269   - /**
270   - * @see Core_Controller_Page_EditController::_preConstruct()
271   - *
272   - * @todo Interação com a API está errada. Isso já é feito em _initNovo()
273   - * na superclasse. VER.
274   - */
275   - protected function _preConstruct()
276   - {
277   - if (isset($this->getRequest()->id) && 0 < $this->getRequest()->id) {
278   - //$this->setEntity($this->getDataMapper()->find($this->getRequest()->id));
279   - //$this->_setRecuperacoes($this->getDataMapper()->findRegraRecuperacao($this->getEntity()));
280   - }
281   - }
282   -
283 273 protected function _preRender()
284 274 {
285 275 parent::_preRender();
... ... @@ -717,6 +707,17 @@ class EditController extends Core_Controller_Page_EditController
717 707 $this->_getHelp('mediaRecuperacaoParalela')
718 708 );
719 709  
  710 + $this->campoCheck(
  711 + 'calculaMediaRecParalela',
  712 + $this->_getLabel('calculaMediaRecParalela'),
  713 + $this->getEntity()->calculaMediaRecParalela,
  714 + '',
  715 + false,
  716 + false,
  717 + false,
  718 + $this->_getHelp('calculaMediaRecParalela')
  719 + );
  720 +
720 721 // Parte condicional
721 722 if (!$this->getEntity()->isNew()) {
722 723 // Quebra
... ... @@ -887,6 +888,11 @@ class EditController extends Core_Controller_Page_EditController
887 888 $data['aprovaMediaDisciplina'] = '0';
888 889 }
889 890  
  891 + //fixup for checkbox
  892 + if (!isset($data['calculaMediaRecParalela'])) {
  893 + $data['calculaMediaRecParalela'] = '0';
  894 + }
  895 +
890 896 if (isset($entity)) {
891 897 $this->getEntity()->setOptions($data);
892 898 } else {
... ...
src/Modules/Unification/StudentLogUnification.php
... ... @@ -15,7 +15,11 @@ class StudentLogUnification implements LogUnificationTypeInterface
15 15 */
16 16 public function getMainPersonName(LogUnification $logUnification)
17 17 {
18   - return $logUnification->main->individual->real_name;
  18 + if ($logUnification->main) {
  19 + return $logUnification->main->individual->real_name;
  20 + }
  21 +
  22 + return 'Aluno removido pela unificação de pessoas (' . $logUnification->main_id . ')';
19 23 }
20 24  
21 25 /**
... ... @@ -34,6 +38,10 @@ class StudentLogUnification implements LogUnificationTypeInterface
34 38 ->pluck('individual.real_name')
35 39 ->toArray();
36 40  
  41 + if (empty($students)) {
  42 + $students[] = 'Aluno(s) removido(s) pela unificação de pessoas (' . implode(',', $studentIds) . ')';
  43 + }
  44 +
37 45 return $students;
38 46 }
39 47  
... ...