Merge branch 'feature/sk-hasil-belajar' into develop

This commit is contained in:
Gregorio Chiko Putra 2019-05-17 12:02:07 +07:00
commit 4c1ad13708
36 changed files with 5048 additions and 367 deletions

View File

@ -10,7 +10,7 @@ class AccessLog extends Model
use SoftDeletes;
protected $fillable = [
'siswa_id',
'siswa_id', 'src',
];
protected $with = [ 'siswa' ];

View File

@ -0,0 +1,48 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Imports\HasilBelajarsImport;
use Maatwebsite\Excel\Facades\Excel;
class ImportExcel extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'ba:import-excel {filename}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Import excel file to table';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
try {
Excel::import(new HasilBelajarsImport, $this->argument('filename'));
} catch (\Exception $e) {
echo $e->getMessage();
}
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Carbon\Carbon;
class PendopoPassword extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'pendopo:password';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Get the current pendopo password.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
echo substr(md5(Carbon::now()->toDateString().'ba'), 0, 6);
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Events;
use App\HasilBelajar;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class HasilBelajarImported
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $hasilBelajar;
/**
* Create a new event instance.
*
* @param App\HasilBelajar $hasilBelajar
* @return void
*/
public function __construct(HasilBelajar $hasilBelajar)
{
$this->hasilBelajar = $hasilBelajar;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}

29
app/HasilBelajar.php Normal file
View File

