1 Commits

Author SHA1 Message Date
R
552a2367f5 [WIP] Cashless 2023-01-11 14:29:02 +07:00
14 changed files with 1772 additions and 1037 deletions

View File

@@ -46,4 +46,15 @@ class ClaimController extends Controller
return Helper::responseJson($claim);
}
public function updateClaimDiagnosis(Request $request)
{
$request->validate([
'claim_code' => 'required',
'icd_codes' => 'required'
]);
// dd($request->toArray());
return $request->toArray();
}
}

View File

@@ -53,39 +53,43 @@ class MembershipController extends Controller
$limits = ClaimService::showMemberBenefitLimit($member, $benefitCode);
$limits['postponed_claims'] = $member->postponedClaims;
$limits['postponed_claims_payment_url'] = "http://google.com";
$limits['postponed_claims_payment_url'] = route('postpone-pay', $member->member_id);
$limits['postponed_claims_unpaid_total'] = $member->postponedClaims->sum('total_claim');
$corporateService = $member->currentCorporate
->corporateServices()
->active()
->where('service_code', 'OP')
->with([
'configs',
'specialities' => function ($speciality) use ($request) {
$speciality->where('code', $request->speciality_code)
->wherePivot('active', 1);
}])
->first();
$configs = $corporateService->configs->mapWithKeys(function ($config) {
return [$config->name => $config];
});
$coverage = [
'benefit' => false,
'admin_fee' => false,
'medicine_benefit' => true, // TODO Make this into setting ?
'medicine_delivery_fee' => false
];
$coverage['medicine_delivery_fee'] = (($configs['delivery_fee']['value'] ?? 1) == 1);
$coverage['gp_benefit'] = (($configs['gp_internal_doctor_online']['value'] ?? 1) == 1);
$coverage['gp_admin_fee'] = (($configs['general_practitioner_fee']['value'] ?? 1) == 1);
$coverage['sp_benefit'] = (($configs['sp_internal_doctor_online']['value'] ?? 1) == 1);
$coverage['sp_admin_fee'] = (($configs['specialist_practitioner_fee']['value'] ?? 1) == 1);
if ($request->has('speciality_code') && !empty($request->speciality_code)) {
$corporateService = $member->currentCorporate
->corporateServices()
->active()
->where('service_code', 'OP')
->with([
'specialities' => function ($speciality) use ($request) {
$speciality->where('code', $request->speciality_code)
->wherePivot('active', 1);
}])
->first();
// $rules = $corporateServiceConfigs->
// dd($corporateServiceConfigs->toArray());
if (empty($corporateService)) {
$limit['coverage'] = [
'benefit' => false,
'admin_fee' => false,
'delivery_fee' => false
];
return Helper::responseJson(data: $limits);
}
if (empty($corporateService->specialities)) {
$limit['coverage'] = [
'benefit' => false,
'admin_fee' => false,
'delivery_fee' => false
];
if (empty($corporateService) || empty($corporateService->specialities)) {
$coverage['benefit'] = false;
$coverage['admin_fee'] = false;
$limits['coverage'] = $coverage;
return Helper::responseJson(data: $limits);
}
@@ -94,8 +98,6 @@ class MembershipController extends Controller
// Load the Relation Data after speciality check is supported
$corporateService->load([
'configs',
// 'configs.exclusions.rules',
'corporateServiceSpecialities' => function ($corporateServiceSpeciality) use ($currentSpeciality) {
$corporateServiceSpeciality->where('speciality_id', $currentSpeciality->id);
},
@@ -105,10 +107,6 @@ class MembershipController extends Controller
'corporateServiceSpecialities.exclusions.rules'
]);
$configs = $corporateService->configs->mapWithKeys(function ($config) {
return [$config->name => $config];
});
$serviceSpeciality = $corporateService->corporateServiceSpecialities->first() ?? null;
$serviceSpecialityRules = $serviceSpeciality->exclusions->first()->rules ?? collect([]);
$serviceSpecialityRules = $serviceSpecialityRules->mapWithKeys(function ($rule) {
@@ -116,16 +114,6 @@ class MembershipController extends Controller
});
$gpSpecialityName = config('aso.general_practitioner_speciality_name', 'Umum');
// dd($serviceSpecialityRules->toArray());
$coverage = [
'benefit' => false,
'admin_fee' => false,
'delivery_fee' => false
];
// dd($configs->toArray());
// dd($gpSpecialityName, $currentSpeciality->name);
if ($gpSpecialityName == $currentSpeciality->name) {
// To General Practitioner
@@ -202,17 +190,9 @@ class MembershipController extends Controller
$coverage['benefit'] = true;
}
$limits['coverage'] = $coverage;
} else {
$limits['coverage'] = [
'benefit' => true,
'admin_fee' => true,
'delivery_fee' => true
];
}
$limits['coverage'] = $coverage;
return Helper::responseJson(data: $limits);
}

