4 Commits

Author SHA1 Message Date
ismailmasseran 0cb85c2375 Merge pull request 'resolve bugs laporan audit operasi' (#13) from fix/resolve-bugs-laporan-audit-operasi into main
Reviewed-on: #13
2026-09-02 11:58:46 +08:00
nurafrinaalimi16 2a0ffde016 resolve bugs laporan audit operasi 2026-09-02 11:55:28 +08:00
ismailmasseran 92991f0d10 Prod kopkb (#12)
Co-authored-by: dev_kopkb <xtrabiz.sb@gmail.com>
Co-authored-by: nurafrinaalimi16 <nurafrinaalimi16@gmail.com>
Co-authored-by: root <root@erahn.click>
Reviewed-on: #12
2026-09-01 15:10:30 +08:00
ismailmasseran 1f8642e230 DONE: add cicd for staging (#1)
Build Docker Image / build-frontend (push) Successful in 22s
Co-authored-by: ISMAIL MASSERAN <topaz@ISMAILs-Macbook.local>
Reviewed-on: #1
2026-08-26 13:36:18 +08:00
20 changed files with 1060 additions and 259 deletions
+16
View File
@@ -0,0 +1,16 @@
.git
.gitea
node_modules
vendor
.env
.env.*
!.env.example
storage/logs
storage/framework/cache
storage/framework/sessions
storage/framework/views
storage/debugbar
npm-debug.log
Dockerfile
docker-compose.yml
docker-compose.staging.yml
+55
View File
@@ -0,0 +1,55 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:O1XZDqK4H6+3GdrODgCaLr2l+OoWvgVhYr0GJ1KizW8=
APP_DEBUG=true
APP_URL=http://localhost
# API_URL=http://api-annurv2.test
API_URL=http://host.docker.internal:8080
# Server-side Http:: from Docker — same rules as API_URL. Defaults in config/api.php use localhost:8000 which fails inside containers.
API_URL_KOOP=http://host.docker.internal:8080
API_URL_PKB=http://host.docker.internal:8080
API_ARRAHNBID=http://lelong.test/api/
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=kaunter_erahn
DB_USERNAME=kaunteruser
DB_PASSWORD=password
BROADCAST_DRIVER=pusher
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
PUSHER_APP_ID=1132718
PUSHER_APP_KEY=26b0ec2f297f94b7aa9b
PUSHER_APP_SECRET=421b61fb5a8ecce477a6
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
MYKAD_READER_PORT=8085
MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED
+57
View File
@@ -0,0 +1,57 @@
APP_NAME=Laravel
APP_ENV=staging
APP_KEY=base64:O1XZDqK4H6+3GdrODgCaLr2l+OoWvgVhYr0GJ1KizW8=
APP_DEBUG=true
APP_URL=http://172.16.6.200:8091
HTTP_PORT=8091
MYSQL_PUBLISH_PORT=3309
API_URL=http://172.16.6.200:8090
API_URL_KOOP=http://172.16.6.200:8090
API_URL_PKB=http://172.16.6.200:8090
API_ARRAHNBID=http://lelong.test/api/
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=kaunter_erahn
DB_USERNAME=kaunteruser
DB_PASSWORD=password
BROADCAST_DRIVER=pusher
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
PUSHER_APP_ID=1132718
PUSHER_APP_KEY=26b0ec2f297f94b7aa9b
PUSHER_APP_SECRET=421b61fb5a8ecce477a6
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
MYKAD_READER_PORT=8085
MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED
+50
View File
@@ -0,0 +1,50 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:WRTHcFTq5YARKVdA8YDUzsh9Ue8vD63ivgZgXNNBiGo=
APP_DEBUG=true
APP_URL=http://ujrahkopkb.erahn.com.my
API_URL=http://apiujrah-kopkb.erahn.com.my
#API_ARRAHNBID=http://lelong.test/api/
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=kaunter_erahn
DB_USERNAME=spider
DB_PASSWORD=G0dz!ll4
BROADCAST_DRIVER=pusher
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
PUSHER_APP_ID=1132718
PUSHER_APP_KEY=26b0ec2f297f94b7aa9b
PUSHER_APP_SECRET=421b61fb5a8ecce477a6
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
MYKAD_READER_PORT=8085
MYKAD_READER_ENABLED_CAWANGAN='' # IF NO CAWANGAN STATED, ALL CAWANGAN IS ENABLED
+49
View File
@@ -0,0 +1,49 @@
name: Build Docker Image
on:
push:
branches:
- staging
tags:
- "v*"
workflow_dispatch:
jobs:
build-frontend:
runs-on: docker
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Login to Docker registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | \
docker login git.koppkb.com \
-u "${{ secrets.REGISTRY_USERNAME }}" \
--password-stdin
- name: Build & push frontend image
run: |
set -e
IMAGE="git.koppkb.com/kopkb/kaunter"
TAGS="-t ${IMAGE}:${{ gitea.sha }}"
if [ "${{ gitea.ref_type }}" = "tag" ] && echo "${{ gitea.ref_name }}" | grep -q '^v'; then
TAGS="${TAGS} -t ${IMAGE}:${{ gitea.ref_name }}"
fi
if [ "${{ gitea.ref_name }}" = "staging" ]; then
TAGS="${TAGS} -t ${IMAGE}:staging"
fi
echo "Building and pushing frontend: ${TAGS}"
docker buildx build \
--target staging \
--platform linux/amd64 \
--cache-from type=registry,ref=${IMAGE}:buildcache,ignore-error=true \
--cache-to type=registry,ref=${IMAGE}:buildcache,mode=max \
-f docker/php/Dockerfile \
${TAGS} \
--push .
+123
View File
@@ -0,0 +1,123 @@
name: Deploy to Staging
on:
workflow_dispatch:
inputs:
image_tag:
description: "Docker image tag to deploy (commit SHA, staging, or v*)"
required: true
default: "staging"
type: string
env:
APP_IMAGE: git.koppkb.com/kopkb/kaunter
DEPLOY_DIR: /home/arrahn/Project/kaunter
jobs:
deploy:
runs-on: host
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ inputs.image_tag }}
- name: Login to Docker registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | \
docker login git.koppkb.com \
-u "${{ secrets.REGISTRY_USERNAME }}" \
--password-stdin
- name: Verify image exists in registry
run: |
set -e
IMAGE_TAG="${{ inputs.image_tag }}"
IMAGE="${APP_IMAGE}:${IMAGE_TAG}"
echo "Checking if image exists: ${IMAGE}"
if ! docker manifest inspect "${IMAGE}" > /dev/null 2>&1; then
echo "ERROR: Image ${IMAGE} does not exist in registry!"
echo "Run the Build Docker Image workflow first."
exit 1
fi
echo "✓ ${IMAGE} found"
- name: Pull Docker image
run: |
set -e
IMAGE_TAG="${{ inputs.image_tag }}"
docker pull "${APP_IMAGE}:${IMAGE_TAG}"
echo "✓ Image pulled successfully"
- name: Sync compose file and deploy
run: |
set -e
IMAGE_TAG="${{ inputs.image_tag }}"
mkdir -p "${DEPLOY_DIR}/docker/nginx"
cp docker-compose.staging.yml "${DEPLOY_DIR}/docker-compose.yml"
cp docker/nginx/default.conf "${DEPLOY_DIR}/docker/nginx/default.conf"
rm -rf "${DEPLOY_DIR}/public"
cp -R public "${DEPLOY_DIR}/public"
if [ ! -f "${DEPLOY_DIR}/.env.staging" ]; then
if [ -f .env.staging ]; then
cp .env.staging "${DEPLOY_DIR}/.env.staging"
echo "Copied .env.staging from repo (first deploy). Edit ${DEPLOY_DIR}/.env.staging on the server if needed."
else
echo "ERROR: ${DEPLOY_DIR}/.env.staging is missing on the server"
exit 1
fi
fi
cd "${DEPLOY_DIR}"
export APP_IMAGE
export IMAGE_TAG
docker compose --env-file .env.staging -f docker-compose.yml pull app
docker compose --env-file .env.staging -f docker-compose.yml up -d --no-build --remove-orphans
echo "✓ Deployed IMAGE_TAG=${IMAGE_TAG}"
- name: Verify deployment
run: |
set -e
cd "${DEPLOY_DIR}"
echo "Waiting for services to start..."
sleep 10
for SERVICE in app web mysql; do
STATUS=$(docker compose --env-file .env.staging -f docker-compose.yml ps --status running --format '{{.Name}}' "$SERVICE" 2>/dev/null || true)
if [ -z "$STATUS" ]; then
echo "ERROR: ${SERVICE} is not running"
docker compose --env-file .env.staging -f docker-compose.yml ps
docker compose --env-file .env.staging -f docker-compose.yml logs --tail=50 "$SERVICE" || true
exit 1
fi
echo "✓ ${SERVICE} is running (${STATUS})"
done
HTTP_PORT=$(grep -E '^HTTP_PORT=' .env.staging 2>/dev/null | cut -d= -f2- | tr -d '"' || true)
HTTP_PORT=${HTTP_PORT:-8091}
check_health() {
NAME=$1
URL=$2
for i in 1 2 3 4 5 6; do
if curl -sf "$URL" > /dev/null; then
echo "✓ ${NAME} health check passed (${URL})"
return 0
fi
echo "Waiting for ${NAME}... attempt ${i}/6"
sleep 5
done
echo "ERROR: ${NAME} health check failed (${URL})"
docker compose --env-file .env.staging -f docker-compose.yml logs --tail=50 app web || true
return 1
}
check_health "kaunter" "http://127.0.0.1:${HTTP_PORT}/health"
+153 -5
View File
@@ -87,13 +87,19 @@ class OperasiController extends Controller
'siri' => $request->siri
])->json();
$updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/UpdateKelulusan/' . $request->kodcaw . '/' . $norujukan, [
$updateData = [
'sahkan' => 1,
'namaoperasi' => $request->namaoperasi,
'siri' => $request->siri
])->json();
} else {
$updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/UpdateHapusAnsuran', [
];
if ($request->has('actions')) {
$updateData['actions'] = $request->actions;
}
$updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/UpdateKelulusan/' . $request->kodcaw . '/' . $norujukan, $updateData)->json();
}else{
$updatelulus = Http::withOptions(['verify' => config('app.api_verify')])->put(config('api.url') . '/api/UpdateHapusAnsuran',[
'siri' => $request->siri,
"kodcaw" => $request->kodcaw,
"norujukan" => $request->norujukan,
@@ -139,6 +145,49 @@ class OperasiController extends Controller
return response()->json($updatelulus, 200);
}
public function createKelulusanByKhazanah(Request $request)
{
$auth_user = Auth::user();
$api_url = config('api.url');
$current = Carbon::now();
$current = new Carbon();
$norujukan = $request->norujukan;
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
$getsiri = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/ListLatestLulus/'. $auth_user['cawangan'] . '/' . $norujukan)->json();
if(isset($getsiri['siri']))
{
$siri = $getsiri['siri'] + 1;
}else{
$siri = 1;
}
$createlulus = Http::withOptions(['verify' => config('app.api_verify')])->post(config('api.url') . '/api/CreateKelulusan/' . $auth_user['cawangan'] . '/' . $norujukan . '/roles/khazanah', [
'komen' => $request->komen,
'dategadai' => $current->toDateString(),
'bilgadai' => 1,
'siri' => $siri,
'margin' => $request->margin,
'berat' => $request->berat,
'nilaimarhun' => $request->nilaimarhun,
'status' => $request->status,
'jumpinjam' => $request->jumpinjam,
'jenistebus' => "G",
'teller' => $request->teller,
'peloperasi' => "operasi",
'pelulus' => "operasi",
'actions' => "Mohon Pengesahan Pembayaran Pampasan"
])->json();
event(new OperasiNotice($auth_user['cawangan'],$auth_user['name']));
return response()->json($siri,201);
}
public function updatekelulusananggota(Request $request)
{
$auth_user = Auth::user();
@@ -149,7 +198,7 @@ class OperasiController extends Controller
$kodcaw = $request->kodcaw;
$komen = $request->komenkelulusan;
$namaoperasi = $request->namaoperasi;
$taglulus = $request->taglulus; // contoh: 'Y' = lulus, 'N' = batal
$taglulus = $request->taglulus; // contoh: 'Y' = lulus, 'N' = batalmarginmutu()
// 1️⃣ Tentukan status kelulusan
$status = ($taglulus == 'Y') ? 1 : 2; // 1 = Lulus, 2 = Batal/Tolak
@@ -401,4 +450,103 @@ class OperasiController extends Controller
return view('operasi.kelulusan_anggota', compact('cawangan_info', 'api_url', 'arraykelulusan'));
}
public function marginmutu()
{
$auth_user = Auth::user();
$api_url = config('api.url');
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
// Get MaxMutuEmas data from API
$maxmutuemas = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/maxmutuemas')->json();
return view('operasi.marginmutu', compact('cawangan_info', 'api_url', 'maxmutuemas'));
}
public function editMarginMutu()
{
$auth_user = Auth::user();
$api_url = config('api.url');
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
return view('operasi.edit_marginmutu', compact('cawangan_info', 'api_url'));
}
public function laporanAudit()
{
$auth_user = Auth::user();
$api_url = config('api.url');
$cawangan_info = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url') . '/api/cawangan/'. $auth_user['cawangan'])->json();
return view('homepage.operasi.laporan-audit', compact('cawangan_info', 'api_url'));
}
public function cetakLaporanAuditTrail(Request $request)
{
$api_url = config('api.url');
$auth_user = Auth::user();
$current = Carbon::now();
$current = new Carbon();
$tarikh_cetak = $current->toDateString();
if($request->dateaudit == null){
$date = $current->toDateString();
}else{
$split_date = explode('-', $request->dateaudit);
$date = $split_date[0] . '-' . $split_date[1] . '-' . $split_date[2];
}
if($request->dateaudit_till == null){
$date_till = $current->toDateString();
}else{
$split_date_till = explode('-', $request->dateaudit_till);
$date_till = $split_date_till[0] . '-' . $split_date_till[1] . '-' . $split_date_till[2];
}
$audittrail_raw = Http::withOptions(['verify' => config('app.api_verify')])->get(config('api.url'). '/api/reports/audittrail/operasi',['date' => $date,'date_till' => $date_till])->json();
if(!$audittrail_raw){
return redirect()->back()->with('errormessage', 'Tiada data pada tarikh tersebut.');
}
// Transform the data to match view format
$audittrail = [];
foreach($audittrail_raw as $item) {
$created_at = \Carbon\Carbon::parse($item['created_at']);
// Format differences for display
$differences_text = '-';
if (isset($item['differences']) && !empty($item['differences'])) {
$diff_parts = [];
foreach ($item['differences'] as $field => $changes) {
$old = $changes['old'] ?? 'null';
$new = $changes['new'] ?? 'null';
$diff_parts[] = "{$field}: {$old}{$new}";
}
$differences_text = implode('; ', $diff_parts);
}
$audittrail[] = [
'tarikh' => $created_at->format('d/m/Y'),
'masa' => $created_at->format('H:i:s'),
'users' => $item['users'],
'actions' => $item['actions'],
'differ' => $differences_text
];
}
$cawangan_detail = [
'kodcaw' => 'operasi',
'namacaw' => 'Operasi Ar-Rahn',
'alamat1' => 'Lot 107, Jalan Parit Dalam,',
'alamat2' => 'Seksyen 8',
'poskod' => '15000',
'bandar' => 'Kota Bahru',
'negeri' => 'Kelantan',
'notel' => '03-12345678',
'nofaks' => '03-12345678',
];
return view('print.laporan_audittrail_operasi', compact('audittrail','cawangan_detail','tarikh_cetak','date','date_till','api_url'));
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
<?php
return [
'url' => env('API_URL'),
'url_koop' => env('API_URL_KOOP','http://localhost:8000'),
'url_koop' => env('API_URL_KOOP','https://apiujrah.erahn.com.my'),
'url_pkb' => env('API_URL_PKB','http://localhost:8000'),
];
+77
View File
@@ -0,0 +1,77 @@
# Staging stack — isolated from local docker-compose.yml (8081 / 3307)
# and from api_arrahn staging (8090 / 3308).
#
# Local:
# docker compose --env-file .env.staging -f docker-compose.staging.yml up -d --build
#
# CI (image already in registry):
# APP_IMAGE=git.koppkb.com/kopkb/kaunter IMAGE_TAG=<sha> \
# docker compose --env-file .env.staging -f docker-compose.staging.yml up -d --no-build
#
# Host nginx reverse-proxies the public domain to 127.0.0.1:${HTTP_PORT}.
# See docker/nginx/host-proxy.example.conf
#
# If 8091 or 3309 is already taken, set HTTP_PORT / MYSQL_PUBLISH_PORT in .env.staging.
name: kaunter_staging
services:
app:
image: ${APP_IMAGE:-kaunter}:${IMAGE_TAG:-staging}
build:
context: .
dockerfile: docker/php/Dockerfile
target: staging
container_name: kaunter_staging_app
working_dir: /var/www/html
volumes:
- storage_staging:/var/www/html/storage
- ./.env.staging:/var/www/html/.env.staging:ro
env_file:
- .env.staging
environment:
APP_ENV: staging
USE_STAGING_ENV: "true"
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
mysql:
condition: service_healthy
restart: unless-stopped
web:
image: nginx:1.25-alpine
container_name: kaunter_staging_web
ports:
- "${HTTP_PORT:-8091}:80"
volumes:
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./public:/var/www/html/public:ro
depends_on:
- app
restart: unless-stopped
mysql:
image: mysql:8.0
container_name: kaunter_staging_mysql
command: --default-authentication-plugin=mysql_native_password
ports:
- "127.0.0.1:${MYSQL_PUBLISH_PORT:-3309}:3306"
environment:
MYSQL_DATABASE: kaunter_erahn
MYSQL_USER: kaunteruser
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: root
volumes:
- mysql_staging_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-proot"]
interval: 5s
timeout: 5s
retries: 30
start_period: 20s
restart: unless-stopped
volumes:
mysql_staging_data:
storage_staging:
+43
View File
@@ -0,0 +1,43 @@
services:
app:
build:
context: .
dockerfile: docker/php/Dockerfile
target: development
working_dir: /var/www/html
volumes:
- ./:/var/www/html:cached
environment:
APP_ENV: local
APP_DEBUG: "true"
# Lets PHP resolve host.docker.internal to the host machine (Linux Docker; Desktop already provides this).
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- mysql
web:
image: nginx:1.25-alpine
ports:
- "8081:80"
volumes:
- ./:/var/www/html:cached
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- app
mysql:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
ports:
- "3307:3306"
environment:
MYSQL_DATABASE: kaunter_erahn
MYSQL_USER: kaunteruser
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: root
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
+36
View File
@@ -0,0 +1,36 @@
server {
listen 80;
server_name _;
root /var/www/html/public;
index index.php index.html;
charset utf-8;
client_max_body_size 50M;
location / {
try_files $uri $uri/ @php;
}
location @php {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/html/public/index.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_read_timeout 120s;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_read_timeout 120s;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
+51
View File
@@ -0,0 +1,51 @@
FROM php:7.4-fpm AS base
WORKDIR /var/www/html
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
git \
pkg-config \
unzip \
libonig-dev \
libzip-dev \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j"$(nproc)" \
pdo_mysql \
mbstring \
bcmath \
zip \
exif \
gd \
&& rm -rf /var/lib/apt/lists/*
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
COPY docker/php/php.ini /usr/local/etc/php/conf.d/app.ini
COPY docker/php/zz-clear-env.conf /usr/local/etc/php-fpm.d/zz-clear-env.conf
COPY docker/php/entrypoint.sh /usr/local/bin/app-entrypoint.sh
RUN chmod +x /usr/local/bin/app-entrypoint.sh \
&& usermod -u 1000 www-data && groupmod -g 1000 www-data
ENTRYPOINT ["app-entrypoint.sh"]
CMD ["php-fpm"]
FROM base AS staging
COPY --chown=www-data:www-data . /var/www/html
RUN composer install --no-interaction --prefer-dist --no-dev --optimize-autoloader --no-scripts \
&& mkdir -p \
storage/logs \
storage/framework/cache/data \
storage/framework/views \
storage/framework/sessions \
storage/app/public \
bootstrap/cache \
&& chown -R www-data:www-data storage bootstrap/cache vendor
FROM base AS development
+35
View File
@@ -0,0 +1,35 @@
#!/bin/sh
set -e
cd /var/www/html
if [ "${USE_STAGING_ENV:-false}" = "true" ] && [ -f .env.staging ]; then
cp .env.staging .env
fi
if [ -f composer.json ]; then
if [ -f vendor/autoload.php ] && [ "${USE_STAGING_ENV:-false}" = "true" ]; then
: # vendor is baked into the staging image
elif [ "${USE_STAGING_ENV:-false}" = "true" ]; then
composer install --no-interaction --prefer-dist --no-dev --optimize-autoloader --no-scripts
else
composer install --no-interaction --prefer-dist
fi
fi
mkdir -p \
storage/logs \
storage/framework/cache/data \
storage/framework/views \
storage/framework/sessions \
storage/app/public \
bootstrap/cache
if [ -f artisan ]; then
php artisan package:discover --ansi
php artisan storage:link --force >/dev/null 2>&1 || true
fi
chown -R www-data:www-data storage bootstrap/cache
exec docker-php-entrypoint "$@"
+4
View File
@@ -0,0 +1,4 @@
memory_limit=512M
upload_max_filesize=50M
post_max_size=50M
max_execution_time=120
+3
View File
@@ -0,0 +1,3 @@
[www]
; Pass container env vars (from compose env_file) through to PHP workers.
clear_env = no
+30 -32
View File
@@ -525,38 +525,36 @@ var api_url = @json($api_url ?? '');
});
// Logik amaran SweetAlert
if("{{ auth()->user()->cawangan }}" == 'X0301'){
if (search === true) {
if (blacklist_search === true) {
Swal.fire({
icon: 'warning',
title: 'Amaran!',
text: 'Pelanggan telah disenarai hitamkan dari Pembiayaan.'
});
}
else if (isAnggota && !isPelanggan) {
Swal.fire({
icon: 'info',
title: 'Anggota Belum Didaftarkan!',
text: 'Pelanggan ini adalah anggota koperasi tetapi belum berdaftar sebagai pelanggan.'
});
}
else if (isPelanggan && !isAnggota) {
Swal.fire({
icon: 'info',
title: 'Pelanggan Bukan Anggota!',
text: 'Pelanggan ini berdaftar tetapi belum menjadi anggota koperasi.'
});
}
else if (!isAnggota && !isPelanggan) {
Swal.fire({
icon: 'info',
title: 'Pelanggan Tiada Dalam Rekod!',
text: 'Sila Daftar Pelanggan.'
});
}
}
}
if (search === true) {
if (blacklist_search === true) {
Swal.fire({
icon: 'warning',
title: 'Amaran!',
text: 'Pelanggan telah disenarai hitamkan dari Pembiayaan.'
});
}
else if (isAnggota && !isPelanggan) {
Swal.fire({
icon: 'info',
title: 'Anggota Belum Didaftarkan!',
text: 'Pelanggan ini adalah anggota koperasi tetapi belum berdaftar sebagai pelanggan.'
});
}
else if (isPelanggan && !isAnggota) {
Swal.fire({
icon: 'info',
title: 'Pelanggan Bukan Anggota!',
text: 'Pelanggan ini berdaftar tetapi belum menjadi anggota koperasi.'
});
}
else if (!isAnggota && !isPelanggan) {
Swal.fire({
icon: 'info',
title: 'Pelanggan Tiada Dalam Rekod!',
text: 'Sila Daftar Pelanggan.'
});
}
}
});
+174 -172
View File
@@ -75,7 +75,8 @@
->json();
@endphp
<input type="text" class="form-control" name="outstanding_semasa"
id="outstanding_semasa" readonly value="{{ number_format($outstanding_semasa, 2) }}">
id="outstanding_semasa" readonly
value="{{ number_format($outstanding_semasa, 2) }}">
</div>
</div>
@@ -157,7 +158,7 @@
<!-- Butang Assign Sebagai Anggota -->
@if (isset($showAssignAnggotaBtn) && $showAssignAnggotaBtn && auth()->user()->cawangan == 'X0301')
@if (isset($showAssignAnggotaBtn) && $showAssignAnggotaBtn)
<div class="m-0 p-2">
<button type="button" class="btn btn-success d-flex align-items-center"
data-noic="{{ $noic }}" onclick="assignAnggota(this)">
@@ -363,31 +364,31 @@
data-toggle="tab" href="#nav-tawarruq" role="tab" aria-controls="nav-tawarruq"
aria-selected="{{ $aria_selected_SAG_baru }}">SAG Baru</a>
<a class="nav-item nav-link {{ $activate_tab_SAG_lama }}" " id="nav-xtawarruq-tab" data-toggle="tab" href="#nav-xtawarruq" role="tab" aria-controls="nav-xtawarruq" aria-selected="{{ $aria_selected_SAG_lama }}"><span id="textnavsag">SAG Lama</span></a>
</div>
</nav>
<div class="tab-content" id="navtawarruqdannottawarruq">
<div class="tab-pane fade {{ $activate_pane_SAG_baru }}" id="nav-tawarruq" role="tabpanel" aria-labelledby="nav-tawarruq-tab">
<table class="table table-striped table-hover" id="myTable">
<thead class="thead-dark">
<tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Pembiayaan</th>
<th>Tarikh Matang</th>
<th>Baki Harga Jualan</th>
<th>Baki Pembiayaan</th>
<th>Margin</th>
<th>Tempoh</th>
<th>Keuntungan</th>
<th>Lelong</th>
</tr>
</thead>
</table>
</div>
<div class="tab-pane fade {{ $activate_pane_SAG_lama }}" id="nav-xtawarruq" role="tabpanel" aria-labelledby="nav-xtawarruq-tab">
<table id="xtawarruq" class="table table-striped table-hover">
<thead class="thead-dark">
{{-- <tr>
</div>
</nav>
<div class="tab-content" id="navtawarruqdannottawarruq">
<div class="tab-pane fade {{ $activate_pane_SAG_baru }}" id="nav-tawarruq" role="tabpanel" aria-labelledby="nav-tawarruq-tab">
<table class="table table-striped table-hover" id="myTable">
<thead class="thead-dark">
<tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Pembiayaan</th>
<th>Tarikh Matang</th>
<th>Baki Harga Jualan</th>
<th>Baki Pembiayaan</th>
<th>Margin</th>
<th>Tempoh</th>
<th>Keuntungan</th>
<th>Lelong</th>
</tr>
</thead>
</table>
</div>
<div class="tab-pane fade {{ $activate_pane_SAG_lama }}" id="nav-xtawarruq" role="tabpanel" aria-labelledby="nav-xtawarruq-tab">
<table id="xtawarruq" class="table table-striped table-hover">
<thead class="thead-dark">
{{-- <tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Gadai</th>
@@ -397,139 +398,139 @@
<th>Tempoh</th>
<th>Lelong</th>
</tr> --}}
<tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Pembiayaan</th>
<th>Tarikh Matang</th>
<th>Baki Harga Jualan</th>
<th>Baki Pembiayaan</th>
<th>Margin</th>
<th>Tempoh</th>
<th>Keuntungan</th>
<th>Lelong</th>
</tr>
</thead>
</table>
<tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Pembiayaan</th>
<th>Tarikh Matang</th>
<th>Baki Harga Jualan</th>
<th>Baki Pembiayaan</th>
<th>Margin</th>
<th>Tempoh</th>
<th>Keuntungan</th>
<th>Lelong</th>
</tr>
</thead>
</table>
</div>
</div>
{{-- Sudah Tebus --}}
<table id="dahtebusTable" class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Penyelesaian Pembiayaan</th>
<th>Baki Pembiayaan</th>
<th>Margin</th>
<th>Tempoh</th>
</tr>
</thead>
</table>
<table id="lelongTable" class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Lelong</th>
<th>Tarikh Tuntut</th>
<th>Pembiayaan</th>
<th>Harga Jual</th>
<th>Jum Tuntut/Bayar</th>
<th>Keuntungan</th>
<th>Caj Lelong</th>
<th>Status Tuntutan</th>
<th>Cetak</th>
</tr>
</thead>
</table>
<div class="text-center">
<button class="btn btn-primary" onclick="ubahfunc(this)" id="button-edit-gadaian">Ubah</button>
<button class="btn btn-primary" onclick="hapusfunc()">Hapus</button>
<button class="btn btn-primary" onclick="histfunc()">Rekod Pembiayaan</button>
<button class="btn btn-primary" onclick="removeansuran(this)" id="button-remove-ansuran">Hapus Ansuran</button>
</div>
</div>
{{-- Sudah Tebus --}}
<table id="dahtebusTable" class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Penyelesaian Pembiayaan</th>
<th>Baki Pembiayaan</th>
<th>Margin</th>
<th>Tempoh</th>
</tr>
</thead>
</table>
<table id="lelongTable" class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Bil</th>
<th>No Rujukan</th>
<th>Tarikh Lelong</th>
<th>Tarikh Tuntut</th>
<th>Pembiayaan</th>
<th>Harga Jual</th>
<th>Jum Tuntut/Bayar</th>
<th>Keuntungan</th>
<th>Caj Lelong</th>
<th>Status Tuntutan</th>
<th>Cetak</th>
</tr>
</thead>
</table>
<div class="text-center">
<button class="btn btn-primary" onclick="ubahfunc(this)" id="button-edit-gadaian">Ubah</button>
<button class="btn btn-primary" onclick="hapusfunc()">Hapus</button>
<button class="btn btn-primary" onclick="histfunc()">Rekod Pembiayaan</button>
<button class="btn btn-primary" onclick="removeansuran(this)" id="button-remove-ansuran">Hapus Ansuran</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="customer_detail" tabindex="-1" aria-labelledby="customer_detailLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="customer_detailLabel">Maklumat Pelanggan</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="kemaskiniform">
<div class='row form-group'>
<div class='col-md-6'>
<div class='form-group row col-md-12'>
<div class='col-md-5'>
Nama
<!-- Modal -->
<div class="modal fade" id="customer_detail" tabindex="-1" aria-labelledby="customer_detailLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="customer_detailLabel">Maklumat Pelanggan</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="kemaskiniform">
<div class='row form-group'>
<div class='col-md-6'>
<div class='form-group row col-md-12'>
<div class='col-md-5'>
Nama
</div>
<div class='col-md-7'>
<input type="text" readonly name='nama' id='nama' value="{{ $customer_info['nama'] }}" class='form-control'>
</div>
</div>
<div class='col-md-7'>
<input type="text" readonly name='nama' id='nama' value="{{ $customer_info['nama'] }}" class='form-control'>
<div class='form-group row col-md-12'>
<div class='col-md-5'>
No KP
</div>
<div class='col-md-7'>
<input type="text" readonly name='icno' id='icno' value="{{ $customer_info['kpbaru'] ? $customer_info['kpbaru'] : $customer_info['kplama'] }}" class='form-control'>
</div>
</div>
</div>
<div class='form-group row col-md-12'>
<div class='col-md-5'>
No KP
<div class='form-group row col-md-12'>
<div class='col-md-5'>
No Pelanggan
</div>
<div class='col-md-7'>
<input type="text" readonly name='nopelanggan' id='nopelanggan' value="{{ $customer_info['nopelanggan'] }}" class='form-control'>
</div>
</div>
<div class='col-md-7'>
<input type="text" readonly name='icno' id='icno' value="{{ $customer_info['kpbaru'] ? $customer_info['kpbaru'] : $customer_info['kplama'] }}" class='form-control'>
<div class='form-group row col-md-12'>
<div class='col-md-5'>
No Telefon 1
</div>
<div class='col-md-7'>
<input type="text" readonly name='' id='telefon' value="{{ $customer_info['telefon'] ? $customer_info['telefon'] : '' }}" class='form-control'>
<span id="errortelefon" style="color:red;"></span>
</div>
</div>
</div>
<div class='form-group row col-md-12'>
<div class='col-md-5'>
No Pelanggan
<div class='form-group row col-md-12'>
<div class='col-md-5'>
No Telefon 2
</div>
<div class='col-md-7'>
<input type="text" readonly name='telefon2' id='telefon2' value="{{ $customer_info['telefon2'] ? $customer_info['telefon2'] : '' }}" class='form-control'>
<span id="errortelefon2" style="color:red;"></span>
</div>
</div>
<div class='col-md-7'>
<input type="text" readonly name='nopelanggan' id='nopelanggan' value="{{ $customer_info['nopelanggan'] }}" class='form-control'>
</div>
</div>
<div class='form-group row col-md-12'>
<div class='col-md-5'>
No Telefon 1
</div>
<div class='col-md-7'>
<input type="text" readonly name='' id='telefon' value="{{ $customer_info['telefon'] ? $customer_info['telefon'] : '' }}" class='form-control'>
<span id="errortelefon" style="color:red;"></span>
</div>
</div>
<div class='form-group row col-md-12'>
<div class='col-md-5'>
No Telefon 2
</div>
<div class='col-md-7'>
<input type="text" readonly name='telefon2' id='telefon2' value="{{ $customer_info['telefon2'] ? $customer_info['telefon2'] : '' }}" class='form-control'>
<span id="errortelefon2" style="color:red;"></span>
</div>
</div>
<div class='form-group row col-md-12'>
<div class='col-md-5'>
Bank
</div>
<div class='col-md-7'>
@php
$bank = Http::withOptions(['verify' => config('app.api_verify')])
->get($api_url . '/api/bank')
->json();
@endphp
<select class="form-control" name="kodbank" data-placeholder="Pilih Bank" id="kodbank" disabled="true">
<option value="-" selected disabled>-</option>
@foreach ($bank as $banks)
<div class='form-group row col-md-12'>
<div class='col-md-5'>
Bank
</div>
<div class='col-md-7'>
@php
$bank = Http::withOptions(['verify' => config('app.api_verify')])
->get($api_url . '/api/bank')
->json();
@endphp
<select class="form-control" name="kodbank" data-placeholder="Pilih Bank" id="kodbank" disabled="true">
<option value="-" selected disabled>-</option>
@foreach ($bank as $banks)
<option value="{{ $banks['abbreviation'] }}"
{{ $banks['abbreviation'] == $customer_info['kodbank'] ? 'selected' : '' }}>
{{ $banks['name'] }}</option>
@@ -971,7 +972,7 @@
var channel = pusher.subscribe(
'notice-kelulusan');
channel.bind('my-kelulusan', function(
data) {
data) {
if (data.norujukan ==
@@ -995,7 +996,7 @@
},
success: function(
data
) {
) {
location
.reload();
@@ -1004,17 +1005,18 @@
xhr,
status,
error
) {
) {
var err =
eval(
"(" +
xhr
.responseText +
")"
);
);
alert
(xhr
.responseText);
.responseText
);
}
});
});
@@ -1242,7 +1244,7 @@
'RM ' + formatter.format(gadai_detail['bakipjm']),
(((Number(gadai_detail['pinjaman']) / Number(gadai_detail[
'nilaimarhun'])) * 100).toFixed(2)).toLocaleString(
"en-GB") + '%',
"en-GB") + '%',
gadai_detail['tempoh']
]).draw();
} else if (jenistebus == "lelong") {
@@ -1273,7 +1275,7 @@
'<a href="#" onclick="checktuntutbaki(this)" data-norujukan=' +
gadai_detail['norujukan'] + ' data-tarikhtuntut=' +
gadai_detail['trkhtuntut'] + '>' + gadai_detail[
'norujukan'] + '</a>',
'norujukan'] + '</a>',
gadai_detail['t_lelong'],
gadai_detail['trkhtuntut'],
'RM ' + formatter.format(gadai_detail['pinjaman']),
@@ -1290,7 +1292,7 @@
'<a href="#" onclick="checktuntutbaki(this)" data-norujukan=' +
gadai_detail['norujukan'] + ' data-tarikhtuntut=' +
gadai_detail['trkhtuntut'] + '>' + gadai_detail[
'norujukan'] + '</a>',
'norujukan'] + '</a>',
gadai_detail['t_lelong'],
gadai_detail['trkhtuntut'],
'RM ' + formatter.format(gadai_detail['pinjaman']),
@@ -2164,10 +2166,10 @@
cancelButtonText: 'Salah',
reverseButtons: true
}).then((
result) => {
result) => {
if (result
.isConfirmed
) {
) {
$.ajax({
method: 'put',
@@ -2181,11 +2183,11 @@
},
success: function(
data
) {
) {
if (data ===
1
) {
) {
Swal.fire({
icon: 'success',
title: 'Berjaya!',
@@ -2220,7 +2222,7 @@
Swal
.DismissReason
.cancel
) {
) {
PengesahanAkhirWakil
.fire(
'Batal',
@@ -2242,12 +2244,12 @@
daftarwakilfunction
(amaun,
norujukan
);
);
});
}
},
error: function(xhr, status,
error) {
error) {
var err = eval("(" + xhr
.responseText + ")");
alert(xhr.responseText);
@@ -2479,7 +2481,7 @@
success: function(data) {},
error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText +
")");
")");
alert(xhr.responseText);
}
});
@@ -2527,7 +2529,7 @@
location
.reload();
}
);
);
} else {
swalWithBootstrapButtons
.fire(
@@ -2540,7 +2542,7 @@
location
.reload();
}
);
);
}
@@ -2554,10 +2556,10 @@
xhr
.responseText +
")"
);
);
alert(xhr
.responseText
);
);
}
});
return true;
@@ -2716,10 +2718,10 @@
'Maklumat Pembiayaan telah dihapuskan.',
'success'
).then(
function() {
location
.reload();
});
function() {
location
.reload();
});
}
})
},
+18 -12
View File
@@ -29,6 +29,7 @@
<div class="form-group row col-12">
<input type="hidden" name="kodcaw" id="kodcaw" value="{{$cawangan_info['kodcaw']}}">
<input type="hidden" name="nokp" id="nokp" value="{{ $customer_info['kpbaru'] }}">
<input type="hidden" name="tag_anggota" id="tag_anggota" value="{{ $customer_info['tag_anggota'] ?? 0 }}">
</div>
<div class="col-12 mb-2">
@@ -630,18 +631,23 @@
$.ajax({
method:'GET',
url: api_url + '/api/kadarujrah',
async:false,
data:{
'nokp': $('#nokp').val(),
'nilaimarhun' : total_nilai_marhun,
'kodcaw' : kodcaw_ujrah
},
success:function(data){
kadarupah = data;
}
});
method:'GET',
url: api_url + '/api/kadarujrah',
async:false,
data:{
'nokp': $('#nokp').val(),
'nilaimarhun' : total_nilai_marhun,
'kodcaw' : kodcaw_ujrah
},
success:function(data){
kadarupah = data;
// Jika anggota (tag_anggota = 1), kadar ujrah dipaksa 0.00
if(Number($('#tag_anggota').val()) === 1){
kadarupah = 0;
}
}
});
$('#total_nilai_marhun').val(formatter.format(total_nilai_marhun));
$('#marhun_detail').val(marhun_details);
+81 -37
View File
@@ -655,7 +655,7 @@
</table>
<table class="main-table text-center" style="border-top: none !important">
<tr>
<th colspan="5">JUMLAH KEUNTUNGAN DAN LAIN-LAIN CAJ BERDASARKAN TEMPOH PEMBIAYAAN</th>
<th colspan="5">JUMLAH KEUNTUNGAN BERDASARKAN TEMPOH PEMBIAYAAN</th>
</tr>
<tr>
<th>TEMPOH PEMBIAYAAN</th>
@@ -670,13 +670,13 @@
<td>{{ $formatted_t_matang_1 }}</td>
</tr>
<tr>
<th class="text-left">JUMLAH KEUNTUNGAN (1%) DAN LAIN-LAIN CAJ YANG PERLU DIBAYAR</th>
<th class="text-left">JUMLAH KEUNTUNGAN YANG PERLU DIBAYAR</th>
<td style="font-size:12px"><b>RM{{ number_format($gadai_detail['bakiupah'] / 6, 2) }}</b></td>
<td style="font-size:12px"><b>RM{{ number_format($gadai_detail['bakiupah'], 2) }}</b></td>
<td>RM{{ number_format($gadai_detail['bakiupah'], 2) }}</td>
</tr>
<tr>
<th class="text-left">JUMLAH KEUNTUNGAN (1%) DAN LAIN-LAIN CAJ TERKUMPUL<br> SEPANJANG TEMPOH
<th class="text-left">JUMLAH KEUNTUNGAN TERKUMPUL<br> SEPANJANG TEMPOH
PEMBIAYAAN
</th>
<td>-</td>
@@ -717,7 +717,7 @@
<tr>
<td colspan="4">
Pelanggan bersetuju dan dengan ini menggadaikan Marhun sebagai cagaran kepada
Jumlah Pembiayaan termasuk Jumlah Keuntungan dan Lain-Lain Caj Terkumpul
Jumlah Pembiayaan termasuk Jumlah Keuntungan Terkumpul
mengikut
syarat-syarat pembiayaan dalam SAG ini. KoPKB dengan ini menerima gadaian Marhun
tersebut.
@@ -731,14 +731,12 @@
<td style="vertical-align: top">
<table class="akad-table">
<tr>
<td colspan="4"><b><u>AKAD (SIMPAN MARHUN)</u></b></td>
<td colspan="4"><b><u>KADAR KEUNTUNGAN BULANAN</u></b></td>
</tr>
<tr>
<td colspan="4">
Pelanggan dengan ini bersetuju marhun disimpan oleh KoPKB dan bersetuju membayar
lain-lain caj
sebagaimana jadual dibawah bagi setiap
RM100.00 Jumlah Marhun Keseluruhan:
Kadar keuntungan Pembiayaan Ar-Rahn Tawarruq adalah berdasarkan jumlah
pembiayaan seperti berikut :
</td>
</tr>
</table>
@@ -746,35 +744,35 @@
<table class="main-table text-center"
style="font-size: 9px; width: 100%; margin-top: 5px;">
<tr>
<th>KADAR LAIN-LAIN CAJ / RM100</th>
<th>KADAR KEUNTUNGAN SEBULAN (%)</th>
</tr>
<tr>
<td>RM{{ $kadar_ujrah[0]['kadarujrah'] }}/sebulan</td>
<td>1.00</td>
</tr>
</table>
@else
<table class="main-table text-center"
style="font-size: 9px; width: 100%; margin-top: 5px;">
<tr>
<th>NILAI MARHUN KESELURUHAN</th>
<th>JUMLAH PEMBIAYAAN</th>
<th></th>
<th>KADAR LAIN-LAIN CAJ / RM100</th>
<th>KADAR KEUNTUNGAN SEBULAN (%)</th>
</tr>
<tr>
<td>
< RM400.99</td>
<td>-</td>
<td>RM{{ $kadar_ujrah[0]['kadarujrah'] }}/sebulan</td>
<td>{{ $kadar_ujrah[0]['kadarupdah'] }}</td>
</tr>
<tr>
<td>RM401.00 - RM2000.99</td>
<td>-</td>
<td>RM{{ $kadar_ujrah[1]['kadarujrah'] }}/sebulan</td>
<td>{{ $kadar_ujrah[1]['kadarupdah'] }}</td>
</tr>
<tr>
<td>> RM2001.00</td>
<td>-</td>
<td>RM{{ $kadar_ujrah[2]['kadarujrah'] }}/sebulan</td>
<td>{{ $kadar_ujrah[2]['kadarupdah'] }}</td>
</tr>
</table>
@endif
@@ -829,15 +827,15 @@
<tr>
<td></td>
<td>e.</td>
<td colspan="2">Membayar Jumlah Pembiayaan termasuk Jumlah Keuntungan dan
Lain-Lain Caj Terkumpul yang diberi mengikut dalam tempoh seperti di SAG ini;
<td colspan="2">Membayar Jumlah Pembiayaan termasuk Jumlah Keuntungan yang diberi
mengikut dalam tempoh seperti di SAG ini;
</td>
</tr>
<tr>
<td></td>
<td>f.</td>
<td colspan="2">Tertakluk kepada pembayaran penuh Jumlah Pembiayaan termasuk
Jumlah Keuntungan dan Lain-Lain Caj Terkumpul, Pelanggan perlu hadir sendiri
Jumlah Keuntungan Terkumpul, Pelanggan perlu hadir sendiri
menyelesaikan Pembiayaan;</td>
</tr>
<tr>
@@ -1066,8 +1064,7 @@
<td colspan="1"></td>
<td colspan="1">o.</td>
<td colspan="2">KoPKB berhak menuntut Jumlah Pembiayaan termasuk Jumlah Keuntungan
dan
Lain-Lain Caj Terkumpul setelah tamat tempoh yang dinyatakan pada notis berkaitan;
setelah tamat tempoh yang dinyatakan pada notis berkaitan;
</td>
</tr>
<tr>
@@ -1212,8 +1209,7 @@
<td colspan="1">a.</td>
<td colspan="2">Marhun akan dilelong atau dijual. KoPKB akan membatalkan
lelongan Marhun sekiranya Pelanggan membayar tunggakan Jumlah Pembiayaan
termasuk Jumlah Keuntungan dan
Lain-Lain Caj
termasuk Jumlah Keuntungan
sepenuhnya tiga (3) hari sebelum tarikh lelongan;</td>
</tr>
<tr>
@@ -1233,7 +1229,7 @@
<td colspan="1">c.</td>
<td colspan="2">Sebarang lebihan hasil lelongan atau jualan (jika ada) setelah
ditolak
Jumlah Pembiayaan termasuk Jumlah Keuntungan dan Lain-Lain Caj Terkumpul
Jumlah Pembiayaan termasuk Jumlah Keuntungan Terkumpul
yang tertunggak dan kos-kos berkaitan akan
dikembalikan
kepada Pelanggan dan;</td>
@@ -1264,7 +1260,7 @@
<td>=</td>
<td><b>BAKI TEMPOH PEMBIAYAAN <br></td>
<td>X</td>
<td><b>JUMLAH KEUNTUNGAN 1% DAN LAIN-LAIN CAJ YANG PERLU DIBAYAR</b></td>
<td><b>JUMLAH KEUNTUNGAN YANG PERLU DIBAYAR</b></td>
</tr>
</table>
<br>
@@ -1280,7 +1276,7 @@
<td colspan="1"></td>
<td colspan="1">a.</td>
<td colspan="2">Pelanggan gagal dan/ingkar menjelaskan Jumlah Pembiayaan,
Jumlah Keuntungan dan Lain-Lain Caj Terkumpul pada tarikh yang ditetapkan;
Jumlah Keuntungan Terkumpul pada tarikh yang ditetapkan;
</td>
</tr>
<tr>
@@ -1306,6 +1302,45 @@
<tr>
<td colspan="1"></td>
<td colspan="1"><b>6.</b></td>
<td colspan="2"><b>Pelanggan dengan ini bersetuju, memberi kuasa dan melantik
Ar-Rahn sebagai wakil (wakil di bawah prinsip Wakalah) untuk menguruskan baki
hasil lelongan yang menjadi hak Pelanggan,
sekiranya ada, yang bernilai RM10.00 (Ringgit Malaysia: Sepuluh) atau kurang,
dan tidak dituntut oleh Pelanggan dalam tempoh tuntutan yang ditetapkan oleh
Ar-Rahn setelah usaha munasabah telah diambil untuk memaklumkan kepada
Pelanggan.</b></td>
</tr>
<tr>
<td colspan="1"></td>
<td colspan="1"><b>7.</b></td>
<td colspan="2">
<b>
Pelanggan selanjutnya bersetuju bahawa baki hasil lelongan tersebut boleh
disalurkan oleh Ar-Rahn, bagi pihak Pelanggan, sebagai infaq kepada mana-mana
institusi agama Islam, badan kebajikan atau institusi lain yang diluluskan
oleh Jawatankuasa Syariah dan/atau pihak berkuasa yang berkaitan, tanpa
sebarang liabiliti ke atas Ar-Rahn selepas penyaluran tersebut dibuat dengan
jumlah tidak melebihi RM10.00.
</b>
<div style="margin-top: 8px;">
<span
style="
display: inline-block;
width: 13px;
height: 13px;
border: 1px solid #000;
margin-right: 6px;
vertical-align: middle;
"></span>
<b>Tandakan (✓) jika tidak bersetuju.</b>
</div>
</td>
</tr>
<tr>
<td colspan="1"></td>
<td colspan="1"><b>8.</b></td>
<td colspan="2"><b>Sekiranya Pelanggan mempunyai sebarang pertanyaan atau
aduan, Pelanggan boleh menghubungi KoPKB sebagaimana berikut:</b></td>
</tr>
@@ -1713,6 +1748,7 @@
{{-- MARHUN DETAIL SECTION --}}
<div class="main-marhun">
<table class="main-table text-center" style="width: 75%">
<tr>
<th>BIL</th>
<th>JENIS MARHUN</th>
@@ -1846,7 +1882,7 @@
</table>
<table class="main-table text-center" style="border-top: none !important">
<tr>
<th colspan="5">JUMLAH KEUNTUNGAN DAN LAIN-LAIN CAJ BERDASARKAN TEMPOH PEMBIAYAAN</th>
<th colspan="5">JUMLAH KEUNTUNGAN BERDASARKAN TEMPOH PEMBIAYAAN</th>
</tr>
<tr>
<th>TEMPOH PEMBIAYAAN</th>
@@ -1861,19 +1897,27 @@
<td>{{ $formatted_t_matang_1 }}</td>
</tr>
<tr>
<th class="text-left">JUMLAH KEUNTUNGAN DAN LAIN-LAIN CAJ YANG PERLU DIBAYAR BULANAN</th>
<th class="text-left">JUMLAH KEUNTUNGAN YANG PERLU DIBAYAR BULANAN</th>
<td style="font-size:12px"><b>RM{{ number_format($gadai_detail['bakiupah'] / 6, 2) }}</b></td>
<td style="font-size:12px"><b>RM{{ number_format($gadai_detail['bakiupah'], 2) }}</b></td>
<td>RM {{ number_format($gadai_detail['bakiupah'], 2) }}</td>
</tr>
<tr>
<th class="text-left">JUMLAH KEUNTUNGAN DAN LAIN-LAIN CAJ TERKUMPUL <br> SEPANJANG TEMPOH
<th class="text-left">JUMLAH KEUNTUNGAN TERKUMPUL <br> SEPANJANG TEMPOH
PEMBIAYAAN</th>
<td>-</td>
<td>RM{{ number_format($gadai_detail['bakiupah'], 2) }}</td>
<td>RM{{ number_format($gadai_detail['upah12'], 2) }}</td>
</tr>
</table>
<div style="color: black; font-weight: bold; margin-top: 0px; width: 100%;">
<span>PENGURUSAN HASIL LELONGAN YANG TIDAK DITUNTUT</span>
<span>
<input type="checkbox" name="hasil_lelongan_tidak_dituntut">
</span>
</div>
{{-- SIGNATURE SECTION --}}
<table class="main-table mt-10">
<tr>
@@ -2138,8 +2182,8 @@
</td>
</tr>
<tr>
<td style="width: 50px;">Nama:</td>
<td>
<td style="width: 50px;">Nama:</td>
<td>
{{ $customer_detail['nama'] }}
</td>
</tr>
@@ -2171,12 +2215,12 @@
</tr>
<tr>
<td style="width: 50px;">Nama:</td>
<td>
@if ($gadai_detail['penilai'] == '')
{{ $auth_username }}
@else
{{ $gadai_detail['penilai'] }}
@endif
<td>
@if ($gadai_detail['penilai'] == '')
{{ $auth_username }}
@else
{{ $gadai_detail['penilai'] }}
@endif
</td>
</tr>
<tr>
+4
View File
@@ -15,6 +15,10 @@ use Illuminate\Support\Facades\Storage;
|
*/
Route::get('/health', function () {
return response()->json(['status' => 'ok']);
});
Route::get('/',['as'=>'login','uses'=>'HomeController@index']);
Route::get('/testtry',function(ImbangdugaServices $imbangduga){