@ -0,0 +1,29 @@
<?php
namespace App;
use App\Events\HasilBelajarImported;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class HasilBelajar extends Model
{
use SoftDeletes;
protected $fillable = [
'siswa_id', 'meta',
];
protected $casts = [
'meta' => 'array',
];
protected $dispatchesEvents = [
'saved' => HasilBelajarImported::class,
];
public function siswa()
{
return $this->belongsTo('App\Siswa');
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers;
use App\Siswa;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
class AccessLogController extends Controller
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function __invoke(Request $request)
{
/*
* Count unique logs for the given source
*
*/
$logs = DB::table('access_logs')
->select(DB::raw('count(*) as num'))
->where('src', $request->src)
->groupBy('siswa_id')
->get()
->count();
/*
* Count the total number of siswa
*
*/
$resources = Siswa::count();
return response()->json([
'accessed' => $logs,
'total' => $resources,
]);
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace App\Http\Controllers;
use App\HasilBelajar;
use App\Siswa;
use App\AccessLog;
use Illuminate\Support\Facades\Validator;
use Carbon\Carbon;
use Illuminate\Http\Request;
class HasilBelajarController extends Controller
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function __invoke(Request $request)
{
/*
* Validate user inputs
*
*/
Validator::make($request->all(), [
'nisn' => 'required|regex:/^[0-9]+$/',
'tanggalLahir' => 'required|regex:/^[0-9]+$/',
], [
'required' => 'Kolom :attribute harus diisi.',
'regex' => 'Kolom :attribute tidak sesuai.',
])->validate();
/*
* Look for the given inputs in the resource
*
*/
try {
$tanggalLahir = Carbon::parse($request->tanggalLahir)->format('Y-m-d');
} catch(Exception $e) {
return response()->json([
'message' => 'The given data was invalid.',
'errors' => [
'tanggalLahir' => ['Kolom tanggal lahir tidak sesuai.'],
]
], 422);
}
$siswa = Siswa::where('nisn', $request->nisn)
->where('tanggal_lahir', $tanggalLahir)
->with('hasilBelajar')
->first();
/*
* Redirect with error if not found
*
*/
if (!$siswa || $siswa == null) {
return response()->json(['errors' => ['siswa' => ['Siswa tidak ditemukan.']]], 404);
}
return $siswa;
}
}

View File

@ -0,0 +1,72 @@
<?php
namespace App\Http\Controllers;
use App\Siswa;
use App\AccessLog;
use Illuminate\Support\Facades\Validator;
use Carbon\Carbon;
use Illuminate\Http\Request;
class SiswaController extends Controller
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function __invoke(Request $request)
{
/*
* Validate user inputs
*
*/
Validator::make($request->all(), [
'nisn' => 'required|regex:/^[0-9]+$/',
'tanggalLahir' => 'required|regex:/^[0-9]+$/',
], [
'required' => 'Kolom :attribute harus diisi.',
'regex' => 'Kolom :attribute tidak sesuai.',
])->validate();
/*
* Look for the given inputs in the resource
*
*/
try {
$tanggalLahir = Carbon::parse($request->tanggalLahir)->format('Y-m-d');
} catch(Exception $e) {
return response()->json([
'message' => 'The given data was invalid.',
'errors' => [
'tanggalLahir' => ['Kolom tanggal lahir tidak sesuai.'],
]
], 422);
}
$siswa = Siswa::where('nisn', $request->nisn)
->where('tanggal_lahir', $tanggalLahir);
if ($request->with !== null)
$siswa = $siswa->with($request->with);
$siswa = $siswa->first();
/*
* Redirect with error if not found
*
*/
if (!$siswa || $siswa == null) {
return response()->json(['errors' => ['siswa' => ['Siswa tidak ditemukan.']]], 404);
}
/*
* Write a new access log
*
*/
if ($request->src == 'surat-kelulusan')
AccessLog::create(['siswa_id' => $siswa->id, 'src' => $request->src]);
return $siswa;
}
}

View File

@ -60,6 +60,7 @@ class Kernel extends HttpKernel
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'pendopo' => \App\Http\Middleware\IzinMasukPendopo::class,
];
/**

View File

@ -0,0 +1,35 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Carbon\Carbon;
class IzinMasukPendopo
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$AUTH_USER = 'tatausaha';
$AUTH_PASS = substr(md5(Carbon::now()->toDateString().'ba'), 0, 6);
header('Cache-Control: no-cache, must-revalidate, max-age=0');
$has_supplied_credentials = !(empty($_SERVER['PHP_AUTH_USER']) && empty($_SERVER['PHP_AUTH_PW']));
$is_not_authenticated = (
!$has_supplied_credentials ||
$_SERVER['PHP_AUTH_USER'] != $AUTH_USER ||
$_SERVER['PHP_AUTH_PW'] != $AUTH_PASS
);
if ($is_not_authenticated) {
header('HTTP/1.1 401 Authorization Required');
header('WWW-Authenticate: Basic realm="Access denied"');
exit;
}
return $next($request);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace App\Imports;
use App\Siswa;
use App\HasilBelajar;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class HasilBelajarsImport implements ToModel, WithHeadingRow
{
/**
* @param array $row
*
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function model(array $row)
{
$siswa = Siswa::where('nisn', $row['nisn'])
->where('nis', $row['nis'])->first();
if (!$siswa)
return null;
$fieldMeta = [];
foreach ($row as $key => $value) {
if (preg_match("/\_+/", $key)) {
$rowNames = explode('_', $key);
$fieldMeta[$rowNames[0]][$rowNames[1]][$rowNames[2]] = round($value, 2);
}
else {
$fieldMeta[$key] = $value;
}
}
return new HasilBelajar([
'siswa_id' => $siswa->id,
'meta' => $fieldMeta,
]);
}
public function sheets(): array
{
return [
new FirstSheetImport()
];
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Listeners;
use Illuminate\Support\Facades\Log;
use App\Events\HasilBelajarImported;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LogImportedHasilBelajar
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle(HasilBelajarImported $event)
{
Log::channel('single')->debug($event->hasilBelajar);
}
}

View File

@ -2,6 +2,8 @@
namespace App\Providers;
use App\Events\HasilBelajarImported;
use App\Listeners\LogImportedHasilBelajar;
use Illuminate\Support\Facades\Event;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
@ -18,6 +20,9 @@ class EventServiceProvider extends ServiceProvider
Registered::class => [
SendEmailVerificationNotification::class,
],
HasilBelajarImported::class => [
LogImportedHasilBelajar::class,
],
];
/**

View File

@ -21,4 +21,14 @@ class Siswa extends Model
'tanggal_lahir' => 'datetime:Y-m-d',
'lulus' => 'boolean',
];
public function accessLog()
{
return $this->hasMany('App\AccessLog');
}
public function hasilBelajar()
{
return $this->hasOne('App\HasilBelajar');
}
}

View File

@ -11,7 +11,9 @@
"php": "^7.1.3",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.8.*",
"laravel/tinker": "^1.0"
"laravel/tinker": "^1.0",
"maatwebsite/excel": "^3.1",
"phpoffice/phpspreadsheet": "^1.6"
},
"require-dev": {
"beyondcode/laravel-dump-server": "^1.0",

329
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "f5a0a61c9139ecda3fa774f43e4c4d47",
"content-hash": "de40b8ae2535e84b7da46e8c705c73c5",
"packages": [
{
"name": "dnoegel/php-xdg-base-dir",
@ -753,6 +753,239 @@
],
"time": "2019-03-30T13:22:34+00:00"
},
{
"name": "maatwebsite/excel",
"version": "3.1.13",
"source": {
"type": "git",
"url": "https://github.com/Maatwebsite/Laravel-Excel.git",
"reference": "d79ee01175c6a5e93f2a873dcda1b755b7570076"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/d79ee01175c6a5e93f2a873dcda1b755b7570076",
"reference": "d79ee01175c6a5e93f2a873dcda1b755b7570076",
"shasum": ""
},
"require": {
"ext-json": "*",
"illuminate/support": "5.5.*|5.6.*|5.7.*|5.8.*",
"opis/closure": "^3.1",
"php": "^7.0",
"phpoffice/phpspreadsheet": "^1.6"
},
"require-dev": {
"mockery/mockery": "^1.1",
"orchestra/database": "^3.8",
"orchestra/testbench": "^3.8",
"phpunit/phpunit": "^8.0",
"predis/predis": "^1.1"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Maatwebsite\\Excel\\ExcelServiceProvider"
],
"aliases": {
"Excel": "Maatwebsite\\Excel\\Facades\\Excel"
}
}
},
"autoload": {
"psr-4": {
"Maatwebsite\\Excel\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Patrick Brouwers",
"email": "patrick@maatwebsite.nl"
}
],
"description": "Supercharged Excel exports and imports in Laravel",
"keywords": [
"PHPExcel",
"batch",
"csv",
"excel",
"export",
"import",
"laravel",
"php",
"phpspreadsheet"
],
"time": "2019-05-08T12:05:59+00:00"
},
{
"name": "markbaker/complex",
"version": "1.4.7",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPComplex.git",
"reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/1ea674a8308baf547cbcbd30c5fcd6d301b7c000",
"reference": "1ea674a8308baf547cbcbd30c5fcd6d301b7c000",
"shasum": ""
},
"require": {
"php": "^5.6.0|^7.0.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
"phpcompatibility/php-compatibility": "^8.0",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "2.*",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^4.8.35|^5.4.0",
"sebastian/phpcpd": "2.*",
"squizlabs/php_codesniffer": "^3.3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Complex\\": "classes/src/"
},
"files": [
"classes/src/functions/abs.php",
"classes/src/functions/acos.php",
"classes/src/functions/acosh.php",
"classes/src/functions/acot.php",
"classes/src/functions/acoth.php",
"classes/src/functions/acsc.php",
"classes/src/functions/acsch.php",
"classes/src/functions/argument.php",
"classes/src/functions/asec.php",
"classes/src/functions/asech.php",
"classes/src/functions/asin.php",
"classes/src/functions/asinh.php",
"classes/src/functions/atan.php",
"classes/src/functions/atanh.php",
"classes/src/functions/conjugate.php",
"classes/src/functions/cos.php",
"classes/src/functions/cosh.php",
"classes/src/functions/cot.php",
"classes/src/functions/coth.php",
"classes/src/functions/csc.php",
"classes/src/functions/csch.php",
"classes/src/functions/exp.php",
"classes/src/functions/inverse.php",
"classes/src/functions/ln.php",
"classes/src/functions/log2.php",
"classes/src/functions/log10.php",
"classes/src/functions/negative.php",
"classes/src/functions/pow.php",
"classes/src/functions/rho.php",
"classes/src/functions/sec.php",
"classes/src/functions/sech.php",
"classes/src/functions/sin.php",
"classes/src/functions/sinh.php",
"classes/src/functions/sqrt.php",
"classes/src/functions/tan.php",
"classes/src/functions/tanh.php",
"classes/src/functions/theta.php",
"classes/src/operations/add.php",
"classes/src/operations/subtract.php",
"classes/src/operations/multiply.php",
"classes/src/operations/divideby.php",
"classes/src/operations/divideinto.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"description": "PHP Class for working with complex numbers",
"homepage": "https://github.com/MarkBaker/PHPComplex",
"keywords": [
"complex",
"mathematics"
],
"time": "2018-10-13T23:28:42+00:00"
},
{
"name": "markbaker/matrix",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPMatrix.git",
"reference": "6ea97472b5baf12119b4f31f802835b820dd6d64"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/6ea97472b5baf12119b4f31f802835b820dd6d64",
"reference": "6ea97472b5baf12119b4f31f802835b820dd6d64",
"shasum": ""
},
"require": {
"php": "^5.6.0|^7.0.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
"phpcompatibility/php-compatibility": "^8.0",
"phpdocumentor/phpdocumentor": "2.*",
"phploc/phploc": "2.*",
"phpmd/phpmd": "2.*",
"phpunit/phpunit": "^4.8.35|^5.4.0",
"sebastian/phpcpd": "2.*",
"squizlabs/php_codesniffer": "^3.3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Matrix\\": "classes/src/"
},
"files": [
"classes/src/functions/adjoint.php",
"classes/src/functions/antidiagonal.php",
"classes/src/functions/cofactors.php",
"classes/src/functions/determinant.php",
"classes/src/functions/diagonal.php",
"classes/src/functions/identity.php",
"classes/src/functions/inverse.php",
"classes/src/functions/minors.php",
"classes/src/functions/trace.php",
"classes/src/functions/transpose.php",
"classes/src/operations/add.php",
"classes/src/operations/directsum.php",
"classes/src/operations/subtract.php",
"classes/src/operations/multiply.php",
"classes/src/operations/divideby.php",
"classes/src/operations/divideinto.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mark Baker",
"email": "mark@lange.demon.co.uk"
}
],
"description": "PHP Class for working with matrices",
"homepage": "https://github.com/MarkBaker/PHPMatrix",
"keywords": [
"mathematics",
"matrix",
"vector"
],
"time": "2018-11-04T22:12:12+00:00"
},
{
"name": "monolog/monolog",
"version": "1.24.0",
@ -1048,6 +1281,100 @@
],
"time": "2018-07-02T15:55:56+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
"reference": "bf00f0cc5f55c354018f9a9ef15e6e3e1a229051"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/bf00f0cc5f55c354018f9a9ef15e6e3e1a229051",
"reference": "bf00f0cc5f55c354018f9a9ef15e6e3e1a229051",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
"markbaker/complex": "^1.4",
"markbaker/matrix": "^1.1",
"php": "^5.6|^7.0",
"psr/simple-cache": "^1.0"
},
"require-dev": {
"doctrine/instantiator": "^1.0.0",
"dompdf/dompdf": "^0.8.0",
"friendsofphp/php-cs-fixer": "@stable",
"jpgraph/jpgraph": "^4.0",
"mpdf/mpdf": "^7.0.0",
"phpcompatibility/php-compatibility": "^8.0",
"phpunit/phpunit": "^5.7",
"squizlabs/php_codesniffer": "^3.3",
"tecnickcom/tcpdf": "^6.2"
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
"jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1-or-later"
],
"authors": [
{
"name": "Erik Tilt"
},
{
"name": "Adrien Crivelli"
},
{
"name": "Maarten Balliauw",
"homepage": "https://blog.maartenballiauw.be"
},
{
"name": "Mark Baker",
"homepage": "https://markbakeruk.net"
},
{
"name": "Franck Lefevre",
"homepage": "https://rootslabs.net"
}
],
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
"keywords": [
"OpenXML",
"excel",
"gnumeric",
"ods",
"php",
"spreadsheet",
"xls",
"xlsx"
],
"time": "2019-01-02T04:42:54+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.5.0",

View File

@ -165,6 +165,7 @@ return [
/*
* Package Service Providers...
*/
Maatwebsite\Excel\ExcelServiceProvider::class,
/*
* Application Service Providers...
@ -225,6 +226,7 @@ return [
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Excel' => Maatwebsite\Excel\Facades\Excel::class,
],

186
config/excel.php Normal file
View File

@ -0,0 +1,186 @@
<?php
use Maatwebsite\Excel\Excel;
return [
'exports' => [
/*
|--------------------------------------------------------------------------
| Chunk size
|--------------------------------------------------------------------------
|
| When using FromQuery, the query is automatically chunked.
| Here you can specify how big the chunk should be.
|
*/
'chunk_size' => 1000,
/*
|--------------------------------------------------------------------------
| Pre-calculate formulas during export
|--------------------------------------------------------------------------
*/
'pre_calculate_formulas' => false,
/*
|--------------------------------------------------------------------------
| CSV Settings
|--------------------------------------------------------------------------
|
| Configure e.g. delimiter, enclosure and line ending for CSV exports.
|
*/
'csv' => [
'delimiter' => ',',
'enclosure' => '"',
'line_ending' => PHP_EOL,
'use_bom' => false,
'include_separator_line' => false,
'excel_compatibility' => false,
],
],
'imports' => [
'read_only' => true,
'heading_row' => [
/*
|--------------------------------------------------------------------------
| Heading Row Formatter
|--------------------------------------------------------------------------
|
| Configure the heading row formatter.
| Available options: none|slug|custom
|
*/
'formatter' => 'slug',
],
/*
|--------------------------------------------------------------------------
| CSV Settings
|--------------------------------------------------------------------------
|
| Configure e.g. delimiter, enclosure and line ending for CSV imports.
|
*/
'csv' => [
'delimiter' => ',',
'enclosure' => '"',
'line_ending' => PHP_EOL,
'use_bom' => false,
'include_separator_line' => false,
'excel_compatibility' => false,
],
],
/*
|--------------------------------------------------------------------------
| Extension detector
|--------------------------------------------------------------------------
|
| Configure here which writer type should be used when
| the package needs to guess the correct type
| based on the extension alone.
|
*/
'extension_detector' => [
'xlsx' => Excel::XLSX,
'xlsm' => Excel::XLSX,
'xltx' => Excel::XLSX,
'xltm' => Excel::XLSX,
'xls' => Excel::XLS,
'xlt' => Excel::XLS,
'ods' => Excel::ODS,
'ots' => Excel::ODS,
'slk' => Excel::SLK,
'xml' => Excel::XML,
'gnumeric' => Excel::GNUMERIC,
'htm' => Excel::HTML,
'html' => Excel::HTML,
'csv' => Excel::CSV,
'tsv' => Excel::TSV,
/*
|--------------------------------------------------------------------------
| PDF Extension
|--------------------------------------------------------------------------
|
| Configure here which Pdf driver should be used by default.
| Available options: Excel::MPDF | Excel::TCPDF | Excel::DOMPDF
|
*/
'pdf' => Excel::DOMPDF,
],
'value_binder' => [
/*
|--------------------------------------------------------------------------
| Default Value Binder
|--------------------------------------------------------------------------
|
| PhpSpreadsheet offers a way to hook into the process of a value being
| written to a cell. In there some assumptions are made on how the
| value should be formatted. If you want to change those defaults,
| you can implement your own default value binder.
|
*/
'default' => Maatwebsite\Excel\DefaultValueBinder::class,
],
'transactions' => [
/*
|--------------------------------------------------------------------------
| Transaction Handler
|--------------------------------------------------------------------------
|
| By default the import is wrapped in a transaction. This is useful
| for when an import may fail and you want to retry it. With the
| transactions, the previous import gets rolled-back.
|
| You can disable the transaction handler by setting this to null.
| Or you can choose a custom made transaction handler here.
|
| Supported handlers: null|db
|
*/
'handler' => 'db',
],
'temporary_files' => [
/*
|--------------------------------------------------------------------------
| Local Temporary Path
|--------------------------------------------------------------------------
|
| When exporting and importing files, we use a temporary file, before
| storing reading or downloading. Here you can customize that path.
|
*/
'local_path' => sys_get_temp_dir(),
/*
|--------------------------------------------------------------------------
| Remote Temporary Disk
|--------------------------------------------------------------------------
|
| When dealing with a multi server setup with queues in which you
| cannot rely on having a shared local temporary path, you might
| want to store the temporary file on a shared disk. During the
| queue executing, we'll retrieve the temporary file from that
| location instead. When left to null, it will always use
| the local path. This setting only has effect when using
| in conjunction with queued imports and exports.
|
*/
'remote_disk' => null,
],
];

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateHasilBelajarsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('hasil_belajars', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('siswa_id');
$table->longText('meta');
$table->timestamps();
$table->softDeletes();
$table->foreign('siswa_id')
->references('id')
->on('siswas')
->onUpdate('cascade')
->onDelete('restrict');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('hasil_belajars');
}
}

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddSrcFieldToAccessLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('access_logs', function (Blueprint $table) {
$table->string('src');
});
DB::table('access_logs')->update(['src' => 'surat-kelulusan']);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('access_logs', function (Blueprint $table) {
$table->dropColumn('src');
});
}
}

