diff --git a/~dev_rating/application/classes/Controller/Api/V0/FinalReport.php b/~dev_rating/application/classes/Controller/Api/V0/FinalReport.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a6626e6f0134a3345708550587976000da3616b
--- /dev/null
+++ b/~dev_rating/application/classes/Controller/Api/V0/FinalReport.php
@@ -0,0 +1,58 @@
+<?php
+
+class Controller_Api_V0_FinalReport extends Controller_Handler_Api {
+    public static function array_group_by($array, $key) {
+        $grouped = [];
+        foreach ($array as $value) {
+            $grouped[$value->{$key}][] = $value;
+        }
+
+        return $grouped;
+    }
+
+    public function action_get_index() {
+        $finalReport = [];
+
+        try {
+            // Получаем год и номер семестра из query запроса
+            $year = $this->request->query('year');
+            $num = $this->request->query('num');
+
+            // Получаем ведомость из БД
+            $finalReport = Model_FinalReport::getBySemesterYearNum($year, $num);
+
+            // Группируем ведомость по планам
+            $finalReport = Controller_Api_V0_FinalReport::array_group_by($finalReport, 'PlanExternalID');
+
+            // Группируем ведомость по предметам
+            foreach ($finalReport as $planExternalID => $row) {
+                $finalReport[$planExternalID] = Controller_Api_V0_FinalReport::array_group_by($row, 'SubjectExternalID');
+            }
+
+            // Группируем ведомость по студентам (у каждого студента одна строчка с оценками, при помощи группировки делаем словарь)
+            foreach ($finalReport as $planExternalID => $disciplines) {
+                foreach ($disciplines as $subjectExternalID => $row) {
+                    $finalReport[$planExternalID][$subjectExternalID] = Controller_Api_V0_FinalReport::array_group_by($row, 'StudentExternalID');
+                }
+            }
+
+            // Перебираем все строки каждого студента и сохраняем результаты в задокументированном формате
+            foreach ($finalReport as $planExternalID => $disciplines) {
+                foreach ($disciplines as $subjectExternalID => $students) {
+                    /** @var Model_FinalReportItem $row */
+                    foreach ($students as $recordBookExternalID => $row) {
+                        $finalReport[$planExternalID][$subjectExternalID][$recordBookExternalID] = [
+                            'semester'  => $row->SemesterRate,
+                            'exam'      => [$row->ExamRate, $row->Exam2Rate, $row->Exam3Rate],
+                            'extra'     => [$row->ExtraRate, $row->Extra2Rate],
+                        ];
+                    }
+                }
+            }
+        } catch (Exception $e) {
+            $this->badRequestError($e->getMessage());
+        }
+
+        return $finalReport;
+    }
+}
diff --git a/~dev_rating/application/classes/Model/FinalReport.php b/~dev_rating/application/classes/Model/FinalReport.php
index b47642ff58c0d879fdef8e39ff27f027d1dd093a..fe1d99ec3a4188adf78c9a9b7bc7e780e5b67e2d 100644
--- a/~dev_rating/application/classes/Model/FinalReport.php
+++ b/~dev_rating/application/classes/Model/FinalReport.php
@@ -1,9 +1,13 @@
 <?php defined('SYSPATH') || die('No direct script access.');
 
-class Model_FinalReport extends Model
+class Model_FinalReport extends Model implements ArrayAccess, Iterator
 {
+    private $position = 0;
+    private $items = [];
+
+
     public function __construct($rows) {
-        return array_map(function ($row) {
+        $this->items = array_map(function ($row) {
             return new Model_FinalReportItem($row);
         }, $rows);
     }
@@ -15,6 +19,48 @@ class Model_FinalReport extends Model
             ->param(':num', $num)
             ->execute();
 
-        return new Model_FinalReport($info);
+        return new Model_FinalReport($info->as_array());
+    }
+
+
+    public function offsetSet($offset, $value) {
+        if (is_null($offset)) {
+            $this->items[] = $value;
+        } else {
+            $this->items[$offset] = $value;
+        }
+    }
+
+    public function offsetExists($offset) {
+        return isset($this->items[$offset]);
+    }
+
+    public function offsetUnset($offset) {
+        unset($this->items[$offset]);
+    }
+
+    public function offsetGet($offset) {
+        return isset($this->items[$offset]) ? $this->items[$offset] : null;
+    }
+
+
+    public function rewind() {
+        $this->position = 0;
+    }
+
+    public function current() {
+        return $this->items[$this->position];
+    }
+
+    public function key() {
+        return $this->position;
+    }
+
+    public function next() {
+        ++$this->position;
+    }
+
+    public function valid() {
+        return isset($this->items[$this->position]);
     }
 }
diff --git a/~dev_rating/application/classes/Model/FinalReportItem.php b/~dev_rating/application/classes/Model/FinalReportItem.php
index 6f2bff54b5006ef408f19235b6444b1401b7feeb..0ec16fc3136f28099f6ba2ad7a866583e8ca67ec 100644
--- a/~dev_rating/application/classes/Model/FinalReportItem.php
+++ b/~dev_rating/application/classes/Model/FinalReportItem.php
@@ -18,7 +18,7 @@ class Model_FinalReportItem extends Model
 {
     public function __construct($row) {
         foreach ($row as $key => $value) {
-            $this[$key] = $value;
+            $this->{$key} = $value;
         }
     }
 }
diff --git a/~dev_rating/application/routes/api/v0.php b/~dev_rating/application/routes/api/v0.php
index 8783cfcfc5eca4b72458a81a0dcdd9c2830e5d82..2ee5f32724433a4d8cfadcc757609aa475b20aa6 100644
--- a/~dev_rating/application/routes/api/v0.php
+++ b/~dev_rating/application/routes/api/v0.php
@@ -1,5 +1,16 @@
 <?php
 
+Route::set('apiv0:final-report', 'api/v0/final-report')
+    ->filter(function($route, $params, $request) {
+        $params['action'] = strtolower($request->method()) . '_' . $params['action'];
+        return $params;
+    })
+    ->defaults([
+        'action'    => 'index',
+        'directory' => 'Api/V0',
+        'controller' => 'FinalReport',
+    ]);
+
 Route::set('apiv0:student', 'api/v0/student')
     ->filter(function($route, $params, $request) {
         $params['action'] = strtolower($request->method()) . '_' . $params['action'];