View File

@@ -0,0 +1,55 @@
<?php
namespace App\Http\Controllers\Api\OLDLMS;
use App\Http\Controllers\Controller;
use App\Models\Member;
use App\Services\Duitku;
use Illuminate\Http\Request;
use Str;
class PaymentController extends Controller
{
public function postponePay($memberId)
{
$member = Member::where('member_id', $memberId)->with('postponedClaims')->firstOrFail();
$totalBill = $member->postponedClaims->sum('total_claim');
$config_duitku = [
'merchant_code' => env('DUITKU_MERCHANT_CODE'),
'merchant_key' => env('DUITKU_MERCHANT_KEY'),
];
$paymentService = new Duitku($config_duitku);
$invoice = (object) [
'invoice_number' => 'INV'.Str::random(5, 5),
];
$user = (object) [
'email' => $member->email,
'phone' => $member->phone,
'name' => $member->name,
'last_name' => $member->last_name ?? '',
'address' => collect([
'line' => 'Alamat',
'city' => (object) [
'name' => 'Tangerang Selatan'
]
]),
'postal_code' => '124123',
];
$paymentCreate = (object) [
'transaction_id' => Str::random(10, 10)
];
$paymentMethod = (object) [
'code' => 'BC',
'timeout' => 60
];
$paymentService->applyInvoice($user, $invoice, $paymentCreate, $totalBill, $paymentMethod);
$duitkuPayment = $paymentService->createPayment();
return redirect($duitkuPayment->paymentUrl);
}
}

View File