5
package-lock.json generated
View File

@ -5342,6 +5342,11 @@
"resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz",
"integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4="
},
"lodash.map": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
"integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM="
},
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",

View File

@ -7,7 +7,8 @@
"test": "tests"
},
"dependencies": {
"lodash.isempty": "^4.4.0"
"lodash.isempty": "^4.4.0",
"lodash.map": "^4.6.0"
},
"devDependencies": {
"cross-env": "^5.2.0",

40
public/css/main.css vendored
View File

@ -7641,6 +7641,30 @@ span.error {
font-style: italic;
}
.letter table.nilai th, .letter table.nilai td {
border-width: 1px;
border-color: #000;
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.letter table.nilai .long {
display: none;
}
.letter table.nilai .short {
display: table-cell;
}
.letter table.nilai tbody.counter {
counter-reset: nomor;
}
.letter table.nilai tbody.counter td:first-child::before {
counter-increment: nomor;
content: counter(nomor) ".";
}
.letter table.signature {
width: auto;
margin-left: auto;
@ -7752,6 +7776,14 @@ span.error {
.letter .print-button {
display: initial;
}
.letter table.nilai .long {
display: table-cell;
}
.letter table.nilai .short {
display: none;
}
}
@media print {
@ -7782,6 +7814,14 @@ span.error {
.letter .letter__body-header {
font-size: 14px;
}
.letter table.nilai .long {
display: table-cell;
}
.letter table.nilai .short {
display: none;
}
}
@media (min-width: 640px) {

2809
public/js/app.js vendored

File diff suppressed because one or more lines are too long

334
resources/js/app.js vendored
View File

@ -1,274 +1,70 @@
import m from "mithril"
import _isEmpty from "lodash.isempty"
import SuratKelulusan from "./components/SuratKelulusan"
import SKHasilBelajar from "./components/SKHasilBelajar"
import Pendopo from "./components/Pendopo"
import Siswa from "./models/Siswa"
import AccessLog from "./models/AccessLog"
m.mount(document.body.querySelector('.container'), {
oninit: () => {
AccessLog.fetch();
},
view: () => {
return [
m('.header', [
m('span.italic.text-xs', [
'Saat ini sudah ',
m('strong', [
AccessLog.current.accessed,
' / ',
AccessLog.current.total,
]),
' siswa yang telah melihat pengumuman kelulusan.'
]),
m('h1.title', 'Pengumuman Kelulusan SMK Bhakti Anindya'),
m('span', 'Silahkan masukkan Nama Lengkap dan NISN kamu di bawah ini.'),
]),
m('form.form', {
onsubmit: e => {
e.preventDefault();
Siswa.cariData({
nisn: e.target.elements.nisn.value,
tanggalLahir: e.target.elements.tanggalLahir.value,
});
if (document.body.querySelector('.container#pendopo') === null) {
m.route.prefix('#');
m.route(document.body.querySelector('.container'), '/', {
'/': SuratKelulusan,
'/hasil-belajar': SKHasilBelajar,
});
// Below is to handle Ctrl+P or MouseR->Print
window.addEventListener("beforeprint", function () {
if (m.route.get() === '/hasil-belajar') {
// If the print button did not exists, show nothing when printing
if (document.body.querySelector('button.print-button') === null)
document.body.style.display = 'none';
else {
if (!component.confirmPrint) {
alert('Surat Keterangan ini hanya dapat dicetak satu kali. Lanjutkan?');
component.confirmPrint = 1;
AccessLog.create({siswaId: Siswa.current.id, src: 'sk-hasil-belajar'}).then(() => {
AccessLog.fetch('sk-hasil-belajar');
})
.catch(e => {
if (e.code === 0) {
AccessLog.error = {
message: e.message,
errors: {
create: ['Terjadi kesalahan saat menghubungkan ke server.'],
},
};
}
else {
AccessLog.error = JSON.parse(e.message);
}
});
}
},
m('.form-grid', [
m('.form-group', [
m('label.form-label[for=input-nisn]', 'NISN'),
m('input.form-input.input-text#input-nisn[name=nisn][type=text][autocomplete=off][required]'),
m('p.input-helper', [
!_isEmpty(Siswa.error) ?
Siswa.error.errors.siswa != undefined ? m('span.error', Siswa.error.errors.siswa[0] + ' ')
: Siswa.error.errors.nisn != undefined ? m('span.error', Siswa.error.errors.nisn[0] + ' ')
: '' : '',
'Nomor Induk Siswa Nasional.',
]),
]),
m('.form-group', [
m('label.form-label[for=input-tanggalLahir]', 'Tanggal Lahir'),
m('input.form-input.input-text#input-tanggalLahir[name=tanggalLahir][type=text][autocomplete=off][required]'),
m('p.input-helper', [
!_isEmpty(Siswa.error) && Siswa.error.errors.tanggalLahir != undefined ? m('span.error', Siswa.error.errors.tanggalLahir[0] + ' ') : '',
'Tanggal lahir dengan format YYYYMMDD. Contoh: untuk tanggal 29 Mei 2000 ditulis 20000529',
]),
]),
m('button.form-submit#input-submit[type=submit]', 'Lihat'),
])),
m(!_isEmpty(Siswa.current) ? '.letter' : '.letter.hidden', [
m('span.mobile-info', 'Untuk mencetak surat ini, harap gunakan browser di desktop PC.'),
m('button.print-button', {
onclick: () => {
window.print();
}
}, [
m.trust('&#9113;'),
' Print',
]),
m('.letter__header', [
m('img[src=img/letter-head.jpg]'),
]),
m('', {
style: {
height: '1px',
width: '100%',
backgroundColor: '#000',
marginTop: '.5rem',
}}),
m('', {
style: {
height: '3px',
width: '100%',
}}),
m('', {
style: {
height: '3px',
width: '100%',
backgroundColor: '#000',
marginBottom: '1rem',
}}),
m('.letter__body', [
m('strong.letter__body-header', [
m('p', 'KEPUTUSAN'),
m('p', 'KEPALA SEKOLAH MENENGAH KEJURUAN (SMK) BHAKTI ANINDYA'),
m('p', 'Nomor: 076 / SMK - BA / V / 2019'),
m('p', 'TENTANG'),
m('p', 'KELULUSAN PESERTA UJIAN DARI SATUAN PENDIDIKAN'),
m('p', 'TAHUN PELAJARAN 2018 / 2019'),
m('br'),
m('p', 'KEPALA SMK BHAKTI ANINDYA'),
]),
m('br'),
m('table', [
m('tr', [
m('td', 'Menimbang'),
m('td', ':'),
m('td', '1.'),
m('td[colspan=3]', 'Bahwa dalam rangka pengumuman hasil ujian akhir kelas XII Tahun Pelajaran 2018/2019 dipandang perlu untuk menerbitkan surat keputusan tentang kelulusan peserta ujian dari satuan pendidikan SMK Bhakti Anindya.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '2.'),
m('td[colspan=3]', 'Bahwa peserta ujian yang namanya tercantum pada surat keputusan ini dipandang cakap, kompeten, dan layak untuk dinyatakan lulus dari Satuan Pendidikan SMK Bhakti Anindya.'),
]),
m('br'),
m('tr', [
m('td', 'Mengingat'),
m('td', ':'),
m('td', '1.'),
m('td[colspan=3]', 'Undang Undang No. 20 Tahun 2003 tentang Sistem Pendidikan Nasional.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '2.'),
m('td[colspan=3]', 'Permendikbud Nomor 57 Tahun 2015 Tentang Penilaian Hasil Belajar Oleh Pemerintah Melalui Ujian Nasional Dan Penilaian Hasil Belajar Oleh Satuan Pendidikan Melalui Ujian Sekolah/ Madrasah/ Pendidikan Kesetaraan Pada SMP/ MTs/ Yang Sederajat Dan SMA/ MA/ SMK Atau Yang Sederajat.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '3.'),
m('td[colspan=3]', 'Peraturan BSNP NOMOR: 0047/P/BSNP/XI/2018 tentang Prosedur Operasional Standar Penyelenggaraan Ujian Nasional Tahun Pelajaran 2018/2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '4.'),
m('td[colspan=3]', 'Peraturan BSNP NOMOR: 0048/BSNP/XI/2018 tentang Prosedur Operasional Standar Penyelenggaraan Ujian Sekolah Berstandar Nasaional Tahun Pelajaran 2018/2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '5.'),
m('td[colspan=3]', 'Pedoman Penyelenggaraan UKK dan Sertifikasi Siswa SMK pada Ujian Nasional Tahun Pelajaran 2017/2018.'),
]),
m('br'),
m('tr', [
m('td', 'Memperhatikan'),
m('td', ':'),
m('td', '1.'),
m('td[colspan=3]', 'Nilat raport semester 1 6 Tahun Pelajaran 2016/2017 2018/2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '2.'),
m('td[colspan=3]', 'Nilai Hasil Ujian Praktik Kejuruan ( UPK ) yang diselenggarakan tanggal 1 April s.d 3 Mei 2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '3.'),
m('td[colspan=3]', 'Nilai Hasil Ujian Sekolah Berstandar Nasional (USBN) yang diselenggarakan tanggal 05 12 April 2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '4.'),
m('td[colspan=3]', 'Nilai Hasil Ujian Nasional Berbasis Komputer (UNBK) yang diselenggarakan tanggal 25 28 Maret 2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '5.'),
m('td[colspan=3]', 'Hasil pengamatan dan penilaian mengenai sikap, prilaku, dan kepribadian yang bersangkutan selama menjadi siswa SMK Bhakti Anindya.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '6.'),
m('td[colspan=3]', 'Hasil Rapat Pleno Dewan Guru SMK Bhakti Anindya tanggal 10 Mei 2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '7.'),
m('td[colspan=3]', 'Surat Keputusan Tentang Kriteria Kelulusan dari Satuan Pendidikan.'),
]),
m('tr',
m('td.text-center[colspan=6]', 'MEMUTUSKAN :')),
m('tr', [
m('td', 'Menetapkan'),
m('td', ':'),
]),
m('tr', [
m('td', 'Pertama'),
m('td', ':'),
m('td'),
m('td', 'Nama Peserta'),
m('td.strong', ':'),
m('td.strong', Siswa.current.nama),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Tempat & Tanggal Lahir'),
m('td.strong', ':'),
m('td.strong', Siswa.current.tempat_lahir + ' , ' + Siswa.current.tanggal_lahir),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'NIS / NISN'),
m('td.strong', ':'),
m('td.strong', Siswa.current.nis + ' / ' + Siswa.current.nisn),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Nomor Peserta'),
m('td.strong', ':'),
m('td.strong', Siswa.current.nopes),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Bidang Studi Keahlian'),
m('td.strong', ':'),
m('td.strong', Siswa.current.bsk),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Program Studi Keahlian'),
m('td.strong', ':'),
m('td.strong', Siswa.current.psk),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Kompetensi Keahlian'),
m('td.strong', ':'),
m('td.strong', Siswa.current.kk),
]),
m('tr', [
m('td[colspan=3]'),
m('td[colspan=3]', [
'Dinyatakan ',
m('span.special', 'LULUS'),
' dari satuan pendidikan SMK Bhakti Anindya Tahun Pelajaran 2018/2019',
]),
]),
m('br'),
m('tr', [
m('td', 'Kedua'),
m('td', ':'),
m('td[colspan=4]', 'Surat Keputusan ini dikeluarkan sebagai pengganti ijazah yang akan diterbitkan kemudian.'),
]),
m('tr', [
m('td', 'Ketiga'),
m('td', ':'),
m('td[colspan=4]', 'Apabila dalam Surat Keputusan ini terdapat kekeliruan akan dilakukan perbaikan sebagaimana mestinya.'),
]),
m('tr', [
m('td', 'Keempat'),
m('td', ':'),
m('td[colspan=4]', 'Surat Keputusan ini berlaku terhitung mulai tanggal ditetapkan.'),
]),
]),
m('table.signature', [
m('tr', [
m('td', 'Ditetapkan di'),
m('td', ':'),
m('td', 'Tangerang'),
]),
m('tr', [
m('td', 'Pada Tanggal'),
m('td', ':'),
m('td', '13 Mei 2019'),
]),
m('tr',
m('td', 'Kepala Sekolah,')),
m('tr',
m('td[colspan=3]',
m('.letter__sign'))),
m('tr',
m('td[colspan=3]', 'Drs. Engkos Kosasih, M.M.')),
]),
]),
]),
];
},
});
}
}
});
window.addEventListener("afterprint", function () {
if (m.route.get() === '/hasil-belajar') {
// Give back the whole document.body
if (document.body.querySelector('button.print-button') === null)
document.body.style.display = 'block';
// Hide the print button
if (document.body.querySelector('button.print-button') !== null)
document.body.querySelector('button.print-button').style.display = 'none';
// To redraw the content to prevent printing
let nisn = document.body.querySelector('input[name=nisn]').value,
tanggalLahir = document.body.querySelector('input[name=tanggalLahir]').value;
Siswa.cariData({
nisn,
tanggalLahir,
src: 'sk-hasil-belajar',
with: ['hasilBelajar', 'accessLog'],
});
}
});
}
else {
m.mount(document.body.querySelector('.container#pendopo'), Pendopo);
}

View File

@ -1,23 +0,0 @@
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Example Component</div>
<div class="card-body">
I'm an example component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.')
}
}
</script>

318
resources/js/components/Pendopo.js vendored Normal file
View File

@ -0,0 +1,318 @@
import m from "mithril"
import _isEmpty from "lodash.isempty"
import _map from "lodash.map"
import Siswa from "../models/Siswa"
var component = {
oninit: () => {
document.title = 'Surat Keterangan Hasil Belajar Siswa - SMK Bhakti Anindya';
Siswa.current = {};
},
namaMapel: {
'agama': 'Pendidikan Agama',
'pkn': 'Pendidikan Kewarganegaraan',
'indo': 'Bahasa Indonesia',
'penjas': 'Pendidikan Jasmani dan Kesehatan',
'senbud': 'Seni Budaya',
'mtk': 'Matematika',
'inggris': 'Bahasa Inggris',
'ipa': 'Ilmu Pengetahuan Alam',
'ips': 'Ilmu Pengetahuan Sosial',
'fisika': 'Fisika',
'kimia': 'Kimia',
'kwh': 'Kewirausahaan',
'kkpi': 'Keterampilan Komputer dan Pengelolaan Informasi',
'dkk': 'Dasar Kompetensi Keahlian',
'kk': 'Kompetensi Keahlian',
'mandarin': 'Bahasa Mandarin',
'kbi': 'Korespondensi Bahasa Inggris',
'pap': 'Praktek Administrasi Perkantoran',
'myob': 'MYOB',
},
rataRata: {
raport: [],
usbn: [],
unbk: [],
},
view: () => {
component.rataRata = {
raport: [],
usbn: [],
unbk: [],
};
return [
m('.header', [
m('h1.title', 'Surat Keterangan Hasil Belajar Siswa SMK Bhakti Anindya'),
m('span', 'Silahkan masukkan Nama Lengkap dan NISN kamu di bawah ini.'),
]),
m('form.form', {
onsubmit: e => {
e.preventDefault();
Siswa.cariData({
nisn: e.target.elements.nisn.value,
tanggalLahir: e.target.elements.tanggalLahir.value,
src: 'sk-hasil-belajar',
with: 'hasilBelajar',
});
}
},
m('.form-grid', [
m('.form-group', [
m('label.form-label[for=input-nisn]', 'NISN'),
m('input.form-input.input-text#input-nisn[name=nisn][type=text][autocomplete=off][required]'),
m('p.input-helper', [
'Nomor Induk Siswa Nasional. ',
!_isEmpty(Siswa.error) ?
Siswa.error.errors.siswa != undefined ? m('span.error', Siswa.error.errors.siswa[0] + ' ')
: Siswa.error.errors.nisn != undefined ? m('span.error', Siswa.error.errors.nisn[0] + ' ')
: '' : '',
]),
]),
m('.form-group', [
m('label.form-label[for=input-tanggalLahir]', 'Tanggal Lahir'),
m('input.form-input.input-text#input-tanggalLahir[name=tanggalLahir][type=text][autocomplete=off][required]'),
m('p.input-helper', [
'Tanggal lahir dengan format YYYYMMDD. Contoh: untuk tanggal 29 Mei 2000 ditulis 20000529. ',
!_isEmpty(Siswa.error) && Siswa.error.errors.tanggalLahir != undefined ? m('span.error', Siswa.error.errors.tanggalLahir[0] + ' ') : '',
]),
]),
m('button.form-submit#input-submit[type=submit]', 'Lihat'),
])),
_isEmpty(Siswa.current) ? null : m('.letter', [
m('span.mobile-info', 'Untuk mencetak surat ini, harap gunakan browser di desktop PC.'),
!_isEmpty(Siswa.current.access_log) ? null
: m('button.print-button', {
onclick: () => {
window.print();
}
}, [
m.trust('&#9113;'),
' Print',
]),
m('.letter__header', [
m('img[src=img/letter-head.jpg]'),
]),
m('', {
style: {
height: '1px',
width: '100%',
backgroundColor: '#000',
marginTop: '.5rem',
}}),
m('', {
style: {
height: '3px',
width: '100%',
}}),
m('', {
style: {
height: '3px',
width: '100%',
backgroundColor: '#000',
marginBottom: '1rem',
}}),
m('.letter__body', [
m('strong.letter__body-header', [
m('p', m('span.border-b.border-black', 'SURAT KETERANGAN')),
m('p.font-normal.mt-1', 'Nomor: 077/SMK-BA/V/2019'),
]),
m('br'),
m('table', [
m('tr',
m('td[colspan=6]', 'Yang bertanda tangan di bawah ini :')),
m('tr', [
m('td'),
m('td', 'Nama'),
m('td', ':'),
m('td[colspan=3]', 'Drs. Engkos Kosasih, M.M.'),
]),
m('tr', [
m('td'),
m('td', 'Jabatan'),
m('td', ':'),
m('td[colspan=3]', 'Kepala Sekolah'),
]),
m('tr', [
m('td'),
m('td', 'Asal Sekolah'),
m('td', ':'),
m('td[colspan=3]', 'SMK Bhakti Anindya'),
]),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr',
m('td[colspan=6]', 'Menerangkan bahwa')),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr', [
m('td'),
m('td', 'Nama'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.nama),
]),
m('tr', [
m('td'),
m('td', 'Tempat / Tanggal Lahir'),
m('td', ':'),
m('td', Siswa.current.tempat_lahir + ' , ' + Siswa.current.tanggal_lahir),
]),
m('tr', [
m('td'),
m('td', 'NIS / NISN'),
m('td', ':'),
m('td', Siswa.current.nis + ' / ' + Siswa.current.nisn),
]),
m('tr', [
m('td'),
m('td', 'Nomor Peserta'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.nopes),
]),
m('tr', [
m('td'),
m('td', 'Kelas'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.kelas),
]),
m('tr', [
m('td'),
m('td', 'Bidang Studi Keahlian'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.bsk),
]),
m('tr', [
m('td'),
m('td', 'Program Studi Keahlian'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.psk),
]),
m('tr', [
m('td'),
m('td', 'Kompetensi Keahlian'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.kk),
]),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr',
m('td[colspan=6]', 'Adalah benar siswa SMK Bhakti Anindya, Kota Tangerang dan pada tanggal 13 Mei 2019 telah dinyatakan lulus')),
m('tr',
m('td[colspan=6]', 'Berikut hasil belajar siswa tersebut :')),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr',
m('td[colspan=6]',
m('table.nilai', [
m('tr', [
m('th', { style: { width: '5%' } }, 'No.'),
m('th[colspan=2]', 'Mata Pelajaran'),
m('th.long.md:w-1/5', 'Rata-rata Raport Semester 1-6'),
m('th.short.md:w-1/5', 'Raport'),
m('th.long.md:w-1/5', 'Ujian Sekolah Berstandar Nasional'),
m('th.short.md:w-1/5', 'USBN'),
m('th.long.md:w-1/5', 'Ujian Nasional Berbasis Komputer'),
m('th.short.md:w-1/5', 'UNBK'),
]),
m('tr', [
m('th', 'A.'),
m('th[colspan=5].text-left', 'Normatif'),
]),
m('tbody.counter',
_map(Siswa.current.hasil_belajar.meta.normatif, (nilai, mapel) => {
if (nilai.raport != 0) component.rataRata.raport.push(nilai.raport);
if (nilai.usbn != 0) component.rataRata.usbn.push(nilai.usbn);
if (nilai.unbk != 0) component.rataRata.unbk.push(nilai.unbk);
return nilai.raport == 0 && nilai.usbn == 0 && nilai.unbk == 0 ? null : m('tr', [
m('td.text-right'),
m('td[colspan=2]', component.namaMapel[mapel]),
m('td.text-center', nilai.raport !== 0 ? nilai.raport.toFixed(2) : null),
m('td.text-center', nilai.usbn !== 0 ? nilai.usbn.toFixed(2) : null),
m('td.text-center', nilai.unbk !== 0 ? nilai.unbk.toFixed(2) : null),
]);
})),
m('tr', [
m('th', 'B.'),
m('th[colspan=5].text-left', 'Adaptif'),
]),
m('tbody.counter',
_map(Siswa.current.hasil_belajar.meta.adaptif, (nilai, mapel) => {
if (nilai.raport != 0) component.rataRata.raport.push(nilai.raport);
if (nilai.usbn != 0) component.rataRata.usbn.push(nilai.usbn);
if (nilai.unbk != 0) component.rataRata.unbk.push(nilai.unbk);
return nilai.raport == 0 && nilai.usbn == 0 && nilai.unbk == 0 ? null : m('tr', [
m('td.text-right'),
m('td[colspan=2]', component.namaMapel[mapel]),
m('td.text-center', nilai.raport !== 0 ? nilai.raport.toFixed(2) : null),
m('td.text-center', nilai.usbn !== 0 ? nilai.usbn.toFixed(2) : null),
m('td.text-center', nilai.unbk !== 0 ? nilai.unbk.toFixed(2) : null),
]);
}),
m('tr', [
m('th', 'C.'),
m('th[colspan=5].text-left', 'Produktif'),
])),
m('tbody.counter',
_map(Siswa.current.hasil_belajar.meta.produktif, (nilai, mapel) => {
if (nilai.raport != 0) component.rataRata.raport.push(nilai.raport);
if (nilai.usbn != 0) component.rataRata.usbn.push(nilai.usbn);
if (nilai.unbk != 0) component.rataRata.unbk.push(nilai.unbk);
return nilai.raport == 0 && nilai.usbn == 0 && nilai.unbk == 0 ? null : m('tr', [
m('td.text-right'),
m('td[colspan=2]', component.namaMapel[mapel]),
m('td.text-center', nilai.raport !== 0 ? nilai.raport.toFixed(2) : null),
m('td.text-center', nilai.usbn !== 0 ? nilai.usbn.toFixed(2) : null),
m('td.text-center', nilai.unbk !== 0 ? nilai.unbk.toFixed(2) : null),
]);
})),
m('tr', [
m('th', 'D.'),
m('th[colspan=5].text-left', 'Mulok'),
]),
m('tbody.counter',
_map(Siswa.current.hasil_belajar.meta.mulok, (nilai, mapel) => {
if (nilai.raport != 0) component.rataRata.raport.push(nilai.raport);
if (nilai.usbn != 0) component.rataRata.usbn.push(nilai.usbn);
if (nilai.unbk != 0) component.rataRata.unbk.push(nilai.unbk);
return nilai.raport == 0 && nilai.usbn == 0 && nilai.unbk == 0 ? null : m('tr', [
m('td.text-right'),
m('td[colspan=2]', component.namaMapel[mapel]),
m('td.text-center', nilai.raport !== 0 ? nilai.raport.toFixed(2) : null),
m('td.text-center', nilai.usbn !== 0 ? nilai.usbn.toFixed(2) : null),
m('td.text-center', nilai.unbk !== 0 ? nilai.unbk.toFixed(2) : null),
]);
})),
m('tr', [
m('th[colspan=3]', 'Rata-rata'),
m('td.text-center', (component.rataRata.raport.reduce((total, num) => total + num) / component.rataRata.raport.length).toFixed(2)),
m('td.text-center', (component.rataRata.usbn.reduce((total, num) => total + num) / component.rataRata.usbn.length).toFixed(2)),
m('td.text-center', (component.rataRata.unbk.reduce((total, num) => total + num) / component.rataRata.unbk.length).toFixed(2)),
]),
]))),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr',
m('td[colspan=6]', 'Demikian Surat Keterangan ini dibuat untuk siswa yang bersangkutan melanjutkan ke jenjang yang lebih tinggi.')),
]),
m('table.signature', [
m('tr',
m('td', 'Tangerang, 13 Mei 2019')),
m('tr',
m('td', 'Kepala Sekolah,')),
m('tr',
m('td',
m('.letter__sign', { style: { height: '3rem' } }))),
m('tr',
m('td', 'Drs. Engkos Kosasih, M.M.')),
]),
]),
]),
];
},
};
export default component;

View File

@ -0,0 +1,355 @@
import m from "mithril"
import _isEmpty from "lodash.isempty"
import _map from "lodash.map"
import Siswa from "../models/Siswa"
import AccessLog from "../models/AccessLog"
var component = {
oninit: () => {
document.title = 'Surat Keterangan Hasil Belajar Siswa - SMK Bhakti Anindya';
Siswa.current = {};
AccessLog.fetch('sk-hasil-belajar');
},
namaMapel: {
'agama': 'Pendidikan Agama',
'pkn': 'Pendidikan Kewarganegaraan',
'indo': 'Bahasa Indonesia',
'penjas': 'Pendidikan Jasmani dan Kesehatan',
'senbud': 'Seni Budaya',
'mtk': 'Matematika',
'inggris': 'Bahasa Inggris',
'ipa': 'Ilmu Pengetahuan Alam',
'ips': 'Ilmu Pengetahuan Sosial',
'fisika': 'Fisika',
'kimia': 'Kimia',
'kwh': 'Kewirausahaan',
'kkpi': 'Keterampilan Komputer dan Pengelolaan Informasi',
'dkk': 'Dasar Kompetensi Keahlian',
'kk': 'Kompetensi Keahlian',
'mandarin': 'Bahasa Mandarin',
'kbi': 'Korespondensi Bahasa Inggris',
'pap': 'Praktek Administrasi Perkantoran',
'myob': 'MYOB',
},
rataRata: {
raport: [],
usbn: [],
unbk: [],
},
// This prop is to prevent double dialog when printing,
// caused by the print button's confirm()
// and the beforeprint's alert()
confirmPrint: 0,
view: () => {
component.rataRata = {
raport: [],
usbn: [],
unbk: [],
};
return [
m('.header', [
m('span.italic.text-xs', [
'Saat ini sudah ',
m('strong', [
AccessLog.current.accessed,
' / ',
AccessLog.current.total,
]),
' siswa yang telah mencetak surat keterangan hasil belajar.'
]),
m('h1.title', 'Surat Keterangan Hasil Belajar Siswa SMK Bhakti Anindya'),
m('span', 'Silahkan masukkan Nama Lengkap dan NISN kamu di bawah ini.'),
]),
m('form.form', {
onsubmit: e => {
e.preventDefault();
Siswa.cariData({
nisn: e.target.elements.nisn.value,
tanggalLahir: e.target.elements.tanggalLahir.value,
src: 'sk-hasil-belajar',
with: ['hasilBelajar', 'accessLog'],
});
}
},
m('.form-grid', [
m('.form-group', [
m('label.form-label[for=input-nisn]', 'NISN'),
m('input.form-input.input-text#input-nisn[name=nisn][type=text][autocomplete=off][required]'),
m('p.input-helper', [
'Nomor Induk Siswa Nasional. ',
!_isEmpty(Siswa.error) ?
Siswa.error.errors.siswa != undefined ? m('span.error', Siswa.error.errors.siswa[0] + ' ')
: Siswa.error.errors.nisn != undefined ? m('span.error', Siswa.error.errors.nisn[0] + ' ')
: '' : '',
]),
]),
m('.form-group', [
m('label.form-label[for=input-tanggalLahir]', 'Tanggal Lahir'),
m('input.form-input.input-text#input-tanggalLahir[name=tanggalLahir][type=text][autocomplete=off][required]'),
m('p.input-helper', [
'Tanggal lahir dengan format YYYYMMDD. Contoh: untuk tanggal 29 Mei 2000 ditulis 20000529. ',
!_isEmpty(Siswa.error) && Siswa.error.errors.tanggalLahir != undefined ? m('span.error', Siswa.error.errors.tanggalLahir[0] + ' ') : '',
]),
]),
m('button.form-submit#input-submit[type=submit]', 'Lihat'),
])),
_isEmpty(Siswa.current) ? null : m('.letter', [
m('span.mobile-info', 'Untuk mencetak surat ini, harap gunakan browser di desktop PC.'),
!_isEmpty(Siswa.current.access_log) ? null
: m('button.print-button', {
onclick: () => {
if (confirm('Surat Keterangan ini hanya dapat dicetak satu kali. Lanjutkan?')) {
component.confirmPrint = 1;
AccessLog.create({siswaId: Siswa.current.id, src: 'sk-hasil-belajar'}).then(() => {
AccessLog.fetch('sk-hasil-belajar');
window.print();
})
.catch(e => {
if (e.code === 0) {
AccessLog.error = {
message: e.message,
errors: {
create: ['Terjadi kesalahan saat menghubungkan ke server.'],
},
};
}
else {
AccessLog.error = JSON.parse(e.message);
}
});
}
}
}, [
m.trust('&#9113;'),
' Print',
]),
!_isEmpty(AccessLog.error)
? m('span.error.ml-2', AccessLog.error.errors.create[0])
: null,
m('.letter__header', [
m('img[src=img/letter-head.jpg]'),
]),
m('', {
style: {
height: '1px',
width: '100%',
backgroundColor: '#000',
marginTop: '.5rem',
}}),
m('', {
style: {
height: '3px',
width: '100%',
}}),
m('', {
style: {
height: '3px',
width: '100%',
backgroundColor: '#000',
marginBottom: '1rem',
}}),
m('.letter__body', [
m('strong.letter__body-header', [
m('p', m('span.border-b.border-black', 'SURAT KETERANGAN')),
m('p.font-normal.mt-1', 'Nomor: 077/SMK-BA/V/2019'),
]),
m('br'),
m('table', [
m('tr',
m('td[colspan=6]', 'Yang bertanda tangan di bawah ini :')),
m('tr', [
m('td'),
m('td', 'Nama'),
m('td', ':'),
m('td[colspan=3]', 'Drs. Engkos Kosasih, M.M.'),
]),
m('tr', [
m('td'),
m('td', 'Jabatan'),
m('td', ':'),
m('td[colspan=3]', 'Kepala Sekolah'),
]),
m('tr', [
m('td'),
m('td', 'Asal Sekolah'),
m('td', ':'),
m('td[colspan=3]', 'SMK Bhakti Anindya'),
]),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr',
m('td[colspan=6]', 'Menerangkan bahwa')),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr', [
m('td'),
m('td', 'Nama'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.nama),
]),
m('tr', [
m('td'),
m('td', 'Tempat / Tanggal Lahir'),
m('td', ':'),
m('td', Siswa.current.tempat_lahir + ' , ' + Siswa.current.tanggal_lahir),
]),
m('tr', [
m('td'),
m('td', 'NIS / NISN'),
m('td', ':'),
m('td', Siswa.current.nis + ' / ' + Siswa.current.nisn),
]),
m('tr', [
m('td'),
m('td', 'Nomor Peserta'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.nopes),
]),
m('tr', [
m('td'),
m('td', 'Kelas'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.kelas),
]),
m('tr', [
m('td'),
m('td', 'Bidang Studi Keahlian'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.bsk),
]),
m('tr', [
m('td'),
m('td', 'Program Studi Keahlian'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.psk),
]),
m('tr', [
m('td'),
m('td', 'Kompetensi Keahlian'),
m('td', ':'),
m('td[colspan=3]', Siswa.current.kk),
]),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr',
m('td[colspan=6]', 'Adalah benar siswa SMK Bhakti Anindya, Kota Tangerang dan pada tanggal 13 Mei 2019 telah dinyatakan lulus')),
m('tr',
m('td[colspan=6]', 'Berikut hasil belajar siswa tersebut :')),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr',
m('td[colspan=6]',
m('table.nilai', [
m('tr', [
m('th', { style: { width: '5%' } }, 'No.'),
m('th[colspan=2]', 'Mata Pelajaran'),
m('th.long.md:w-1/5', 'Rata-rata Raport Semester 1-6'),
m('th.short.md:w-1/5', 'Raport'),
m('th.long.md:w-1/5', 'Ujian Sekolah Berstandar Nasional'),
m('th.short.md:w-1/5', 'USBN'),
m('th.long.md:w-1/5', 'Ujian Nasional Berbasis Komputer'),
m('th.short.md:w-1/5', 'UNBK'),
]),
m('tr', [
m('th', 'A.'),
m('th[colspan=5].text-left', 'Normatif'),
]),
m('tbody.counter',
_map(Siswa.current.hasil_belajar.meta.normatif, (nilai, mapel) => {
if (nilai.raport != 0) component.rataRata.raport.push(nilai.raport);
if (nilai.usbn != 0) component.rataRata.usbn.push(nilai.usbn);
if (nilai.unbk != 0) component.rataRata.unbk.push(nilai.unbk);
return nilai.raport == 0 && nilai.usbn == 0 && nilai.unbk == 0 ? null : m('tr', [
m('td.text-right'),
m('td[colspan=2]', component.namaMapel[mapel]),
m('td.text-center', nilai.raport !== 0 ? nilai.raport.toFixed(2) : null),
m('td.text-center', nilai.usbn !== 0 ? nilai.usbn.toFixed(2) : null),
m('td.text-center', nilai.unbk !== 0 ? nilai.unbk.toFixed(2) : null),
]);
})),
m('tr', [
m('th', 'B.'),
m('th[colspan=5].text-left', 'Adaptif'),
]),
m('tbody.counter',
_map(Siswa.current.hasil_belajar.meta.adaptif, (nilai, mapel) => {
if (nilai.raport != 0) component.rataRata.raport.push(nilai.raport);
if (nilai.usbn != 0) component.rataRata.usbn.push(nilai.usbn);
if (nilai.unbk != 0) component.rataRata.unbk.push(nilai.unbk);
return nilai.raport == 0 && nilai.usbn == 0 && nilai.unbk == 0 ? null : m('tr', [
m('td.text-right'),
m('td[colspan=2]', component.namaMapel[mapel]),
m('td.text-center', nilai.raport !== 0 ? nilai.raport.toFixed(2) : null),
m('td.text-center', nilai.usbn !== 0 ? nilai.usbn.toFixed(2) : null),
m('td.text-center', nilai.unbk !== 0 ? nilai.unbk.toFixed(2) : null),
]);
}),
m('tr', [
m('th', 'C.'),
m('th[colspan=5].text-left', 'Produktif'),
])),
m('tbody.counter',
_map(Siswa.current.hasil_belajar.meta.produktif, (nilai, mapel) => {
if (nilai.raport != 0) component.rataRata.raport.push(nilai.raport);
if (nilai.usbn != 0) component.rataRata.usbn.push(nilai.usbn);
if (nilai.unbk != 0) component.rataRata.unbk.push(nilai.unbk);
return nilai.raport == 0 && nilai.usbn == 0 && nilai.unbk == 0 ? null : m('tr', [
m('td.text-right'),
m('td[colspan=2]', component.namaMapel[mapel]),
m('td.text-center', nilai.raport !== 0 ? nilai.raport.toFixed(2) : null),
m('td.text-center', nilai.usbn !== 0 ? nilai.usbn.toFixed(2) : null),
m('td.text-center', nilai.unbk !== 0 ? nilai.unbk.toFixed(2) : null),
]);
})),
m('tr', [
m('th', 'D.'),
m('th[colspan=5].text-left', 'Mulok'),
]),
m('tbody.counter',
_map(Siswa.current.hasil_belajar.meta.mulok, (nilai, mapel) => {
if (nilai.raport != 0) component.rataRata.raport.push(nilai.raport);
if (nilai.usbn != 0) component.rataRata.usbn.push(nilai.usbn);
if (nilai.unbk != 0) component.rataRata.unbk.push(nilai.unbk);
return nilai.raport == 0 && nilai.usbn == 0 && nilai.unbk == 0 ? null : m('tr', [
m('td.text-right'),
m('td[colspan=2]', component.namaMapel[mapel]),
m('td.text-center', nilai.raport !== 0 ? nilai.raport.toFixed(2) : null),
m('td.text-center', nilai.usbn !== 0 ? nilai.usbn.toFixed(2) : null),
m('td.text-center', nilai.unbk !== 0 ? nilai.unbk.toFixed(2) : null),
]);
})),
m('tr', [
m('th[colspan=3]', 'Rata-rata'),
m('td.text-center', (component.rataRata.raport.reduce((total, num) => total + num) / component.rataRata.raport.length).toFixed(2)),
m('td.text-center', (component.rataRata.usbn.reduce((total, num) => total + num) / component.rataRata.usbn.length).toFixed(2)),
m('td.text-center', (component.rataRata.unbk.reduce((total, num) => total + num) / component.rataRata.unbk.length).toFixed(2)),
]),
]))),
m('tr',
m('td',
m.trust('&nbsp;'))),
m('tr',
m('td[colspan=6]', 'Demikian Surat Keterangan ini dibuat untuk siswa yang bersangkutan melanjutkan ke jenjang yang lebih tinggi.')),
]),
m('table.signature', [
m('tr',
m('td', 'Tangerang, 13 Mei 2019')),
m('tr',
m('td', 'Kepala Sekolah,')),
m('tr',
m('td',
m('.letter__sign', { style: { height: '3rem' } }))),
m('tr',
m('td', 'Drs. Engkos Kosasih, M.M.')),
]),
]),
]),
];
},
};
export default component;

View File

@ -0,0 +1,279 @@
import m from "mithril";
import _isEmpty from "lodash.isempty"
import Siswa from "../models/Siswa"
import AccessLog from "../models/AccessLog"
var component = {
oninit: () => {
document.title = 'Surat Kelulusan Siswa - SMK Bhakti Anindya';
Siswa.current = {};
AccessLog.fetch('surat-kelulusan');
},
view: () => {
return [
m('.header', [
m('span.italic.text-xs', [
'Saat ini sudah ',
m('strong', [
AccessLog.current.accessed,
' / ',
AccessLog.current.total,
]),
' siswa yang telah melihat pengumuman kelulusan.'
]),
m('h1.title', 'Surat Kelulusan Siswa SMK Bhakti Anindya'),
m('span', 'Silahkan masukkan Nama Lengkap dan NISN kamu di bawah ini.'),
]),
m('form.form', {
onsubmit: e => {
e.preventDefault();
Siswa.cariData({
nisn: e.target.elements.nisn.value,
tanggalLahir: e.target.elements.tanggalLahir.value,
src: 'surat-kelulusan',
});
}
},
m('.form-grid', [
m('.form-group', [
m('label.form-label[for=input-nisn]', 'NISN'),
m('input.form-input.input-text#input-nisn[name=nisn][type=text][autocomplete=off][required]'),
m('p.input-helper', [
'Nomor Induk Siswa Nasional. ',
!_isEmpty(Siswa.error) ?
Siswa.error.errors.siswa != undefined ? m('span.error', Siswa.error.errors.siswa[0] + ' ')
: Siswa.error.errors.nisn != undefined ? m('span.error', Siswa.error.errors.nisn[0] + ' ')
: '' : '',
]),
]),
m('.form-group', [
m('label.form-label[for=input-tanggalLahir]', 'Tanggal Lahir'),
m('input.form-input.input-text#input-tanggalLahir[name=tanggalLahir][type=text][autocomplete=off][required]'),
m('p.input-helper', [
'Tanggal lahir dengan format YYYYMMDD. Contoh: untuk tanggal 29 Mei 2000 ditulis 20000529. ',
!_isEmpty(Siswa.error) && Siswa.error.errors.tanggalLahir != undefined ? m('span.error', Siswa.error.errors.tanggalLahir[0] + ' ') : '',
]),
]),
m('button.form-submit#input-submit[type=submit]', 'Lihat'),
])),
m(!_isEmpty(Siswa.current) ? '.letter' : '.letter.hidden', [
m('span.mobile-info', 'Untuk mencetak surat ini, harap gunakan browser di desktop PC.'),
m('button.print-button', {
onclick: () => {
window.print();
}
}, [
m.trust('&#9113;'),
' Print',
]),
m('.letter__header', [
m('img[src=img/letter-head.jpg]'),
]),
m('', {
style: {
height: '1px',
width: '100%',
backgroundColor: '#000',
marginTop: '.5rem',
}}),
m('', {
style: {
height: '3px',
width: '100%',
}}),
m('', {
style: {
height: '3px',
width: '100%',
backgroundColor: '#000',
marginBottom: '1rem',
}}),
m('.letter__body', [
m('strong.letter__body-header', [
m('p', 'KEPUTUSAN'),
m('p', 'KEPALA SEKOLAH MENENGAH KEJURUAN (SMK) BHAKTI ANINDYA'),
m('p', 'Nomor: 076 / SMK - BA / V / 2019'),
m('p', 'TENTANG'),
m('p', 'KELULUSAN PESERTA UJIAN DARI SATUAN PENDIDIKAN'),
m('p', 'TAHUN PELAJARAN 2018 / 2019'),
m('br'),
m('p', 'KEPALA SMK BHAKTI ANINDYA'),
]),
m('br'),
m('table', [
m('tr', [
m('td', 'Menimbang'),
m('td', ':'),
m('td', '1.'),
m('td[colspan=3]', 'Bahwa dalam rangka pengumuman hasil ujian akhir kelas XII Tahun Pelajaran 2018/2019 dipandang perlu untuk menerbitkan surat keputusan tentang kelulusan peserta ujian dari satuan pendidikan SMK Bhakti Anindya.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '2.'),
m('td[colspan=3]', 'Bahwa peserta ujian yang namanya tercantum pada surat keputusan ini dipandang cakap, kompeten, dan layak untuk dinyatakan lulus dari Satuan Pendidikan SMK Bhakti Anindya.'),
]),
m('br'),
m('tr', [
m('td', 'Mengingat'),
m('td', ':'),
m('td', '1.'),
m('td[colspan=3]', 'Undang Undang No. 20 Tahun 2003 tentang Sistem Pendidikan Nasional.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '2.'),
m('td[colspan=3]', 'Permendikbud Nomor 57 Tahun 2015 Tentang Penilaian Hasil Belajar Oleh Pemerintah Melalui Ujian Nasional Dan Penilaian Hasil Belajar Oleh Satuan Pendidikan Melalui Ujian Sekolah/ Madrasah/ Pendidikan Kesetaraan Pada SMP/ MTs/ Yang Sederajat Dan SMA/ MA/ SMK Atau Yang Sederajat.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '3.'),
m('td[colspan=3]', 'Peraturan BSNP NOMOR: 0047/P/BSNP/XI/2018 tentang Prosedur Operasional Standar Penyelenggaraan Ujian Nasional Tahun Pelajaran 2018/2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '4.'),
m('td[colspan=3]', 'Peraturan BSNP NOMOR: 0048/BSNP/XI/2018 tentang Prosedur Operasional Standar Penyelenggaraan Ujian Sekolah Berstandar Nasaional Tahun Pelajaran 2018/2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '5.'),
m('td[colspan=3]', 'Pedoman Penyelenggaraan UKK dan Sertifikasi Siswa SMK pada Ujian Nasional Tahun Pelajaran 2017/2018.'),
]),
m('br'),
m('tr', [
m('td', 'Memperhatikan'),
m('td', ':'),
m('td', '1.'),
m('td[colspan=3]', 'Nilat raport semester 1 6 Tahun Pelajaran 2016/2017 2018/2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '2.'),
m('td[colspan=3]', 'Nilai Hasil Ujian Praktik Kejuruan ( UPK ) yang diselenggarakan tanggal 1 April s.d 3 Mei 2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '3.'),
m('td[colspan=3]', 'Nilai Hasil Ujian Sekolah Berstandar Nasional (USBN) yang diselenggarakan tanggal 05 12 April 2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '4.'),
m('td[colspan=3]', 'Nilai Hasil Ujian Nasional Berbasis Komputer (UNBK) yang diselenggarakan tanggal 25 28 Maret 2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '5.'),
m('td[colspan=3]', 'Hasil pengamatan dan penilaian mengenai sikap, prilaku, dan kepribadian yang bersangkutan selama menjadi siswa SMK Bhakti Anindya.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '6.'),
m('td[colspan=3]', 'Hasil Rapat Pleno Dewan Guru SMK Bhakti Anindya tanggal 10 Mei 2019.'),
]),
m('tr', [
m('td[colspan=2]'),
m('td', '7.'),
m('td[colspan=3]', 'Surat Keputusan Tentang Kriteria Kelulusan dari Satuan Pendidikan.'),
]),
m('tr',
m('td.text-center[colspan=6]', 'MEMUTUSKAN :')),
m('tr', [
m('td', 'Menetapkan'),
m('td', ':'),
]),
m('tr', [
m('td', 'Pertama'),
m('td', ':'),
m('td'),
m('td', 'Nama Peserta'),
m('td.strong', ':'),
m('td.strong', Siswa.current.nama),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Tempat & Tanggal Lahir'),
m('td.strong', ':'),
m('td.strong', Siswa.current.tempat_lahir + ' , ' + Siswa.current.tanggal_lahir),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'NIS / NISN'),
m('td.strong', ':'),
m('td.strong', Siswa.current.nis + ' / ' + Siswa.current.nisn),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Nomor Peserta'),
m('td.strong', ':'),
m('td.strong', Siswa.current.nopes),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Bidang Studi Keahlian'),
m('td.strong', ':'),
m('td.strong', Siswa.current.bsk),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Program Studi Keahlian'),
m('td.strong', ':'),
m('td.strong', Siswa.current.psk),
]),
m('tr', [
m('td[colspan=3]'),
m('td', 'Kompetensi Keahlian'),
m('td.strong', ':'),
m('td.strong', Siswa.current.kk),
]),
m('tr', [
m('td[colspan=3]'),
m('td[colspan=3]', [
'Dinyatakan ',
m('span.special', 'LULUS'),
' dari satuan pendidikan SMK Bhakti Anindya Tahun Pelajaran 2018/2019',
]),
]),
m('br'),
m('tr', [
m('td', 'Kedua'),
m('td', ':'),
m('td[colspan=4]', 'Surat Keputusan ini dikeluarkan sebagai pengganti ijazah yang akan diterbitkan kemudian.'),
]),
m('tr', [
m('td', 'Ketiga'),
m('td', ':'),
m('td[colspan=4]', 'Apabila dalam Surat Keputusan ini terdapat kekeliruan akan dilakukan perbaikan sebagaimana mestinya.'),
]),
m('tr', [
m('td', 'Keempat'),
m('td', ':'),
m('td[colspan=4]', 'Surat Keputusan ini berlaku terhitung mulai tanggal ditetapkan.'),
]),
]),
m('table.signature', [
m('tr', [
m('td', 'Ditetapkan di'),
m('td', ':'),
m('td', 'Tangerang'),
]),
m('tr', [
m('td', 'Pada Tanggal'),
m('td', ':'),
m('td', '13 Mei 2019'),
]),
m('tr',
m('td', 'Kepala Sekolah,')),
m('tr',
m('td[colspan=3]',
m('.letter__sign'))),
m('tr',
m('td[colspan=3]', 'Drs. Engkos Kosasih, M.M.')),
]),
]),
]),
];
},
};
export default component;

View File

@ -2,15 +2,42 @@ import m from "mithril"
var model = {
current: {},
fetch: () => {
m.request({
error: {},
fetch: src => {
model.current = {};
model.error = {};
return m.request({
method: 'get',
url: '/api/access_log',
data: { src },
})
.then(response => {
model.current = response;
});
.then(response => {
model.current = response;
})
.catch(e => {
if (e.code === 0) {
model.error = {
message: e.message,
errors: {
accessLog: ['Terjadi kesalahan saat menghubungkan ke server.']
},
};
}
else
model.error = JSON.parse(e.message);
});
},
}
create: data => {
model.error = {};
return m.request({
method: 'post',
url: '/api/access_log',
data,
})
.then(response => {
model.current = response;
});
},
};
export default model;

View File

@ -6,6 +6,7 @@ var model = {
error: {},
cariData: data => {
model.current = {};
model.error = {},
m.request({
method: 'post',
url: '/api/siswa',
@ -13,10 +14,19 @@ var model = {
})
.then(response => {
model.current = response;
AccessLog.fetch();
AccessLog.fetch(data.src);
})
.catch(e => {
model.error = JSON.parse(e.message);
if (e.code === 0) {
model.error = {
message: e.message,
errors: {
siswa: ['Terjadi kesalahan saat menghubungkan ke server.'],
},
};
}
else
model.error = JSON.parse(e.message);
});
},
}

View File

@ -84,6 +84,29 @@ span.error {
}
}
table.nilai {
th, td {
@apply border border-black px-1;
}
.long {
@apply hidden;
}
.short {
display: table-cell;
}
tbody.counter {
counter-reset: nomor;
td:first-child::before {
counter-increment: nomor;
content: counter(nomor) ".";
}
}
}
table.signature {
@apply w-auto ml-auto mt-4;
@ -156,6 +179,16 @@ span.error {
.print-button {
display: initial;
}
table.nilai {
.long {
display: table-cell;
}
.short {
@apply hidden;
}
}
}
}
@ -183,5 +216,15 @@ span.error {
.letter__body-header {
font-size: 14px;
}
table.nilai {
.long {
display: table-cell;
}
.short {
@apply hidden;
}
}
}
}

View File

@ -10,12 +10,12 @@
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro" rel="stylesheet">
<!-- Styles -->
<link rel="stylesheet" href="css/main.css">
<link rel="stylesheet" href="{{ asset('css/main.css') }}">
</head>
<body>
<div class="container">
</div>
<script src="js/app.js"></script>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pendopo</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
<!-- Style -->
<link href="{{ asset('css/main.css') }}" rel="stylesheet">
</head>
<body>
<div id="pendopo" class="container">
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

View File

@ -13,55 +13,20 @@ use Illuminate\Http\Request;
|
*/
Route::post('/siswa', function (Request $request) {
// Validate user inputs
// Auto redirect on fail
Validator::make($request->all(), [
'nisn' => 'required|regex:/^[0-9]+$/',
'tanggalLahir' => 'required|regex:/^[0-9]+$/',
], [
'required' => 'Kolom :attribute harus diisi.',
'regex' => 'Kolom :attribute tidak sesuai.',
])->validate();
Route::post('/siswa', 'SiswaController')->name('siswa.retrieve');
// Look for the given inputs in the resource
Route::post('/hasil_belajar', 'HasilBelajarController')->name('hasilBelajar.retrieve');
Route::get('/access_log', 'AccessLogController')->name('accessLog.fetch');
Route::post('/access_log', function(Request $request) {
try {
$tanggalLahir = Carbon\Carbon::parse($request->tanggalLahir)->format('Y-m-d');
} catch(Exception $e) {
App\AccessLog::create(['siswa_id' => $request->siswaId, 'src' => $request->src]);
} catch (Exception $e) {
return response()->json([
'message' => 'The given data was invalid.',
'message' => $e->getMessage(),
'errors' => [
'tanggalLahir' => ['Kolom tanggal lahir tidak sesuai.'],
]
], 422);
'create' => ['Telah terjadi kesalahan pada server.'],
],
], (int)$e->getCode() ?: 500);
}
$siswa = App\Siswa::where('nisn', $request->nisn)
->where('tanggal_lahir', $tanggalLahir)
->first();
// Redirect with error if not found
if (!$siswa || $siswa == null) {
return response()->json(['errors' => ['siswa' => ['Siswa tidak ditemukan.']]], 404);
}
// Write to log
App\AccessLog::create(['siswa_id' => $siswa->id]);
return $siswa;
});
Route::get('/access_log', function () {
// Get the number of unique access
$logs = DB::table('access_logs')->select(DB::raw('count(*) as num'))
->groupBy('siswa_id')
->get()
->count();
// Get the total number of available resource
$resources = App\Siswa::count();
return response()->json([
'accessed' => $logs,
'total' => $resources,
]);
});
})->name('accessLog.create');

View File

@ -14,3 +14,7 @@
Route::get('/', function () {
return view('main');
});
Route::get('/pendopo', function () {
return view('pendopo');
})->middleware('pendopo');