@@ -179,7 +179,7 @@ class Plan extends Model
public function benefits()
{
return $this->belongsToMany(Benefit::class, 'corporate_benefits', 'plan_id', 'id')
return $this->belongsToMany(Benefit::class, 'corporate_benefits', 'plan_id', 'benefit_id')
->withTimestamps()
->withPivot([
// TODO corporate_benefits pivot

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class DuitkuServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
require_once app_path() . '/Services/Duitku.php';
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
//
}
}

View File

@@ -112,6 +112,7 @@ class ClaimService{
// $policy = $member->currentPolicy;
// $corporate = $member->currentCorporate;
$benefit = $member->currentPlan->benefits()->where('code', $benefit_code)->first();
// dd($member->currentPlan->benefits->toArray());
$corporateBenefit = $member->currentPlan->corporateBenefits()->where('benefit_id', $benefit->id)->first();
// dd($benefit->toArray());

228
app/Services/Duitku.php Normal file
View File

@@ -0,0 +1,228 @@
<?php
namespace App\Services;
// use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Duitku\Config;
use Exception;
class Duitku
{
public function __construct($config_duitku)
{
$merchantKey = $config_duitku['merchant_key'];
$merchantCode = $config_duitku['merchant_code'];
$this->duitkuConfig = new Config($merchantKey, $merchantCode);
$this->duitkuConfig->setSandboxMode(env('DUITKU_SANDBOX', true));
// $duitkuConfig = new \Duitku\Config("3b4264fb0118bab008448a67e83f6cbe", "DS12798");
// // false for production mode
// // true for sandbox mode
// $duitkuConfig->setSandboxMode(true);
}
public function applyInvoice($patient, $invoices, $paymentCreate, $total_price, $paymentMethods)
{
$paymentMethod = $paymentMethods->code;
$paymentAmount = $total_price; // Amount
$email = $patient->email ?? ''; //"customer@gmail.com"; // your customer email
$phoneNumber = $patient->phone ?? ''; //"081234567890"; // your customer phone number (optional)
$productDetails = $invoices->invoice_number;
$merchantOrderId = $paymentCreate->transaction_id; // from merchant, unique
// dd($merchantOrderId);
$additionalParam = ''; // optional
$merchantUserInfo = ''; // optional
$customerVaName = $patient->name ?? ''; // display name on bank confirmation display
$callbackUrl = env('DUITKU_PAYMENT_CALLBACK_URL'); // url for callback
$returnUrl = 'https://dev-superapp.primaya.id';
$expiryPeriod = $paymentMethods->timeout; // set the expired time in minutes
// Customer Detail
$firstName = $patient->name ?? '';
// dd($firstName);
$lastName = $patient->last_name ?? '';
// Address
$alamat = $patient->address->first()->line ?? '';
// dd($alamat);
$city = $patient->address->first()->city->name ?? '';
// dd($city);
$postalCode = $patient->postal_code ?? '';
$countryCode = "ID";
$address = array(
'firstName' => $firstName,
'lastName' => $lastName,
'address' => $alamat,
'city' => $city,
'postalCode' => $postalCode,
'phone' => $phoneNumber,
'countryCode' => $countryCode
);
$customerDetail = array(
'firstName' => $firstName,
'lastName' => $lastName,
'email' => $email,
'phoneNumber' => $phoneNumber,
'billingAddress' => $address,
// 'shippingAddress' => $address
);
// $itemDetails = [];
// foreach ($invoices->items as $item) {
// $itemDetails[] = [
// 'name' => $invoices->invoice_number,
// 'price' => (int) $item->price_net,
// 'quantity' => 1,
// ];
// }
$itemDetails = array(
array(
'name' => $invoices->invoice_number,
'price' => (int) $total_price,
'quantity' => 1,
)
);
$params = array(
'paymentMethod' => $paymentMethod,
'paymentAmount' => (int) $paymentAmount,
'merchantOrderId' => $merchantOrderId,
'productDetails' => $productDetails,
'additionalParam' => $additionalParam,
'merchantUserInfo' => $merchantUserInfo,
'customerVaName' => $customerVaName,
'email' => $email,
'phoneNumber' => $phoneNumber,
'itemDetails' => $itemDetails,
'customerDetail' => $customerDetail,
'callbackUrl' => $callbackUrl,
'returnUrl' => $returnUrl,
'expiryPeriod' => $expiryPeriod
);
$this->transaction_details = $params;
return $this;
}
public function createPayment()
{
try {
// createInvoice Request
$responseDuitku = \Duitku\Api::createInvoice($this->transaction_details, $this->duitkuConfig);
return json_decode($responseDuitku);
} catch (\Exception $e) {
throw $e;
}
}
public function checkTransaction($paymentCreate)
{
try {
// $merchantOrderId = "96ce0853-35e2-4809-97bf-47463d236773";
$merchantOrderId = $paymentCreate->first()->transaction_id;
// dd($merchantOrderId);
$transactionList = \Duitku\Api::transactionStatus($merchantOrderId, $this->duitkuConfig);
header('Content-Type: application/json');
$transaction = json_decode($transactionList);
// var_dump($transactionList);
if ($transaction->statusCode == "00") {
return response()->json([
'data' => $transaction
]);
} else if ($transaction->statusCode == "01") {
return response()->json([
'data' => $transaction
]);
} else {
return response()->json([
'data' => $transaction
]);
// Action Failed Or Expired
}
} catch (Exception $e) {
echo $e->getMessage();
}
}
public static function getSignature($merchantCode, $amount, $merchantOrderId, $apiKey)
{
$params = $merchantCode . $amount . $merchantOrderId . $apiKey;
// DS12798
// 110.000,00
// 96ce58d2-0aec-4a1a-b0b1-c96c0e2ff2d8
// 3b4264fb0118bab008448a67e83f6cbe
return md5($params);
}
public function validateCallback($config_duitku, $merchantCode, $amount, $merchantOrderId, $signature)
{
$apiKey = $config_duitku['merchant_key'];
if (!empty($merchantCode) && !empty($amount) && !empty($merchantOrderId) && !empty($signature)) {
$this->params = $merchantCode . $amount . $merchantOrderId . $apiKey;
$calcSignature = $this->getSignature($merchantCode, $amount, $merchantOrderId, $apiKey);
if ($signature == $calcSignature) {
return true;
} else {
throw new \Exception('Bad Signature');
}
} else {
throw new \Exception('Bad Parameter');
}
}
public function translatePaymentStatus($paymentStatusCode)
{
switch ($paymentStatusCode) {
case '00':
$status = 'success';
break;
default:
$status = 'failed';
break;
}
return $status;
}
public function paymentMethod()
{
try {
$paymentAmount = "10000"; //"YOUR_AMOUNT";
$paymentMethodList = \Duitku\Api::getPaymentMethod($paymentAmount, $this->duitkuConfig);
header('Content-Type: application/json');
// return
$paymentMethod = json_decode($paymentMethodList);
return response()->json($paymentMethod->paymentFee);
// echo $paymentMethodList->paymentFee;
} catch (Exception $e) {
echo $e->getMessage();
}
}
}

View File

@@ -7,6 +7,7 @@
"require": {
"php": "^8.0.2",
"box/spout": "^3.3",
"duitkupg/duitku-php": "dev-master",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^9.11",
"laravel/sanctum": "^2.15",
@@ -14,7 +15,8 @@
"laravel/tinker": "^2.7",
"maatwebsite/excel": "^3.1",
"nwidart/laravel-modules": "^9.0",
"psr/simple-cache": "^1.0"
"psr/simple-cache": "^1.0",
"pusher/pusher-php-server": "^7.2"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.7",

2363
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -193,7 +193,10 @@ return [
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\DuitkuServiceProvider::class,
App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
@@ -212,6 +215,7 @@ return [
'aliases' => Facade::defaultAliases()->merge([
// 'ExampleClass' => App\Example\ExampleClass::class,
'Duitku' => App\Services\Duitku::class,
'Excel' => Maatwebsite\Excel\Facades\Excel::class,
'LmsApi' => App\Services\LmsApi::class,
])->toArray(),

View File

@@ -36,8 +36,11 @@ return [
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html

View File

@@ -218,6 +218,12 @@ export default function List() {
({row.diagnosis?.code}) {row.diagnosis?.name}
</TableCell>
<TableCell align="left">{fCurrency(row.total_claim)}</TableCell>
{ (row.status == 'approved' && (
<TableCell align="left">Approved</TableCell>
)) }
{ (row.status == 'postponed' && (
<TableCell align="left">Postpone</TableCell>
)) }
<TableCell align="right">
<EditRoundedIcon
@@ -271,6 +277,9 @@ export default function List() {
<TableCell style={headStyle} align="left">
Total Claim
</TableCell>
<TableCell style={headStyle} align="left">
Status
</TableCell>
<TableCell style={headStyle} align="right">
Action
</TableCell>

View File

@@ -3,6 +3,7 @@
use App\Http\Controllers\Api\AuthController;
use App\Http\Controllers\Api\OLDLMS\ClaimController;
use App\Http\Controllers\Api\OLDLMS\MembershipController;
use App\Http\Controllers\Api\OLDLMS\PaymentController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
@@ -23,4 +24,5 @@ Route::middleware('linksehat.old.auth')->group(function() {
Route::post('check-coverage-limit', [MembershipController::class, 'checkLimit']);
Route::post('claim-create', [ClaimController::class, 'store']);
Route::post('claim-update-diagnosis', [ClaimController::class, 'updateClaimDiagnosis']);
});

View File

@@ -1,5 +1,6 @@
<?php
use App\Http\Controllers\Api\OLDLMS\PaymentController;
use Illuminate\Support\Facades\Route;
/*
@@ -16,3 +17,5 @@ use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::get('postpone-pay/{member_id}', [PaymentController::class, 'postponePay'])->name('postpone-pay');