Merge branch 'master' of gitlab.com:CIEFWorldwideSdnBhd/exchange into admin_Completed_Order

This commit is contained in:
lonetrinity
2018-08-14 10:29:24 +08:00
121 changed files with 4395 additions and 6587 deletions
+80
View File
@@ -0,0 +1,80 @@
APP_NAME=IZYIM
APP_ENV=production
APP_KEY=base64:Fu2YulXExzm9HJ5LgVmZUmcbRkchHkc82q02MorN5GQ=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
APP_NAME=exchange
APP_ENV=local
APP_KEY=base64:Fu2YulXExzm9HJ5LgVmZUmcbRkchHkc82q02MorN5GQ=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
JWT_SECRET=FwYZ3SPFgjpEDqAwcaSIV6eEmQiMtGWt
+18
View File
@@ -0,0 +1,18 @@
APP_ENV=phpunit
APP_DEBUG=true
APP_KEY=w7VQXeA7U31DCdh1U39lpRz0iD7i0oCI
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret
CACHE_DRIVER=array
SESSION_DRIVER=array
QUEUE_DRIVER=sync
MAIL_DRIVER=log
JWT_SECRET=FwYx3SPFxjpEDxAwcaSIV6eExQiMtGWx
+3 -2
View File
@@ -3,7 +3,7 @@
/public/storage
/public/js
/public/css
public/mix-manifest.json
/public/mix-manifest.json
/storage/*.key
/vendor/**
/.idea
@@ -19,4 +19,5 @@ yarn-error.log
.env.prod
vendor/composer/autoload_static.php
vendor/composer/autoload_classmap.php
package-lock.json
package-lock.json
composer.lock
+35
View File
@@ -0,0 +1,35 @@
#!/bin/bash
# Install dependencies only for Docker.
[[ ! -e /.dockerenv ]] && exit 0
set -xe
# Update packages and install composer and PHP dependencies.
apt-get update -yqq
apt-get install git libgd-dev libcurl4-gnutls-dev libicu-dev libmcrypt-dev libvpx-dev libjpeg-dev libpng-dev libxpm-dev zlib1g-dev libfreetype6-dev libxml2-dev libexpat1-dev libbz2-dev libgmp3-dev libldap2-dev unixodbc-dev libpq-dev libsqlite3-dev libaspell-dev libsnmp-dev libpcre3-dev libtidy-dev -yqq
# Compile PHP, include these extensions.
docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
docker-php-ext-install mbstring pdo_mysql curl json intl gd xml zip bz2 opcache
# Install Composer and project dependencies.
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
composer install
# Copy over testing configuration.
cp .env.testing .env
# Install xdebug
#pecl install xdebug && docker-php-ext-enable xdebug
# Generate an application key. Re-cache.
php artisan key:generate
php artisan jwt:secret
php artisan config:cache
php artisan config:clear
# php artisan optimize // remove after laravel 5.6
# Run database migrations with seeder
php artisan migrate:refresh --seed
+34
View File
@@ -0,0 +1,34 @@
before_script:
- bash .gitlab-ci.sh
stages:
- testing
- staging
variables:
MYSQL_DATABASE: default
MYSQL_USER: default
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: root
unitTesting:
stage: testing
image: php:7.2.6
services:
- mysql:5.7
script:
- vendor/bin/phpunit --coverage-text --colors=never
staging:
stage: staging
before_script:
- mkdir -p ~/.ssh
- echo -e "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
- chmod 400 ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- ssh izyim@40.76.84.105 "cd exchange && git pull origin master && sudo docker-compose -f docker-prod.yml up -d"
environment:
name: staging
url: https://exchange-staging.izyim.com/
when: manual
+26 -9
View File
@@ -1,21 +1,38 @@
# Changelog
## 1.0.2-alpha - 2018-08-13
- Added completed booking tab feature
- Removed login remember me checkbox
- Updated blue report with bank name and bank branch
- Fixed marking bug on mobile version
- Fixed step 2 bug
## 4.1.0 - 2018-03-14
## 1.0.1-alpha - 2018-08-09
- Fixed X2 milestone, now completed at step 5
- Fixed X2 no billing charge
- Fixed forgot password bug
- Updated customer registration marking with auto capital feature
- Updated admin marking setting with auto capital feature
- Added green report info for every page after supplier booking page
## 1.0.0-alpha - 2018-08-02
- Release 1.0.0
## 4.1.0-dev - 2018-03-14
- Upgrade to Laravel 5.6
- Update npm dependencies
- Enabled Mix [esModule](https://github.com/JeffreyWay/laravel-mix/pull/1526#issuecomment-373044182) by default
- Lint with eslint-plugin-vue and eslint-config-standard
## 4.0.0 - 2018-01-23
## 4.0.0-dev - 2018-01-23
- Brought back the `layout` property in pages that was removed in 3.0. By default it's set to `default` (`~/layouts/default.vue`).
## 3.0.1 - 2018-01-22
## 3.0.1-dev - 2018-01-22
- Removed middleware from routes, since they don't work when you press the back button. Now you have to use the `middleware` property in pages.
## 3.0.0 - 2018-01-22
## 3.0.0-dev - 2018-01-22
- Removed `layout` property from pages in favor of explicit layout components
- Improved middleware system, you can either define it on a route or directly on a component
@@ -23,23 +40,23 @@
- Change jwt token ttl to one day
- Fixed hot module replacement
## 2.2.1 - 2018-01-19
## 2.2.1-dev - 2018-01-19
- Upgrade to Bootstrap 4
## 2.2.0 - 2018-01-16
## 2.2.0-dev - 2018-01-16
- Added dynamic import for pages
- Added locale with dynamic import
- Import shakable fontawesome module
## 2.1.0 - 2018-01-10
## 2.1.0-dev - 2018-01-10
- Simplifyd password reset
- Upgrade to Bootstrap 4 beta3
- Added oauth with popup window
## 2.0.0 - 2017-12-19
## 2.0.0-dev - 2017-12-19
- Added support for Socialite
- Added dropdown to select the locale
@@ -52,7 +69,7 @@
- Namespaced store modules
- Published project to Packagist
## 1.0.0 - 2017-09-02
## 1.0.0-dev - 2017-09-02
- Upgrade to Laravel 5.5.
- Upgrade to Bootstrap 4 beta1.
+11 -1
View File
@@ -1,3 +1,11 @@
# Build frontend assets
# FROM node as frontend
# WORKDIR /app
# ADD . /app
# RUN npm install
# RUN npm run production
# Build backend
FROM php:7.1.3
RUN apt-get update -y && apt-get install -y openssl zip unzip git zlib1g-dev netcat mysql-client libgd-dev libfreetype6-dev libjpeg62-turbo-dev libpng12-dev
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
@@ -7,11 +15,13 @@ WORKDIR /app
ADD . /app
RUN chown -R www-data:www-data /app
RUN chmod 755 /app/storage
RUN chmod 777 -R /app/bootstrap/cache
RUN composer install
RUN php artisan clear-compiled
COPY wait.sh /usr/local/bin/wait.sh
RUN chmod +x /usr/local/bin/wait.sh
CMD /usr/local/bin/wait.sh && composer update --no-scripts && composer dumpautoload && php artisan storage:link && php artisan migrate && php artisan serve --host=0.0.0.0 --port=8000
CMD /usr/local/bin/wait.sh && composer update --no-scripts && composer dumpautoload && php artisan migrate && php artisan serve --host=0.0.0.0 --port=8000
EXPOSE 8000
@@ -26,9 +26,16 @@ class ForgotPasswordController extends Controller
* @param string $response
* @return \Illuminate\Http\RedirectResponse
*/
protected function sendResetLinkEmail($response)
protected function sendResetLink(Request $request)
{
return ['status' => trans($response)];
if($request->input('email')) {
$this->sendResetLinkEmail($request);
}
return response()->json([
'error' => false,
'status' => 'We have sent reset password link to '. $request->input('email')
]);
}
/**
@@ -8,6 +8,8 @@ use App\Http\Controllers\Controller;
use App\Exceptions\EmailTakenException;
use Laravel\Socialite\Facades\Socialite;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
class OAuthController extends Controller
{
@@ -46,7 +46,6 @@ class RegisterController extends Controller
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|name|max:255',
'marking' => 'required|max:255|unique:markings',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
@@ -61,12 +60,17 @@ class RegisterController extends Controller
*/
protected function create(Request $data)
{
$this->validate($data, [
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
$marking = Marking::Where('email',$data['email'])->first();
if(!$marking){
return response()->json(["message"=>"Marking does not exist, please contact sales team to get one"], 400);
}
if($marking->marking != $data['marking']){
if($marking->marking != strtoupper($data['marking'])){
return response()->json(["message"=>"Incorrect marking"], 400);
}
@@ -78,7 +82,7 @@ class RegisterController extends Controller
$user = new User();
$user->name = $data['name'];
$user->email = $data['email'];
$user->marking = $marking->marking;
$user->marking = $marking->marking;
$user->password = bcrypt($data['password']);
$user->save();
+293 -89
View File
@@ -13,6 +13,7 @@ use App\Invoice;
use App\SettingCredit;
use App\SettingTaxRate;
use App\SettingBillingCharge;
use App\Notification;
use Auth;
use Validator;
use DateTime;
@@ -23,7 +24,8 @@ class BookingController extends Controller
public function index(){
$user = Auth::user();
$bookings = Booking::select('user_id', 'id', 'created_at', 'status', 'rate', 'term', 'amount', 'bia', 'verification_status')
->where('user_id', $user->id)
->where('user_id', Auth::user()->id)
->where('status', '<', '7')
->orderby('updated_at','desc')
->paginate(10);
@@ -70,17 +72,86 @@ class BookingController extends Controller
default:
$status_desc = "";
}
$booking->status_desc = $status_desc;
$booking->marking = $booking->user->marking;
}
return $bookings;
}
public function userComplete(){
$user = Auth::user();
$bookings = Booking::select('user_id', 'id', 'created_at', 'status', 'rate', 'term', 'amount', 'bia', 'verification_status')
->where('user_id', Auth::user()->id)
->where('status', '=', '7')
->orderby('updated_at','desc')
->paginate(10);
// reformat to fit frontend structure
foreach ($bookings as $booking) {
// set timeout
$date1 = new DateTime($booking->created_at);
$date2 = new DateTime();
$time_in_seconds = SettingCredit::orderby('updated_at','desc')->first()->time_limit;
$difference_in_seconds = ($date1->format('U') + $time_in_seconds) - ($date2->format('U'));
$booking->timeout = $difference_in_seconds;
// TODO : you can make it better
if($difference_in_seconds < 0 ){
$booking->timeout = 0;
}
// TODO : transfer_amount change name to bia
$booking->transfer_amount = $booking->bia;
$booking->track_status = "(". $booking->status ."/7)";
// all x2 until step 5 only
if ($booking->term == "x2_cash" || $booking->term == "x2_cheque" || $booking->term == "x2_ba") {
$booking->track_status = "(". $booking->status ."/5)";
}
switch ($booking->status) {
case 1:
$status_desc = "Order in progress";
break;
case 2:
$status_desc = "Waiting for payment";
break;
case 3:
$status_desc = "Waiting verification";
break;
case 4:
$status_desc = "Processing transfer";
break;
case 5:
$status_desc = "Transfer Complete, please upload your PO";
if ($booking->term == "x2_cash" || $booking->term == "x2_cheque" || $booking->term == "x2_ba"){
$status_desc = "Order Completed";
}
break;
case 6:
$status_desc = "Processing invoice";
break;
case 7:
$status_desc = "Order Completed";
break;
default:
$status_desc = "";
}
$booking->status_desc = $status_desc;
$booking->marking = $booking->user->marking;
}
return $bookings;
}
public function adminIndex(){
$user = Auth::user();
$bookings = Booking::select('user_id', 'id', 'created_at', 'admin_status', 'rate', 'term', 'amount', 'bia', 'verification_status')
->where('status', '<', '7')
->orderby('updated_at','desc')
->get();
->paginate(10);
// reformat to fit frontend structure
foreach ($bookings as $booking) {
@@ -100,9 +171,8 @@ class BookingController extends Controller
$booking->transfer_amount = $booking->bia;
$term = $booking->term;
if($term == "x1_ba" || $term == "x2_cheque"){
$status = $booking->admin_status > 2 ? $booking->admin_status - 2 : $booking->admin_status;
$booking->track_status = "(". $status ."/5)";
if ($booking->term == "x2_cash" || $booking->term == "x2_cheque" || $booking->term == "x2_ba"){
$booking->track_status = "(". $booking->admin_status ."/6)";
}
else{
$booking->track_status = "(". $booking->admin_status ."/7)";
@@ -116,20 +186,19 @@ class BookingController extends Controller
$status_desc = "Verify user bank slip";
break;
case 3:
if($term !== "x1_ba" || $term !== "x2_cheque"){
$status_desc = "Generate supplier booking report";
break;
}
$status_desc = "Generate supplier booking report";
break;
case 4:
if($term !== "x1_ba" || $term !== "x2_cheque"){
$status_desc = "Supplier booking report. Please confirm with your booking.";
break;
}
$status_desc = "Supplier booking report. Please confirm with your booking.";
break;
case 5:
$status_desc = "Please, upload China Bankslip";
break;
case 6:
$status_desc = "Waiting customer to upload purchase order";
case 6:
$status_desc = "Waiting customer to upload purchase order";
if ($booking->term == "x2_cash" || $booking->term == "x2_cheque" || $booking->term == "x2_ba"){
$status_desc = "Order Completed";
}
break;
case 7:
$status_desc = "Customer has uploaded purchase order, please upload invoice";
@@ -146,19 +215,76 @@ class BookingController extends Controller
return $bookings;
}
public function adminBookComplete(){
$user = Auth::user();
$bookings = Booking::select('user_id', 'id', 'created_at', 'status', 'rate', 'term', 'amount', 'bia', 'verification_status')
->where('admin_status', '=', '7')
->orderby('updated_at','desc')
->paginate(10);
// reformat to fit frontend structure
foreach ($bookings as $booking) {
// set timeout
$date1 = new DateTime($booking->created_at);
$date2 = new DateTime();
$time_in_seconds = SettingCredit::orderby('updated_at','desc')->first()->time_limit;
$difference_in_seconds = ($date1->format('U') + $time_in_seconds) - ($date2->format('U'));
$booking->timeout = $difference_in_seconds;
// TODO : you can make it better
if($difference_in_seconds < 0 ){
$booking->timeout = 0;
}
// TODO : transfer_amount change name to bia
$booking->transfer_amount = $booking->bia;
$booking->track_status = "(". $booking->status ."/7)";
switch ($booking->status) {
case 1:
$status_desc = "Order in progress";
break;
case 2:
$status_desc = "Waiting for payment";
break;
case 3:
$status_desc = "Waiting verification";
break;
case 4:
$status_desc = "Processing transfer";
break;
case 5:
$status_desc = "Transfer Complete, please upload your PO";
break;
case 6:
$status_desc = "Processing invoice";
break;
case 7:
$status_desc = "Order Completed";
break;
default:
$status_desc = "";
}
$booking->status_desc = $status_desc;
$booking->marking = $booking->user->marking;
}
return $bookings;
}
public function show($id)
{
$booking = Booking::where('user_id',Auth::user()->id)->where('id', $id)->first();
$user_bankslip = $booking->userBankSlip()->first();
$china_bankslip = $booking->chinaBankSlip()->get();
$po = $booking->purchaseOrder()->first();
$invoice = $booking->invoice()->first();
if($booking){
$date1 = new DateTime($booking->created_at);
$user_bankslip = $booking->userBankSlip()->first();
$china_bankslip = $booking->chinaBankSlip()->get();
$po = $booking->purchaseOrder()->first();
$invoice = $booking->invoice()->first();
if ($user_bankslip){
$booking->user_bankslip_path = Storage::url($user_bankslip->bankslip_path);
$booking->reject_reason = $user_bankslip->reject_reason;
@@ -193,7 +319,10 @@ class BookingController extends Controller
}
return $booking;
}
}
else{
return response()->json(['success'=>false, 'message'=>'Booking not found'], 404);
}
}
public function adminShow($id)
@@ -248,7 +377,9 @@ class BookingController extends Controller
$term = $request->input('term');
$amount = $request->input("amount"); // in RMB
$rates = Rate::orderby('updated_at','desc')->first();
$creditLimit = SettingCredit::orderby('updated_at','desc')->first();
$creditLimit = SettingCredit::orderby('updated_at','desc')->first();
$taxrate = SettingTaxRate::latest()->first()->tax_rate;
$billingChargeRate = SettingBillingCharge::latest()->first()->billing_charge_rate;
if (!$creditLimit){
return response()->json("Credit limit not set, please contact admin", 405);
@@ -289,41 +420,48 @@ class BookingController extends Controller
break;
}
// Service charge (RMB) : if amount higher than 10,000, no service charge. if amount lower than 10,000, 20.00 service charge
if ($amount >= 10000 && ($term == 'x2_cash' || $term = 'x2_cheque' || $term = 'x2_ba')) {
// Service charge (RMB) : if amount higher than 10,000 or term x2 no service charge.
if ($amount >= 10000 && ($term == 'x2_cash' || $term == 'x2_cheque' || $term == 'x2_ba')) {
$svcharge = 0;
} else {
$svcharge = 20.00;
}
// initial rmb to myr amount
$RMBinMYR = (($amount + $svcharge) / $rate);
// TODO : Should be remove this ?
// gst 0%
$gst = 0 * $RMBinMYR;
// Sales tax : 10 %
$sales_tax = 0.10 * $RMBinMYR;
// Billing fees : 1.5%
$billing = 0.015 * $RMBinMYR;
// Bank in amount
$bia = round($RMBinMYR + $gst + $sales_tax + $billing, 2);
$subtotal = round(($amount + $svcharge) / $rate, 2);
// TODO : refactor
if ($taxrate !=0){
$taxAmount = round($subtotal * $taxrate - $subtotal, 2);
}
else{
$taxAmount = 0;
}
if ($term == 'x2_cash' || $term == 'x2_cheque' || $term == 'x2_ba'){
$billingChargeAmount = 0;
}
else{
// TODO : billing charge rate to percentage so we do not need to minus amount + svcharge
$billingChargeAmount = round((($amount / $rate) * $billingChargeRate) - ($amount / $rate), 2);
}
$bankin_amount = round($subtotal + $taxAmount + $billingChargeAmount , 2);
$booking = new Booking();
$booking->account_name = $request->input('account_name');
$booking->account_num = $request->input('account_num');
$booking->bank_name = $request->input('bank_name');
$booking->bank_branch = $request->input('bank_branch');
$booking->amount = $request->input('amount');
$booking->order_no = $request->input('order_no');
$booking->payment_for = $request->input('payment_for');
$booking->term = $term;
$booking->rate_id = $rates->id;
$booking->rate = $rate;
$booking->rmb_book_amount = $request->input('amount');
$booking->rmb_book_amount = $request->input('amount'); // BIG TODO : amount change variable name to rmb_book_amount
$booking->status = 2;
$booking->bia = $bia;
$booking->bia = $bankin_amount; // BID TODO : change bia viariable name
// $booking->user_id = $user->id;
$booking->user()->associate($user);
@@ -350,8 +488,9 @@ class BookingController extends Controller
// $booking->usd_book_cnap = $request->input('usd_book_cnap');
// $booking->usd_book_bank_branch = $request->input('usd_book_bank_branch');
// $booking->verification_status = $request->input('verification_status');
// return response()->json($booking, 201);
$booking->save();
//return response()->json('error', 400);
// return response()->json('error', 400);
return response()->json($booking, 201);
}
@@ -392,7 +531,7 @@ class BookingController extends Controller
}
$validator = Validator::make($request->all(), [
'file' => 'max:3072'
'file' => 'max:10000' // image size
]);
if($validator->fails())
@@ -415,19 +554,26 @@ class BookingController extends Controller
'user_bankslip', $bankslip_file, $unique_image_path
);
$user_bankslip = $booking->userBankSlip()->first();
if($upload_path){
$user_bankslip = $booking->userBankSlip()->first();
// if user bankslip not exist, create new one
if(!$user_bankslip){
$user_bankslip = new UserBankSlip;
// if user bankslip not exist, create new one
if(!$user_bankslip){
$user_bankslip = new UserBankSlip;
}
$user_bankslip->booking_id = $booking->id;
$user_bankslip->bankslip_path = $upload_path;
$user_bankslip->transfer_amount = $request->input('transfer_amount');
$user_bankslip->save();
return response()->json(['message'=>"Success"],200);
}
else{
return response()->json(['message' => 'File not uploaded. Please contact support'], 400);
}
$user_bankslip->booking_id = $booking->id;
$user_bankslip->bankslip_path = $upload_path;
$user_bankslip->transfer_amount = $request->input('transfer_amount');
$user_bankslip->save();
return response()->json(['message'=>"Success"],200);
}
else {
return response()->json(['message' => 'No file detected'], 400);
@@ -447,9 +593,16 @@ class BookingController extends Controller
$booking->admin_status = 2;
$booking->save();
// Add notification message to admin
$adminNotification = new Notification;
$adminNotification->detail = "A bankslip is uploaded for booking " . $booking->id;
$adminNotification->link = "/booking/" . $booking->id . "/verification";
$adminNotification->user_id = User::withRole('admin')->first()->id;
$adminNotification->save();
$user_bankslip->transfer_amount = $request->input('transfer_amount');
$user_bankslip->save();
return response()->json(["message"=> "Success"],200);
return response()->json($adminNotification,200);
}
public function uploadPurchaseOrder(Request $request, $id)
@@ -472,7 +625,7 @@ class BookingController extends Controller
}
$validator = Validator::make($request->all(), [
'file' => 'max:3072'
'file' => 'max:10000'
]);
if($validator->fails())
@@ -545,6 +698,8 @@ class BookingController extends Controller
$amount = $request->input('amount');
$term = $request->input('term');
$china_beneficiary = $request->input('china_beneficiary');
$order_no = $request->input('order_no');
$payment_for = $request->input('payment_for');
$rates = Rate::orderby('updated_at','desc')->first();
$marking = $user = Auth::user()->marking;
$taxrate = SettingTaxRate::latest()->first()->tax_rate;
@@ -559,16 +714,15 @@ class BookingController extends Controller
if($amount > $creditLimit->rmb_credit_limit){
return response()->json(["message" => "Exceed credit limit, please contact our sales team for larger quantitiy"], 400);
}
switch ($term) {
case "x1_cash":
$rate = $rates->x1_cash;
$payment_method = "cash";
$payment_method = "CASH";
break;
case "x1_cheque":
$rate = $rates->x1_cheque;
$payment_method = "Cheque";
$payment_method = "CHEQUE";
break;
case "x1_ba":
$rate = $rates->x1_ba;
@@ -576,11 +730,11 @@ class BookingController extends Controller
break;
case "x2_cash":
$rate = $rates->x2_cash;
$payment_method = "Cash";
$payment_method = "CASH";
break;
case "x2_cheque":
$rate = $rates->x2_cheque;
$payment_method = "Cheque";
$payment_method = "CHEQUE";
break;
case "x2_ba":
$rate = $rates->x2_ba;
@@ -594,19 +748,36 @@ class BookingController extends Controller
break;
}
if ($amount >= 10000 && ($term == 'x2_cash' || $term = 'x2_cheque' || $term = 'x2_ba')) {
if ($amount >= 10000 && ($term == 'x2_cash' || $term == 'x2_cheque' || $term == 'x2_ba')) {
$svcharge = 0;
} else {
$svcharge = 20.00;
}
$subtotal = round($amount + $svcharge / $rate,2);
$taxAmount = round($subtotal * $taxrate,2);
$billingChargeAmount = round(($amount + $svcharge) * $billingChargeRate, 2);
$subtotal = round(($amount + $svcharge) / $rate,2);
// TODO : refactor
if ($taxrate !=0){
$taxAmount = round($subtotal * $taxrate - $subtotal,2);
}
else{
$taxAmount = 0;
}
if ($term == 'x2_cash' || $term == 'x2_cheque' || $term == 'x2_ba'){
$billingChargeAmount = 0;
}
else{
// TODO : billing charge rate to percentage so we do not need to minus amount + svcharge
$billingChargeAmount = round((($amount / $rate) * $billingChargeRate) - ($amount / $rate), 2);
}
$bankin_amount = round($subtotal + $taxAmount + $billingChargeAmount , 2);
return response()->json([
'date' => date('Y-m-d'),
'order_no' => $order_no,
'payment_for' => $payment_for,
'marking' => $marking,
'payment_method' => $payment_method,
'china_beneficary' => $china_beneficiary,
@@ -617,6 +788,10 @@ class BookingController extends Controller
'taxAmount' => $taxAmount,
'billingChargeAmount' => $billingChargeAmount,
'bankin_amount' => $bankin_amount,
'bank_name'=> $request->input('bank_name'),
'bank_branch'=> $request->input('bank_branch'),
'acc_name' => $request->input('acc_name'),
'acc_no' => $request->input('acc_no')
], 200);
}
@@ -642,16 +817,30 @@ class BookingController extends Controller
$userBankSlip->is_approve = 1;
$userBankSlip->is_reject = 0;
$userBankSlip->estimated_arrival_time = $request->input('estimated_arrival_time');
$userBankSlip->save();
// update booking status
$booking->status = 4;
if($booking->term !== "x1_ba" || $booking->term !== "x2_cheque")
if($booking->term !== "x1_ba" || $booking->term !== "x2_cheque"){
$booking->admin_status = 3;
else
// Add notification message to user
$userNotification = new Notification;
$userNotification->detail = "Your bankslip for booking " . $booking->id . " is approved.";
$userNotification->link = "/booking/" . $booking->id . "/transfer";
$userNotification->user_id = $booking->user_id;
$userNotification->save();
}
else{
$booking->admin_status = 5;
// Add notification message to user
$userNotification = new Notification;
$userNotification->detail = "Your bankslip for booking " . $booking->id . " is approved.";
$userNotification->link = "/booking/" . $booking->id . "/supplier";
$userNotification->user_id = $booking->user_id;
$userNotification->save();
}
$booking->save();
return response()->json(['message'=>'Success'],200);
}
@@ -707,7 +896,7 @@ class BookingController extends Controller
}
$validator = Validator::make($request->all(), [
'invoice_path' => 'max:3072'
'invoice_path' => 'max:10000'
]);
if($validator->fails())
@@ -747,6 +936,11 @@ class BookingController extends Controller
$booking->admin_status = 5; // upload china bankslip
if($booking->save()){
$userNotification = new Notification;
$userNotification->detail = "Supplier booking report for booking " . $booking->id . " is completed.";
$userNotification->link = "/booking/" . $booking->id . "/transfer";
$userNotification->user_id = $booking->user_id;
$userNotification->save();
return response()->json(['message'=>"Success"],200);
}
}
@@ -755,16 +949,21 @@ class BookingController extends Controller
$booking = Booking::where('user_id',Auth::user()->id)->where('id',$id)->first();
$purchase_order = $booking->purchaseOrder()->first();
return($purchase_order);
if(!$purchase_order){
return response()->json(["message"=> "Please upload your purchase order"],400);
}
$booking->status = 6; // wait invoice
$booking->admin_status = 6; // upload invoice
$booking->save();
return response()->json(['message'=>'Success'],200);
$adminNotification = new Notification;
$adminNotification->detail = "Purchase Order for booking " . $booking->id . " is uploaded.";
$adminNotification->link = "/booking/" . $booking->id . "/upload-invoice";
$adminNotification->user_id = User::withRole('admin')->first()->id;
$adminNotification->save();
return response()->json($purchase_order,200);
}
public function confirmInvoice(Request $request, $id)
@@ -781,27 +980,32 @@ class BookingController extends Controller
$booking->admin_status = 7; // completed
if($booking->save()){
$adminNotification = new Notification;
$adminNotification->detail = "Invoice for booking " . $booking->id . " is uploaded.";
$adminNotification->link = "/booking/" . $booking->id . "/complete";
$adminNotification->user_id = $booking->user_id;
$adminNotification->save();
return response()->json(['message'=>"Success"],200);
}
}
// public function adminShowCompletedOrders()
// {
// $bookings = Booking::select('id','created_at','user_id','rate','amount', 'bia', 'admin_status')
// ->where('admin_status', 7)
// ->orderBy('id', 'desc')
// ->get();
public function adminShowCompletedOrders()
{
$bookings = Booking::select('id','created_at','user_id','rate','amount', 'bia', 'admin_status')
->where('admin_status', 7)
->orderBy('id', 'desc')
->get();
// foreach ($bookings as $booking) {
// $booking->id;
// $booking->created_at;
// $booking->marking = $booking->user->marking;
// $booking->rate;
// $booking->amount;
// $booking->bia;
// $booking->admin_status = "(". $booking->admin_status ."/7)";;
// }
// return $bookings;
// }
foreach ($bookings as $booking) {
$booking->id;
$booking->created_at;
$booking->marking = $booking->user->marking;
$booking->rate;
$booking->amount;
$booking->bia;
$booking->admin_status = "(". $booking->admin_status ."/7)";;
}
return $bookings;
}
}
@@ -11,6 +11,8 @@ use App\UserBankSlip;
use App\SettingBeneficiary;
use App\SupplierBookingItem;
use App\SettingSupplier;
use App\SettingTaxRate;
use App\SettingActiveBank;
use Illuminate\Http\Request;
class BookingSupplierController extends Controller
@@ -30,15 +32,68 @@ class BookingSupplierController extends Controller
public function show($id)
{
$booking = Booking::where('id', $id)->first();
$bankin_amount = round($booking->amount / $booking->rate, 2);
if (!$booking){
return response()->json(['message' => 'Booking not found'], 404);
}
switch ($booking->term) {
case "x1_cash":
$payment_method = "CASH";
break;
case "x1_cheque":
$payment_method = "CHEQUE";
break;
case "x1_ba":
$payment_method = "BA";
break;
case "x2_cash":
$payment_method = "CASH";
break;
case "x2_cheque":
$payment_method = "CHEQUE";
break;
case "x2_ba":
$payment_method = "BA";
break;
default:
return response()->json([
'success' => false,
'message' => 'Invalid input',
], 422);
break;
}
$supplier_booking = $booking->supplierBooking()->first();
$dt = new \DateTime($supplier_booking->created_at);
$supplier_booking->date = $dt->format('j F Y');
$supplier_booking->marking = $booking->user->marking;
$supplier_booking->payment_for = $booking->payment_for;
$supplier_booking->order_no = $booking->order_no;
$supplier_booking->payment_method = $payment_method;
$active_bank = SettingActiveBank::first();
// if setting is set to use customer's beneficiary
if ($active_bank->beneficiary_id == 0){
$supplier_booking->acc_name = $booking->account_name;
$supplier_booking->acc_no = $booking->account_num; // TODO : standardize acc_no
$supplier_booking->bank_name = $booking->bank_name;
$supplier_booking->bank_branch = $booking->bank_branch;
}
else{
$beneficiary = SettingBeneficiary::find($active_bank->beneficiary_id);
$supplier_booking->acc_name = $beneficiary->company_name;
$supplier_booking->acc_no = $beneficiary->acc_no;
$supplier_booking->bank_name = $beneficiary->bank_name;
$supplier_booking->bank_branch = $beneficiary->bank_branch;
}
return response()->json($supplier_booking ,200);
}
@@ -47,41 +102,58 @@ class BookingSupplierController extends Controller
// TODO : Multiple booking
public function store(Request $request)
{
$transfer_amount = $request->input("transfer_amount");
//$transfer_amount = $request->input("transfer_amount");
$supplier_id = $request->input("supplier_id");
$booking_id = $request->input("booking_id");
$rate = $request->input('rate');
$rate = $request->input('rate'); // costing rate
$rebate = $request->input('rebate');
// Calculation
$amountInRMB = $transfer_amount * $rate;
$billing = 0.015 * $transfer_amount;
$sales_tax = 0.10 * $transfer_amount;
$gst = 0 * $transfer_amount; // do we still need this ?
$customerBankInAmount = round($transfer_amount + $gst + $sales_tax + $billing,2);
$rmbBankAmount = $customerBankInAmount + $rebate;
$user = Auth::user();
$supplier = SettingSupplier::find($supplier_id);
$booking = Booking::find($booking_id);
// Calculation (backup)
// $amountInRMB = $transfer_amount * $rate;
// $billing = 0.015 * $transfer_amount;
// $sales_tax = 0.0 * $transfer_amount;
// $gst = 0 * $transfer_amount; // do we still need this ?
// $customerBankInAmount = round($transfer_amount + $gst + $sales_tax + $billing,2);
// $rmbBankAmount = round($customerBankInAmount + $rebate, 2);
// Update: changes in 1.1 according to new supplier booking report
$transfer_amount = $booking->amount;
$amount_in_myr = round($transfer_amount / $rate, 2);
$amountInRMB = $transfer_amount;
$tax_rate = SettingTaxRate::latest()->first()->tax_rate;
$sales_tax = round($tax_rate * $amount_in_myr - $amount_in_myr, 2);
$amount_after_tax = round($amount_in_myr * $tax_rate,2);
//$billing = 0.015 * $transfer_amount;
//
//$gst = 0 * $transfer_amount; // do we still need this ?
//$customerBankInAmount = round($transfer_amount + $gst + $sales_tax + $billing,2);
//$rmbBankAmount = round($customerBankInAmount + $rebate, 2);
// update existing booking supplier if exist
$bookingsupplier = SupplierBooking::where('booking_id', $booking_id)->first();
if (!$bookingsupplier){
$bookingsupplier = new SupplierBooking();
}
$bookingsupplier->supplier_id = $supplier->id;
$bookingsupplier->payment_method = $request->input('payment_method');
$bookingsupplier->transfer_amount = $transfer_amount;
$bookingsupplier->amountInRMB = $amountInRMB; // TODO : rename to underscore
$bookingsupplier->amount_in_myr = $amount_in_myr;
$bookingsupplier->tax_rate = $tax_rate;
$bookingsupplier->amount_after_tax = $amount_after_tax;
$bookingsupplier->rate = $rate;
$bookingsupplier->billing_amount = $billing;
$bookingsupplier->salestax_amount = $sales_tax;
$bookingsupplier->rebate = $rebate;
$bookingsupplier->amountInRMB = $amountInRMB;
$bookingsupplier->rmbBankAmount = $rmbBankAmount;
$bookingsupplier->rebate = $rebate;
$bookingsupplier->salestax_amount = $sales_tax;
//$bookingsupplier->payment_method = $request->input('payment_method'); // TODO : remove from db
//$bookingsupplier->transfer_amount = $transfer_amount; // TODO : remove from db
//$bookingsupplier->billing_amount = $billing; // TODO : remove from db
//$bookingsupplier->rmbBankAmount = $rmbBankAmount; // TODO : remove from db
$bookingsupplier->booking_id = $booking->id;
$bookingsupplier->save();
@@ -89,47 +161,12 @@ class BookingSupplierController extends Controller
$booking->status = 4;
$booking->admin_status = 4;
$booking->save();
return response()->json($bookingsupplier, 201);
}
public function update(Request $request, $id)
{
$bookingsupplier = SupplierBooking::find($id);
$bookingsupplier->payment_method = $request->input('payment_method');
$bookingsupplier->transfer_amount = $request->input('transfer_amount');
$bookingsupplier->rate = $request->input('rate');
$bookingsupplier->rebate = $request->input('rebate');
// calculation
$amountInRMB = $amount * $rate;
$billing = 0.015 * $amount;
$sales_tax = 0.10 * $amount;
$gst = 0 * $amount;
$customerBankInAmount = round($amount + $gst + $sales_tax + $billing,2);
$rmbBankAmount = $customerBankInAmount + $rebate;
// save amount in rmb
$bookingsupplier->amountInRMB = $amountInRMB;
// save rmb bank amount
$bookingsupplier->rmbBankAmount = $rmbBankAmount;
$bookingsupplier->save();
/* For multiple booking */
// $supplierbookingitems = $request->input("supplierbookingitem");
// foreach ($bookings as $booking)
// {
// $update_supplierbookingitem = SupplierBookingItem::where('supplierbooking_id', $id)->first();
// $update_supplierbookingitem->china_bankslip_url = $booking['china_bankslip_url'];
// $update_supplierbookingitem->bank_in_amount = $booking['bank_in_amount'];
// $update_supplierbookingitem->date = $booking['date'];
// $update_supplierbookingitem->details = $booking['details'];
// $update_supplierbookingitem->save();
// }
return response()->json(['book_id'=>$book_id],201);
}
public function report(Request $request, $id)
{
$supplier_booking = Booking::firstOrFail($id)->supplierBooking()->firstOrFail();
@@ -4,6 +4,8 @@ namespace App\Http\Controllers;
use App\ChinaBankSlip;
use App\Booking;
use App\User;
use App\Notification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Validator;
@@ -30,7 +32,7 @@ class ChinaBankSlipController extends Controller
}
$validator = Validator::make($request->all(), [
'china_bank_slips' => 'max:3072'
'china_bank_slips' => 'max:10000'
]);
if($validator->fails()){
@@ -80,6 +82,13 @@ class ChinaBankSlipController extends Controller
$booking->admin_status = 6;
$booking->save();
$userNotification = new Notification;
$userNotification->detail = "Your china bankslip for booking " . $booking->id . " is uploaded.";
$userNotification->link = "/booking/" . $booking->id . "/upload-po";
$userNotification->user_id = $booking->user_id;
$userNotification->save();
return response()->json(["message"=> "Success"],200);
}
+5 -1
View File
@@ -19,13 +19,17 @@ class MarkingController extends Controller
public function store(Request $request)
{
$marking = Marking::create($request->all());
$marking = new Marking;
$marking->marking = strtoupper($request->input('marking'));
$marking->email = $request->input('email');
$marking->save();
return response()->json($marking, 201);
}
public function update(Request $request, Marking $marking)
{
// TODO : update to upper case
$marking->update($request->all());
return response()->json($marking, 200);
@@ -0,0 +1,66 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Notification;
use Illuminate\Support\Facades\DB;
use Auth;
class NotificationController extends Controller
{
public function index()
{
return Notification::all()->orderby('updated_at','desc');
}
public function show(Notification $notification)
{
return $notification;
}
public function store(Request $request)
{
$notification = Notification::create($request->all());
return response()->json($notification, 201);
}
public function update(Request $request, Notification $notification)
{
$notification->update($request->all());
return response()->json($notification, 200);
}
public function delete(Notification $notification)
{
$notification->delete();
return response()->json(null, 204);
}
public function getUserMessage()
{
$user_all_notification = Notification::Where("user_id",Auth::user()->id)
->orderby('updated_at','desc')
->paginate(5);
$user_unread_notification = Notification::Where([["user_id",Auth::user()->id],["is_read",0]])
->orderby('updated_at','desc')
->get();
return response()->json([
"message" =>$user_all_notification,
"unread_message" =>$user_unread_notification
],200);
}
public function readNotification($notification_id){
$affected = DB::table('notifications')
->Where('id', $notification_id)
->update(array('is_read' => 1));
return response()->json("Read message", 200);
}
}
@@ -12,8 +12,12 @@ class SettingBeneficiaryController extends Controller
return SettingBeneficiary::all();
}
public function show(SettingBeneficiary $beneficiary)
public function show($beneficiary)
{
if ($beneficiary == 0){
response()->json(["company_name"=>"123", "account_number"=>"123"] , 201);
}
$beneficiary = SettingBeneficiary::find($beneficiary);
return $beneficiary;
}
+1
View File
@@ -61,6 +61,7 @@ class Kernel extends HttpKernel
'ability' => 'App\Http\Middleware\TokenEntrustAbility',
'role' => \Zizaco\Entrust\Middleware\EntrustRole::class,
'permission' => \Zizaco\Entrust\Middleware\EntrustPermission::class,
'jwt' => \App\Http\Middleware\RefreshToken::class,
'ability' => 'App\Http\Middleware\TokenEntrustAbility'
];
}
+1 -1
View File
@@ -5,7 +5,7 @@ namespace App\Http\Middleware;
use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
class TokenEntrustAbility extends BaseMiddleware
{
+77
View File
@@ -0,0 +1,77 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Notification extends Model
{
protected $fillable = ['detail','user_id','is_read'];
protected $appends = ['time_interval'];
public function getTimeIntervalAttribute()
{
$created_time = $this->created_at;
date_default_timezone_set('Asia/Kuala_Lumpur'); //Change as per your default time
$str = strtotime($created_time);
$today = strtotime(date('Y-m-d H:i:s'));
// It returns the time difference in Seconds...
$time_differnce = $today-$str;
// To Calculate the time difference in Years...
$years = 60*60*24*365;
// To Calculate the time difference in Months...
$months = 60*60*24*30;
// To Calculate the time difference in Days...
$days = 60*60*24;
// To Calculate the time difference in Hours...
$hours = 60*60;
// To Calculate the time difference in Minutes...
$minutes = 60;
if(intval($time_differnce/$years) > 1)
{
return intval($time_differnce/$years)." years ago";
}else if(intval($time_differnce/$years) > 0)
{
return intval($time_differnce/$years)." year ago";
}else if(intval($time_differnce/$months) > 1)
{
return intval($time_differnce/$months)." months ago";
}else if(intval(($time_differnce/$months)) > 0)
{
return intval(($time_differnce/$months))." month ago";
}else if(intval(($time_differnce/$days)) > 1)
{
return intval(($time_differnce/$days))." days ago";
}else if (intval(($time_differnce/$days)) > 0)
{
return intval(($time_differnce/$days))." day ago";
}else if (intval(($time_differnce/$hours)) > 1)
{
return intval(($time_differnce/$hours))." hours ago";
}else if (intval(($time_differnce/$hours)) > 0)
{
return intval(($time_differnce/$hours))." hour ago";
}else if (intval(($time_differnce/$minutes)) > 1)
{
return intval(($time_differnce/$minutes))." minutes ago";
}else if (intval(($time_differnce/$minutes)) > 0)
{
return intval(($time_differnce/$minutes))." minute ago";
}else if (intval(($time_differnce)) > 1)
{
return intval(($time_differnce))." seconds ago";
}else
{
return "few seconds ago";
}
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
class UserBankSlip extends Model
{
protected $fillable = ['bank_slip_type','bankslip_url','transfer_amount','booking_id','cust_marking','estimated_arrival_time'];
protected $fillable = ['bank_slip_type','bankslip_url','transfer_amount','booking_id','cust_marking'];
public function booking()
{
+11 -3
View File
@@ -1,18 +1,26 @@
# Docs: https://caddyserver.com/docs/caddyfile
https://exchange-staging.izyim.com {
proxy /phpmyadmin 127.0.0.1:8090
root /var/www/public
fastcgi / 127.0.0.1:9000 php {
index index.php
}
header / {
Cache-Control no-cache
}
# To handle .html extensions with laravel change ext to
# ext / .html
rewrite {
to {path} {path}/ /index.php?{query}
r .*
ext /
to /index.php?{query}
}
gzip
browse
# browse
log stdout
errors stdout
on startup php-fpm --nodaemonize
+3 -1
View File
@@ -12,6 +12,8 @@ RUN curl --silent --show-error --fail --location \
COPY Caddyfile /etc/Caddyfile
WORKDIR /var/www/public
WORKDIR /var/www
RUN mkdir -p /var/www/public/storage
RUN ln -sf /var/www/storage/app/public /var/www/public/storage
CMD ["/usr/bin/caddy", "--conf", "/etc/Caddyfile", "--log", "stdout"]
Generated
-5224
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -169,6 +169,7 @@ return [
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
Tymon\JWTAuth\Providers\LaravelServiceProvider::class
],
/*
@@ -219,6 +220,9 @@ return [
'View' => Illuminate\Support\Facades\View::class,
'Html' => Collective\Html\HtmlFacade::class,
'Entrust' => Zizaco\Entrust\EntrustFacade::class,
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
],
];
+4 -4
View File
@@ -50,7 +50,7 @@ return [
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false,
'strict' => true,
'engine' => null,
],
@@ -58,9 +58,9 @@ return [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'database' => 'forunittest',
'username' => 'root',
'password' => '',
'database' => 'phpunit',
'username' => 'default',
'password' => 'secret',
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
+1 -1
View File
@@ -100,7 +100,7 @@ return [
|
*/
'ttl' => env('JWT_TTL', 60),
'ttl' => env('JWT_TTL', 60 * 12),
/*
|--------------------------------------------------------------------------
+1 -1
View File
@@ -5,6 +5,6 @@ use Faker\Generator as Faker;
$factory->define(App\Marking::class, function (Faker $faker) {
return [
'email' => $faker->unique()->safeEmail,
'marking' => str_random(10)
'marking' => strtoupper(str_random(5))
];
});
@@ -11,6 +11,5 @@ $factory->define(App\UserBankSlip::class, function (Faker $faker) {
'transfer_amount' => $faker->randomDigit,
'cust_marking' => str_random(10),
'booking_id' => $faker->randomElement($book_id),
'estimated_arrival_time' => $faker->randomDigit
];
});
+2 -2
View File
@@ -21,6 +21,6 @@ $factory->define(App\User::class, function (Faker $faker) {
'email' => $faker->unique()->safeEmail,
'password' => $password ?: $password = bcrypt('secret'),
'remember_token' => str_random(10),
'marking' => $faker->name,
'marking' => $faker->name,
];
});
});
@@ -17,7 +17,7 @@ class CreateSettingSuppliersTable extends Migration
$table->increments('id');
$table->string('company_name');
$table->string('gst_no');
$table->string('supplier_reg_no');
$table->string('supplier_reg_no')->nullable();
$table->string('bank_name');
$table->string('acc_no');
$table->timestamps();
@@ -21,7 +21,7 @@ class CreateChinaBankSlipsTable extends Migration
$table->string('bank_address');
$table->string('swift');
$table->string('cnap');
$table->string('bank _branch');
$table->string('bank_branch');
$table->string('order_id');
$table->double('transfer_amount_needed');
$table->double('actual_transfer_amount');
@@ -17,7 +17,7 @@ class CreatePurchaseOrdersTable extends Migration
$table->increments('id');
$table->string('image_url');
$table->double('amount');
$table->integer('book_id')->unsigned();
$table->integer('book_id')->unsigned()->nullable;
$table->foreign('book_id')->references('id')->on('bookings');
$table->timestamps();
});
@@ -14,7 +14,7 @@ class AddTimeLimitSettingCreditTable extends Migration
public function up()
{
Schema::table('setting_credits', function (Blueprint $table) {
$table->integer('time_limit');
$table->integer('time_limit')->nullable();
});
}
@@ -26,7 +26,7 @@ class AddTimeLimitSettingCreditTable extends Migration
public function down()
{
Schema::table('setting_credits', function (Blueprint $table) {
// $table->dropColumn('time_limit');
$table->dropColumn('time_limit');
});
}
}
@@ -14,7 +14,7 @@ class AddEtaUserBankSlipTable extends Migration
public function up()
{
Schema::table('user_bank_slips', function (Blueprint $table) {
$table->integer('estimated_arrival_time');
$table->integer('estimated_arrival_time')->nullable();
});
}
@@ -27,7 +27,7 @@ class AddEtaUserBankSlipTable extends Migration
{
if (Schema::hasColumn('user_bank_slips', 'estimated_arrival_time')) {
Schema::table('user_bank_slips', function (Blueprint $table) {
// $table->dropColumn('estimated_arrival_time');
$table->dropColumn('estimated_arrival_time');
});
}
}
@@ -15,7 +15,7 @@ class AddBookingidForeignkeyToChinabankslipTable extends Migration
{
Schema::table('china_bank_slips', function($table)
{
$table->integer('booking_id')->unsigned();
$table->integer('booking_id')->unsigned()->nullable();
$table->foreign('booking_id')->references('id')->on('bookings');
});
}
@@ -17,7 +17,7 @@ class RenameBookingForeignkeyInPoTable extends Migration
{
$table->dropForeign(['book_id']);
$table->dropColumn('book_id');
$table->integer('booking_id')->unsigned();
$table->integer('booking_id')->unsigned()->nullable();
$table->foreign('booking_id')->references('id')->on('bookings');
});
}
@@ -17,7 +17,7 @@ class RenameBookingForeignkeyFromSupplierbookingTable extends Migration
{
$table->dropForeign(['book_id']);
$table->dropColumn('book_id');
$table->integer('booking_id')->unsigned();
$table->integer('booking_id')->unsigned()->nullable();
$table->foreign('booking_id')->references('id')->on('bookings');
});
}
@@ -15,7 +15,7 @@ class AddBillingFieldToSupplierbookingTable extends Migration
{
Schema::table('supplier_bookings', function($table)
{
$table->double('billing_amount');
$table->double('billing_amount')->nullable();
});
}
@@ -26,6 +26,8 @@ class AddBillingFieldToSupplierbookingTable extends Migration
*/
public function down()
{
//
Schema::table('supplier_bookings', function (Blueprint $table) {
$table->dropColumn('billing_amount');
});
}
}
@@ -15,7 +15,7 @@ class AddSalestaxFieldToSupplierbookingTable extends Migration
{
Schema::table('supplier_bookings', function($table)
{
$table->double('salestax_amount');
$table->double('salestax_amount')->nullable();
});
}
@@ -26,6 +26,8 @@ class AddSalestaxFieldToSupplierbookingTable extends Migration
*/
public function down()
{
//
Schema::table('supplier_bookings', function (Blueprint $table) {
$table->dropColumn('salestax_amount');
});
}
}
@@ -15,7 +15,7 @@ class AddNameInUsersTable extends Migration
{
Schema::table('users', function($table)
{
$table->string('name');
$table->string('name')->nullable();
});
}
@@ -15,7 +15,7 @@ class AddMarkingToUserTable extends Migration
{
Schema::table('users', function($table)
{
$table->string('marking');
$table->string('marking')->nullable();
});
}
@@ -25,7 +25,10 @@ class AddMarkingToUserTable extends Migration
* @return void
*/
public function down()
{
//
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('marking');
});
}
}
@@ -17,7 +17,7 @@ class CreateSettingActiveBankTable extends Migration
$table->increments('id');
$table->string('x1_bank_id')->unique();
$table->string('x2_bank_id')->unique();
$table->string('beneficiary_id')->unique();
$table->string('beneficiary_id')->nullable();
$table->foreign('x1_bank_id')
->references('acc_no')->on('setting_malaysia_banks')
->onDelete('cascade');
@@ -1,51 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class UpdateAccnoToIdSettingActiveTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('setting_active_banks', function(Blueprint $table)
{
$table->dropForeign('setting_active_banks_x1_bank_id_foreign');
$table->dropForeign('setting_active_banks_x2_bank_id_foreign');
$table->dropForeign('setting_active_banks_beneficiary_id_foreign');
$table->dropColumn('x1_bank_id');
$table->dropColumn('x2_bank_id');
$table->dropColumn('beneficiary_id');
});
Schema::table('setting_active_banks', function(Blueprint $table)
{
$table->unsignedInteger('x1_bank_id')->unique();
$table->foreign('x1_bank_id')
->references('id')->on('setting_malaysia_banks');
$table->unsignedInteger('x2_bank_id')->unique();
$table->foreign('x2_bank_id')
->references('id')->on('setting_malaysia_banks');
$table->unsignedInteger('beneficiary_id')->unique();
$table->foreign('beneficiary_id')
->references('id')->on('setting_beneficiaries');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}
@@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddOrdernoNPaymentforFieldToBookingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('bookings', function (Blueprint $table) {
$table->string('order_no')->nullable();
$table->string('payment_for')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('bookings', function (Blueprint $table) {
//
});
}
}
@@ -0,0 +1,39 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateNotificationTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('notifications', function (Blueprint $table) {
$table->increments('id');
$table->string('detail');
$table->string('link');
$table->unsignedInteger('user_id');
$table->boolean('is_read')->default(0);
$table->timestamps();
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('notifications');
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddFieldsIntoSupplierBookingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('supplier_bookings', function (Blueprint $table) {
$table->string('amount_in_myr')->nullable();
$table->string('tax_rate')->nullable();
$table->string('amount_after_tax')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}
@@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class ChangeDatatypeInBookingTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('bookings', function (Blueprint $table) {
$table->string('account_num')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('bookings', function (Blueprint $table) {
//
});
}
}
@@ -0,0 +1,42 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class MakeNullableInChinaBankSlipsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('china_bank_slips', function (Blueprint $table) {
$table->string('company_name')->nullable()->change();
$table->string('bank_name')->nullable()->change();
$table->string('acc_no')->nullable()->change();
$table->string('bank_address')->nullable()->change();
$table->string('swift')->nullable()->change();
$table->string('cnap')->nullable()->change();
$table->string('order_id')->nullable()->change();
$table->decimal('transfer_amount_needed')->nullable()->change();
$table->decimal('actual_transfer_amount')->nullable()->change();
$table->string('date')->nullable()->change();
$table->string('details')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('china_bank_slips', function (Blueprint $table) {
//
});
}
}
@@ -0,0 +1,37 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class MakeNullableInBookingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('bookings', function (Blueprint $table) {
$table->string('company_name')->nullable()->change();
$table->string('company_address')->nullable()->change();
$table->string('bank_address')->nullable()->change();
$table->string('swift_code')->nullable()->change();
$table->string('cnap')->nullable()->change();
$table->string('term')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('bookings', function (Blueprint $table) {
//
});
}
}
@@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class MakeNullableInSupplierBookingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('supplier_bookings', function (Blueprint $table) {
$table->decimal('transfer_amount')->nullable()->change();
$table->decimal('rmbBankAmount')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('supplier_bookings', function (Blueprint $table) {
//
});
}
}
@@ -0,0 +1,29 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class DropEtaInChinaBankSlipsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('user_bank_slips', function (Blueprint $table) {
$table->dropColumn('estimated_arrival_time');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
}
@@ -0,0 +1,30 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RemoveBillingAmountInSupplierBookings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('supplier_bookings', function (Blueprint $table) {
$table->dropColumn('billing_amount');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class DropcolumnBankBranchInChinaBankSlipsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('china_bank_slips', function (Blueprint $table) {
$table->dropColumn('bank_branch');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('china_bank_slips', function (Blueprint $table) {
//
});
}
}
+5 -3
View File
@@ -18,8 +18,8 @@ class BookTableSeeder extends Seeder
$rate = Rate::all()->last();
DB::table('bookings')->insert([
'account_name' => 'milah',
'account_num' => '99898',
'account_name' => 'EXCHANGE SDN BHD',
'account_num' => '99898239298123',
'bank_name' => 'maybank',
'bank_branch' => 'rembau',
'company_name' => 'ICEF',
@@ -35,7 +35,9 @@ class BookTableSeeder extends Seeder
'rate_id' => $rate->id,
'user_id' => $user->id,
'status' => 2,
'admin_status' => 2,
'admin_status' => 1,
'order_no' => '001',
'payment_for' => 'FULL PAYMENT',
'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
]);
+1
View File
@@ -28,6 +28,7 @@ class DatabaseSeeder extends Seeder
$this->call(SettingActiveBankSeeder::class);
$this->call(SettingTaxRateSeeder::class);
$this->call(SettingBillingChargeSeeder::class);
$this->call(NotificationSeeder::class);
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Seeder;
use App\User;
use Carbon\Carbon;
class NotificationSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$user = User::where("email", "user@example.com")->first();
$admin = User::where("email", "admin@example.com")->first();
DB::table('notifications')->insert([
'detail' => 'This is an user seeder notification',
'user_id' => $user->id,
'link' => '/',
'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
]);
DB::table('notifications')->insert([
'detail' => 'This is an admin seeder notification',
'user_id' => $admin->id,
'link' => '/',
'created_at' => Carbon::now()->format('Y-m-d H:i:s'),
'updated_at' => Carbon::now()->format('Y-m-d H:i:s'),
]);
}
}
+14 -14
View File
@@ -132,21 +132,21 @@ class RolesAndPermissionsSeeder extends Seeder {
}
$this->command->info($commandBullet."Attached $pcount permissions to $role[name] role");
// Update old records
if ($originalRole)
{
$userCount = 0;
$RoleUsers = DB::table(Config::get('entrust.role_user_table'))->where('role_id',$originalRole->id)->get();
foreach ($RoleUsers as $user) {
$u = User::where('id',$user->user_id)->first();
$u->attachRole($newRole);
$userCount++;
}
$this->command->info($commandBullet."Updated role attachment for $userCount users");
// Update old records : Temporary disabled
// if ($originalRole)
// {
// $userCount = 0;
// $RoleUsers = DB::table(Config::get('entrust.role_user_table'))->where('role_id',$originalRole->id)->get();
// foreach ($RoleUsers as $user) {
// $u = User::where('id',$user->user_id)->first();
// $u->attachRole($newRole);
// $userCount++;
// }
// $this->command->info($commandBullet."Updated role attachment for $userCount users");
Role::where('id',$originalRole->id)->delete(); // will also remove old role_user records
$this->command->info($commandBullet."Removed the original $role[name] role");
}
// Role::where('id',$originalRole->id)->delete(); // will also remove old role_user records
// $this->command->info($commandBullet."Removed the original $role[name] role");
// }
}
+4 -4
View File
@@ -13,15 +13,15 @@ class SettingActiveBankSeeder extends Seeder
*/
public function run()
{
$bankx1 = SettingMalaysiaBank::where('acc_no', "=" ,'malaysiaacc01')->first();
$bankx2 = SettingMalaysiaBank::where('acc_no', "=",'malaysiaacc02')->first();
$chinabank = SettingBeneficiary::where('acc_no', "=" ,'123456789')->first();
$bankx1 = SettingMalaysiaBank::find(1);
$bankx2 = SettingMalaysiaBank::find(2);
$beneficiary = SettingBeneficiary::find(2);
DB::table('setting_active_banks')->truncate();
DB::table('setting_active_banks')->insert([
'x1_bank_id' => $bankx1->id,
'x2_bank_id' => $bankx2->id,
'beneficiary_id' => $chinabank->id
'beneficiary_id' => $beneficiary->id
]);
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ class SettingBeneficiarySeeder extends Seeder
'bank_branch' => 'Putra'
]);
DB::table('setting_beneficiaries')->insert([
'company_name' => 'Bota',
'company_name' => 'CIEF1',
'bank_name' => 'CIMB',
'acc_no' => '123456789',
'bank_address' => 'Jalan cyberjaya',
+3 -3
View File
@@ -13,9 +13,9 @@ class SettingCreditSeeder extends Seeder
public function run()
{
DB::table('setting_credits')->insert([
'rmb_credit_limit' => '4000',
'usd_credit_limit' => '5000',
'time_limit' => '6000'
'rmb_credit_limit' => '100000',
'usd_credit_limit' => '100000',
'time_limit' => '60000'
]);
}
}
+4 -4
View File
@@ -15,8 +15,8 @@ class SettingMalaysiaBankSeeder extends Seeder
DB::table('setting_malaysia_banks')->truncate();
DB::table('setting_malaysia_banks')->insert([
'company_name' => 'CIEF',
'bank_name' => 'Maybank',
'acc_no' => 'malaysiaacc01',
'bank_name' => 'MAYBANK',
'acc_no' => '75930284783',
'bank_address' => 'Jalan putrajaya',
'swift' => 'ABC123',
'cnap' => 'CED234',
@@ -24,8 +24,8 @@ class SettingMalaysiaBankSeeder extends Seeder
]);
DB::table('setting_malaysia_banks')->insert([
'company_name' => 'CIEF',
'bank_name' => 'Maybank',
'acc_no' => 'malaysiaacc02',
'bank_name' => 'MAYBANK',
'acc_no' => '85839298348',
'bank_address' => 'Jalan putrajaya',
'swift' => 'ABC123',
'cnap' => 'CED234',
+1 -1
View File
@@ -12,7 +12,7 @@ class SettingTaxRateSeeder extends Seeder
public function run()
{
DB::table('setting_tax_rates')->insert([
'tax_rate' => '1.1',
'tax_rate' => '1.0',
]);
}
}
+14
View File
@@ -67,5 +67,19 @@ services:
cache:
image: redis:3.0-alpine
phpmyadmin:
depends_on:
- mysql
image: phpmyadmin/phpmyadmin
restart: always
ports:
- 8090:80
environment:
PMA_HOST: mysql
MYSQL_ROOT_PASSWORD: root
networks:
- frontend
- backend
volumes:
dbdata:
+1 -2
View File
@@ -16,7 +16,7 @@
"@fortawesome/fontawesome-free-brands": "^5.0.8",
"@fortawesome/fontawesome-free-regular": "^5.0.8",
"@fortawesome/fontawesome-free-solid": "^5.0.8",
"@fortawesome/vue-fontawesome": "^0.0.22",
"@fortawesome/vue-fontawesome": "0.0.22",
"@xkeshi/vue-countdown": "^0.6.0",
"axios": "^0.18.0",
"bootstrap": "^4.0.0",
@@ -27,7 +27,6 @@
"npm": "^6.0.1",
"popper.js": "^1.14.1",
"sweetalert2": "^7.15.1",
"vee-validate": "^2.1.0-beta.5",
"vform": "^1.0.0",
"vue": "^2.5.16",
"vue-axios": "^2.1.1",
+5 -3
View File
@@ -30,10 +30,12 @@
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="DB_CONNECTION" value="testing"/>
<!-- <env name="DB_CONNECTION" value="testing"/> -->
<env name="MAIL_DRIVER" value="array"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="DB_CONNECTION" value="mysql"/>
<env name="DB_DATABASE" value="default"/>
<!-- <env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/> -->
<ini name="display_errors" value="true"/>
</php>
</phpunit>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

+7
View File
@@ -47,6 +47,13 @@ npm run hot
npm run production
```
#### Todo
- [ ] Unit test on supplier booking
- [ ] Continous delivery with npm build
- [ ] Add comments in controller functions
- [ ] Store files to AWS S3
- [ ] Real time rate update
## Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
+17 -19
View File
@@ -10,26 +10,24 @@ import locale from 'element-ui/lib/locale/lang/en'
import '~/plugins'
import '~/components'
import VeeValidate from 'vee-validate';
const config = {
errorBagName: 'errors', // change if property conflicts.
fieldsBagName: 'fields',
delay: 0,
// locale: 'zh_CN',
strict: true,
enableAutoClasses: false,
classNames: {
touched: 'touched', // the control has been blurred
untouched: 'untouched', // the control hasn't been blurred
valid: 'valid', // model is valid
invalid: 'invalid', // model is invalid
pristine: 'pristine', // control has not been interacted with
dirty: 'dirty' // control has been interacted with
},
events: 'blur',
inject: true
};
Vue.use(VeeValidate, config);
errorBagName: 'errors', // change if property conflicts.
fieldsBagName: 'fields',
delay: 0,
// locale: 'zh_CN',
strict: true,
enableAutoClasses: false,
classNames: {
touched: 'touched', // the control has been blurred
untouched: 'untouched', // the control hasn't been blurred
valid: 'valid', // model is valid
invalid: 'invalid', // model is invalid
pristine: 'pristine', // control has not been interacted with
dirty: 'dirty' // control has been interacted with
},
events: 'blur',
inject: true
}
Vue.config.productionTip = false
@@ -1,10 +1,10 @@
<template>
<el-row>
<el-steps :value="(value.term === 'x1_ba' || value.term === 'x2_cheque') && value.status > 2 ? value.status - 2 : value.status" :active="(value.term === 'x1_ba' || value.term === 'x2_cheque') && value.status > 2 ? value.status - 2 : value.status" :align-center="true" process-status="wait" finish-status="success">
<el-steps :value="value.status" :active="value.status" :align-center="true" process-status="wait" finish-status="success">
<el-step title="Booking"/>
<el-step title="Verification"/>
<el-step title="Supplier Booking" v-if="!(value.term === 'x1_ba' || value.term === 'x2_cheque')"/>
<el-step title="Supplier Report" v-if="!(value.term === 'x1_ba' || value.term === 'x2_cheque')"/>
<el-step title="Supplier Booking"/>
<el-step title="Supplier Report"/>
<el-step title="Upload China Bankslip To Booking"/>
<el-step title="Purchase Order/Invoice"/>
<el-step title="Completed"/>
@@ -33,23 +33,23 @@
{{ $t('Transaction History') }}
</router-link>
</li>
<li v-if="(user && role == 'admin')" class="nav-item">
<!-- TODO: remove entirely including controller and routes <li v-if="(user && role == 'admin')" class="nav-item">
<router-link :to="{ name: 'admin.complete' }" class="nav-link">
{{ $t('Completed Orders') }}
</router-link>
</li>
</li> -->
</ul>
<!-- update rate dialog start -->
<el-dialog align="center" :visible.sync="UpdateRateDialogVisible" width="900px">
<el-form :inline="true" align="center" ref="rate" :model="rate" :rules="rules">
<el-form-item prop="x1_cash" >X1: &nbsp;&nbsp;&nbsp;Cash : <el-input v-model.number="rate.x1_cash" style=width:25% ></el-input></el-form-item>
<el-form-item prop="x1_cheque" >Cheque : <el-input v-model.number="rate.x1_cheque" style=width:25%></el-input></el-form-item>
<el-form-item prop="x1_ba">BA : <el-input v-model.number="rate.x1_ba" style=width:25%></el-input></el-form-item>
<el-form-item prop="x1_cash" >X1: &nbsp;&nbsp;&nbsp;Cash : <el-input v-model.number="rate.x1_cash" style=width:60% ></el-input></el-form-item>
<el-form-item prop="x1_cheque" >Cheque : <el-input v-model.number="rate.x1_cheque" style=width:60%></el-input></el-form-item>
<el-form-item prop="x1_ba">BA : <el-input v-model.number="rate.x1_ba" style=width:60%></el-input></el-form-item>
<br>
<el-form-item prop="x2_cash" >X2: &nbsp;&nbsp;&nbsp;Cash : <el-input v-model.number="rate.x2_cash" style=width:25% ></el-input></el-form-item>
<el-form-item prop="x2_cheque" >Cheque : <el-input v-model.number="rate.x2_cheque" style=width:25%></el-input></el-form-item>
<el-form-item prop="x2_ba" >BA : <el-input v-model.number="rate.x2_ba" style=width:25%></el-input></el-form-item>
<el-form-item prop="x2_cash" >X2: &nbsp;&nbsp;&nbsp;Cash : <el-input v-model.number="rate.x2_cash" style=width:60% ></el-input></el-form-item>
<el-form-item prop="x2_cheque" >Cheque : <el-input v-model.number="rate.x2_cheque" style=width:60%></el-input></el-form-item>
<el-form-item prop="x2_ba" >BA : <el-input v-model.number="rate.x2_ba" style=width:60%></el-input></el-form-item>
</el-form>
<br>
<div align="center">
@@ -139,7 +139,7 @@ export default {
this.rate = response.data
})
},
createRate: function () {
createRate: function () { // TODO : we do not have create rate, only update rate. Delete this ?
this.loading = true,
this.dialogFormVisible1 = true
let newRate = {
+146 -36
View File
@@ -5,6 +5,36 @@
{{ appName }}
</router-link>
<template v-if="user">
<el-dropdown trigger="click" align="right">
<el-badge :value="bellBadge > 0 ? bellBadge : ''" class="item">
<el-button icon="el-icon-bell" circle @click="refreshNoti()"></el-button>
</el-badge>
<el-dropdown-menu slot="dropdown">
<div id="notification">
<div v-for="item in notification" :key="item">
<a v-on:click.prevent='readNotification(item.id);navigateTo(item.link)'>
<el-dropdown-item>
<b v-if="item.is_read == 0">
{{item.detail}}
</b>
<span v-else >
{{item.detail}}
</span>
<br/>
<span class="opacity80">
{{item.time_interval}}
</span>
</el-dropdown-item>
</a>
</div>
</div>
<el-button v-if="pagination.next_page_url != null" id="notification-load-more" v-on:click='fetchPaginateBooking(pagination.next_page_url)'>Load more</el-button>
<div v-else id="notification-load-more"></div>
</el-dropdown-menu>
</el-dropdown>
</template>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggler" aria-controls="navbarToggler" aria-expanded="false">
<span class="navbar-toggler-icon"/>
</button>
@@ -12,31 +42,11 @@
<div id="navbarToggler" class="collapse navbar-collapse">
<ul class="navbar-nav ml-auto">
<locale-dropdown/>
<!-- <li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li> -->
</ul>
<ul class="navbar-nav ml-auto">
<!-- Authenticated -->
<!--Authenticated -->
<template v-if="user">
<!-- <el-badge :value="12" class="item">
<el-button size="share-button"><i class="el-icon-bell"></i></el-button>
</el-badge> -->
<!-- <el-dropdown trigger="click">
<el-badge :value="12" class="item">
<el-button icon="el-icon-bell" circle></el-button>
</el-badge>
<el-dropdown-menu slot="dropdown" style="max-width: 30%" id="notification">
<a v-for="item in notification" :href="item.link">
<el-dropdown-item>
{{item.message}}
</el-dropdown-item>
</a>
</el-dropdown-menu>
</el-dropdown> -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-dark"
href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@@ -57,7 +67,6 @@
</div>
</li>
</template>
</li>
<!-- Guest -->
<template v-else>
<li class="nav-item">
@@ -80,6 +89,7 @@
<script>
import { mapGetters } from 'vuex'
import LocaleDropdown from './LocaleDropdown'
import axios from 'axios'
export default {
components: {
@@ -88,28 +98,99 @@ export default {
data: () => ({
appName: window.config.appName,
notification:[{
message : "You have an unread message",
link : "http://www.google.com"
},
{
message : "There are 10 booking for your approval",
link : "http://www.yahoo.com"
}]
notification:[],
loadingNotification:false,
bellBadge : 0,
unread_message_length:0,
url: '/api/notification/user',
pagination: [],
}),
computed: mapGetters({
user: 'auth/user'
}),
mounted(){
if(this.user){
this.getNotification(this.url)
}
},
methods: {
async logout () {
async logout(){
// Log out the user.
await this.$store.dispatch('auth/logout')
await this.$store.dispatch('auth/logout');
// Redirect to login.
this.$router.push({ name: 'login' })
this.$router.push({ name: 'login' });
},
refreshNoti() {
axios.get(this.url).then(response => {
this.bookingTable = response.data.data
this.notification = response.data.message.data;
this.bellBadge = response.data.unread_message.length;
this.makePagination(response.data.message);
console.log(response.data);
})
},
getNotification(url){
this.notification = [];
this.loadingNotification=true;
axios
.get(url)
.then((response) => {
this.loadingNotification=false;
this.notification = response.data.message.data;
this.bellBadge = response.data.unread_message.length;
this.makePagination(response.data.message);
console.log(response.data);
}).catch((error) => {
console.log(error)
this.$router.push({
name: 'notfound'
})
})
},
makePagination(data){
let pagination ={
current_page: data.current_page,
last_page: data.last_page,
next_page_url: data.next_page_url,
prev_page_url: data.prev_page_url
};
this.pagination = pagination;
},
fetchPaginateBooking(url) {
this.url = url;
this.loadingNotification=true;
if(this.url !== null){
axios
.get(url)
.then((response) => {
this.loadingNotification=false;
this.notification = this.notification.concat(response.data.message.data);
this.bellBadge = response.data.unread_message.length;
this.makePagination(response.data.message);
console.log(this.notification);
}).catch((error) => {
console.log(error)
this.$router.push({
name: 'notfound'
})
})
}
},
readNotification(notification_id){
axios
.post('/api/notification/read-notification/'+notification_id)
.then((response) => {
this.getNotification(this.url);
}).catch((error) => {
console.log(error)
this.$router.push({
name: 'notfound'
})
})
},
navigateTo(nav) {
window.location.href = nav;
}
}
}
@@ -121,4 +202,33 @@ export default {
height: 2rem;
margin: -.375rem 0;
}
.el-dropdown-menu{
height: 50%;
}
#notification{
overflow-y: scroll;
overflow-x: hidden;
max-height: 100%;
}
#notification-load-more{
position: absolute;
width: 100%;
min-height: 20px;
background: white;
border: 1px solid #dcdfe6;
}
.el-dropdown-menu__item {
line-height: 26px;
}
.opacity80{
opacity: 0.8 ;
}
::-webkit-scrollbar {
width: 0px;
background: transparent; /* make scrollbar transparent */
}
.item {
margin-top: 10px;
margin-right: 40px;
}
</style>
@@ -1,6 +1,6 @@
<template>
<el-row>
<el-steps class="progressBar" :value="value" :active="value" :align-center="true" process-status="wait" finish-status="success">
<el-steps class="progressBar" :value="value.status" :active="value.status" :align-center="true" process-status="wait" finish-status="success">
<el-step title="Booking"/>
<el-step title="Payment"/>
<el-step title="Order Confirmation"/>
@@ -19,32 +19,12 @@
}
}
/*
.el-steps {
padding-top: 70px;
}
.el-step .el-step__main {
transform: translateY(-70px);
}
.el-step__title.is-wait {
font-size: 10pt;
}
.el-step__title {
line-height: 1.4;
}
.el-step .is-success .el-step__line {
background-color: #67c23a;
} */
</style>
<script>
export default {
props: ['value'],
data: () => ({
status: 1
})
}
</script>
@@ -0,0 +1,44 @@
<template>
<el-row>
<el-steps :value="value.status" :active="value.status" :align-center="true" process-status="wait" finish-status="success">
<el-step title="Booking"/>
<el-step title="Verification"/>
<el-step title="Supplier Booking"/>
<el-step title="Supplier Report"/>
<el-step title="Upload China Bankslip To Booking"/>
<el-step title="Completed"/>
</el-steps>
</el-row>
</template>
<style type="text/css">
/* .el-row {
margin: 20px 0;
}
.el-steps {
padding-top: 70px;
}
.el-step .el-step__main {
transform: translateY(-70px);
}
.el-step__title.is-wait {
font-size: 10pt;
}
.el-step__title {
line-height: 1.4;
}
.el-step .is-success .el-step__line {
background-color: #67c23a;
} */
</style>
<script>
export default {
props: ['value'],
data: () => ({
})
}
</script>
@@ -0,0 +1,27 @@
<template>
<el-row>
<el-steps class="progressBar" :value="value.status" :active="value.status" :align-center="true" process-status="wait" finish-status="success">
<el-step title="Booking"/>
<el-step title="Payment"/>
<el-step title="Order Confirmation"/>
<el-step title="Order Complete"/>
</el-steps>
</el-row>
</template>
<style type="text/css">
@media screen and (max-width: 800px) {
.progressBar {
width: 60%;
}
}
</style>
<script>
export default {
props: ['value'],
data: () => ({
})
}
</script>
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="trackerConfig" />
<x2-progress-track v-if="(booking_details.admin_status == 'x2_cash' || booking_details.admin_status == 'x2_cheque' || booking_details.admin_status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center">
<h4 style="margin-top:5%;"></h4>
@@ -28,7 +29,7 @@
<tbody>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Order Number :</div>
<div class="cell">Ref No :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.id }}</div>
@@ -211,11 +212,13 @@
</style>
<script>
import ProgressTrack from '~/components/AdminProgressTrack'
import X2ProgressTrack from '~/components/X2AdminProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data() {
return {
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="trackerConfig"/>
<x2-progress-track v-if="(booking_details.admin_status == 'x2_cash' || booking_details.admin_status == 'x2_cheque' || booking_details.admin_status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center">
<h4 style="margin-top:5%;">Order Completed</h4>
@@ -37,7 +38,7 @@
</div>
<el-row :gutter="12" type="flex">
<el-col :span="12" align="center">
<div v-for="cn_bankslip in booking_details.china_bankslip_path">
<div v-for="cn_bankslip in booking_details.china_bankslip_path" :key='cn_bankslip'>
<a target="_blank" :href="getURL(cn_bankslip)">
<img v-if="isImage(cn_bankslip)" v-bind:src="cn_bankslip" class="image">
<p v-else>Download</p>
@@ -66,7 +67,7 @@
</el-col>
</el-row>
<br>
<!-- bank slips END -->
<!-- bank slips END -->
<el-row justify="center" align="center">
<el-card class="box-card">
@@ -91,7 +92,7 @@
<div class="el-row" style="margin-left: -6px; margin-right: -6px;">
<div class="el-col el-col-12" style="padding-left: 6px; padding-right: 6px;">
<div class="el-table el-table--fit el-table--enable-row-hover el-table--enable-row-transition" align="center">
<div class="el-table__body-wrapper is-scrolling-none">
<table class="el-table__body" style="width: 400px;" cellspacing="0" cellpadding="0" border="0">
<colgroup>
@@ -101,7 +102,7 @@
<tbody>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Order Number :</div>
<div class="cell">Ref No :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.id }}</div>
@@ -219,7 +220,9 @@
<div class="cell"></div>
</td>
<td class="el-table_3_column_12 is-left ">
<div class="cell"><b>MYR {{ booking_details.bia }}</b></div>
<div class="cell">
<b>MYR {{ booking_details.bia }}</b>
</div>
</td>
</tr>
<tr class="el-table__row">
@@ -261,7 +264,37 @@
</el-card>
</el-row>
<br>
<el-row justify="center" align="center">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Supplier Report</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12" style="text-align:center">
<el-col :span="20" style="text-align:center">
<canvas id="myCanvas" ref="myCanvas" v-insert-message="supplier_booking"></canvas>
<br>
<el-button @click="downloadReport()" type="text">Download Now</el-button>
</el-col>
</el-row>
</el-card>
<br>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>User BankinSlip</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12">
<el-col :span="22" style="text-align:center">
<a target="_blank" :href="getURL(booking_details.user_bankslip_path)">
<img v-if="isImage(booking_details.user_bankslip_path)" v-bind:src="booking_details.user_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</el-col>
</el-row>
</el-card>
</el-row>
<br>
<el-row justify="center" align="center">
<el-card class="box-card">
<div slot="header" class="clearfix">
@@ -284,77 +317,269 @@
.booking-details {
font-weight: bold;
}
.image {
border: 1px solid #ddd;
border-radius: 4px;
margin-left: auto;
margin-right: auto;
width: 150px;
display: block;
border: 1px solid #ddd;
border-radius: 4px;
margin-left: auto;
margin-right: auto;
width: 150px;
display: block;
}
.image:hover {
box-shadow: 0 0 2px 1px rgba(0, 140, 186, 0.5);
}
</style>
<script>
import VueCountdown from '@dmaksimovic/vue-countdown'
import ProgressTrack from '~/components/AdminProgressTrack'
import axios from 'axios'
import ProgressTrack from '~/components/AdminProgressTrack'
import X2ProgressTrack from '~/components/X2AdminProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
},
data () {
return {
trackerConfig :{
export default {
components: {
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data() {
return {
trackerConfig: {
status: 8,
term: null
},
loading_btn: false,
booking_details:{
supplier_booking:{},
loading_btn: false,
booking_details: {
id: null,
amount: null,
bia: null,
user_bankslip_path: null,
}
}
},
beforeCreate () {
const loading = this.$loading({
lock: true,
text: 'Please wait..',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
axios
.get('/api/admin/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term;
loading.close()
}).catch((error) => {
console.log(error)
loading.close()
this.$router.push({
name: 'notfound'
})
}
},
beforeCreate() {
const loading = this.$loading({
lock: true,
text: 'Please wait..',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
},
methods: {
getExtension(path){
return path.slice(-3);
axios
.get('/api/admin/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term;
loading.close()
}).catch((error) => {
console.log(error)
loading.close()
this.$router.push({
name: 'notfound'
})
})
axios.get('/api/supplier-booking/' + this.$route.params.id)
.then((response) => {
this.supplier_booking = response.data
loading.close()
}).catch((error) => {
console.log(error)
this.$router.push({
name: 'notfound'
})
loading.close()
})
},
isImage(path){
var ext = this.getExtension(path);
return ext === 'jpg' || ext === 'jpeg' || ext === 'bmp' || ext === 'png';
methods: {
getExtension(path) {
return path.slice(-3);
},
isImage(path) {
var ext = this.getExtension(path);
return ext === 'jpg' || ext === 'jpeg' || ext === 'bmp' || ext === 'png';
},
getURL(path) {
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
return baseUrl + path;
}
},
getURL(path){
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
return baseUrl + path;
directives: {
insertMessage: function (canvasElement, binding) {
setTimeout(function (canvasElement, binding) {
////////////////// variable //////////////////////////
var canvasWidth = 450;
var rowHeight = [20, 40, 60, 80, 100, 120, 140, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350, 390,
410,
470, 490, 510, 610, 630
]
const canvasHeight = rowHeight[rowHeight.length - 1];
var column1X = 220;
var column2X = 320;
var column3X = 420;
///////////////////Canvast Init////////////////////
var canvas = document.getElementById("myCanvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// Get canvas context
var ctx = canvasElement.getContext("2d");
// Clear the canvas
ctx.clearRect(0, 0, 300, 150);
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, 0, canvasWidth, rowHeight[0]);
for (var i = 1; i < rowHeight.length; i++) {
if (i % 2 == 1)
ctx.fillStyle = "#A9D08E";
else
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, rowHeight[i - 1], canvasWidth, rowHeight[i]);
}
///////////// fillup with text////////////////
//// config canvas
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
ctx.textAlign = "right";
//// Row 1
ctx.fillText("Ref No. :", column1X, rowHeight[1] - 5);
ctx.fillText(binding.value.booking_id, column3X, rowHeight[1] - 5);
//// Row 2
ctx.fillText("Date :", column1X, rowHeight[2] - 5);
ctx.fillText(binding.value.date, column3X, rowHeight[2] - 5);
//// Row 3
ctx.fillText("Marking :", column1X, rowHeight[3] - 5);
ctx.font = "bold 14px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText(binding.value.marking, column3X, rowHeight[3] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 4
ctx.fillText("Payment For(Order No.) :", column1X, rowHeight[4] - 5);
ctx.fillText(binding.value.order_no, column3X, rowHeight[4] - 5);
//// Row 4
ctx.fillText("Payment For :", column1X, rowHeight[5] - 5);
ctx.fillText(binding.value.payment_for, column3X, rowHeight[5] - 5);
//// Row 5
ctx.fillText("Payment Method :", column1X, rowHeight[6] - 5);
ctx.fillText(binding.value.payment_method, column3X, rowHeight[6] - 5);
//// Row 6
ctx.fillText("Remark :", column1X, rowHeight[7] - 10);
//// Row 7
// Empty
//// Row 8
ctx.fillText("MYR/RM :", column1X, rowHeight[9] - 5);
ctx.fillText("MYR", column2X, rowHeight[9] - 5);
ctx.font = "bold 14px Arial";
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[9] - 5);
ctx.font = "13px Arial";
//// Row 8
ctx.fillText("* RATE :", column1X, rowHeight[10] - 5);
ctx.fillText(binding.value.rate, column3X, rowHeight[10] - 5);
//// Row 9
ctx.fillText("REBATE :", column1X, rowHeight[11] - 5);
ctx.fillText("MYR", column2X, rowHeight[11] - 5);
ctx.font = "14px Arial";
ctx.fillText(binding.value.rebate, column3X, rowHeight[11] - 5);
ctx.font = "13px Arial";
//// Row 10
ctx.font = "bold 14px Arial";
ctx.fillText("CNY", column2X, rowHeight[12] - 5);
ctx.fillText(binding.value.amountInRMB, column3X, rowHeight[12] - 5);
ctx.font = "13px Arial";
//line
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo(column1X + 30, rowHeight[11]);
ctx.lineTo(column3X + 20, rowHeight[11]);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(column1X + 30, rowHeight[12]);
ctx.lineTo(column3X + 20, rowHeight[12]);
ctx.stroke();
//// Row 11
ctx.fillText("MYR/RM :", column1X, rowHeight[14] - 5);
ctx.fillText("MYR", column2X, rowHeight[14] - 5);
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[14] - 5);
//// Row 12
// ctx.fillText("Billing(1.0%) :", column1X, rowHeight[15] - 5);
// ctx.fillText("MYR", column2X, rowHeight[15] - 5);
// ctx.fillText(binding.value.billing_amount, column3X, rowHeight[15] - 5);
//// Row 13
ctx.fillText("+ TAX " + (Math.round((binding.value.tax_rate * 100 - 100) * 100) / 100) + "% :",
column1X, rowHeight[16] - 5); // TODO : Change to percentage
ctx.fillText("MYR", column2X, rowHeight[16] - 5);
ctx.fillText(binding.value.salestax_amount, column3X, rowHeight[16] - 5);
// //// Row 14
// ctx.fillText("+ GST 6% :", column1X, rowHeight[17] - 15);
// ctx.fillText("MYR", column2X, rowHeight[17] - 15);
// ctx.fillText("289.84", column3X, rowHeight[17] - 15);
//// Row 15
ctx.font = "bold 14px Arial";
ctx.fillText("Bank In Amount :", column1X, rowHeight[18] - 5);
ctx.fillStyle = "#0070D5";
ctx.fillText("MYR", column2X, rowHeight[18] - 5);
ctx.fillText(binding.value.amount_after_tax, column3X, rowHeight[18] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//line
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[17]);
ctx.lineTo(column3X + 20, rowHeight[17]);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[18] + 1);
ctx.lineTo(column3X + 20, rowHeight[18] + 1);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[18] - 2);
ctx.lineTo(column3X + 20, rowHeight[18] - 2);
ctx.stroke();
//// Row 16
// ctx.fillText("Rebate :", column1X, rowHeight[19] - 25);
// ctx.fillText("CNY", column2X, rowHeight[19] - 25);
// ctx.fillText("224.68", column3X, rowHeight[19] - 25);
//// Row 16
ctx.font = "bold 14px Arial";
ctx.fillText("Bank In to Account Below :", column1X, rowHeight[20] - 5);
ctx.font = "bold italic 15px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText("CNY", column2X, rowHeight[20] - 5);
ctx.fillText(binding.value.amountInRMB, column3X - 20, rowHeight[20] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 17
//// Row 18
//// Row 19
// var img = new Image();
// img.src = "/banklogo.png";
// img.crossOrigin = "anonymous";
// var maxwidth = 70;
// var ratio = maxwidth / img.width;
// var offset = ((rowHeight[22] - rowHeight[21]) / 2) - (img.height * ratio / 2);
// var y = rowHeight[21] + offset; // to make it always center
// img.onload=function(){
// ctx.drawImage(img, 50, 530, 80, 50);
// };
// text
ctx.font = "bold 14px Arial";
ctx.textAlign = "center";
ctx.fillText("China beneficiary Account", column2X - 40, rowHeight[22] - 80);
ctx.fillText("户名 : " + binding.value.acc_name, column2X - 40, rowHeight[22] - 60);
ctx.fillText(binding.value.acc_no, column2X - 40, rowHeight[22] - 40);
ctx.fillText(binding.value.bank_name, column2X - 40, rowHeight[22] - 20);
ctx.fillText(binding.value.bank_branch, column2X - 40, rowHeight[22] - 2);
ctx.font = "13px Arial";
}, 1000, canvasElement, binding);
}
}
}
}
</script>
</script>
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="trackerConfig" />
<x2-progress-track v-if="(booking_details.admin_status == 'x2_cash' || booking_details.admin_status == 'x2_cheque' || booking_details.admin_status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center">
<h4 style="margin-top:5%;"></h4>
@@ -29,7 +30,7 @@
<tbody>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Order Number :</div>
<div class="cell">Ref No :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.id }}</div>
@@ -216,9 +217,9 @@
<el-form-item prop="rebate">
<el-input v-model="supplierBookingForm.rebate" type="text" placeholder="Rebate" style="width: 80%" />
</el-form-item>
<el-form-item prop="transfer_amount">
<!-- <el-form-item prop="transfer_amount">
<el-input v-model="supplierBookingForm.transfer_amount" type="text" placeholder="Payment Amount" style="width: 80%" />
</el-form-item>
</el-form-item> -->
<el-form-item>
<el-button :loading="loading_btn" type="primary" @click="generateReport('supplierBookingForm')">Generate Report</el-button>
</el-form-item>
@@ -237,11 +238,13 @@
</style>
<script>
import ProgressTrack from '~/components/AdminProgressTrack'
import X2ProgressTrack from '~/components/X2AdminProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data() {
return {
@@ -260,7 +263,6 @@
supplier_options: null,
supplierBookingForm: {
supplier: null,
amount: null,
rebate: null,
rate: null,
transfer_amount: null,
@@ -333,10 +335,9 @@
let newReport = {
booking_id: this.$route.params.id,
supplier_id: this.supplierBookingForm.supplier,
amount: this.supplierBookingForm.amount,
rebate: this.supplierBookingForm.rebate,
rate: this.supplierBookingForm.rate,
transfer_amount: this.supplierBookingForm.transfer_amount,
//transfer_amount: this.supplierBookingForm.transfer_amount,
}
axios.post('/api/supplier-booking', newReport)
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="trackerConfig" />
<x2-progress-track v-if="(booking_details.admin_status == 'x2_cash' || booking_details.admin_status == 'x2_cheque' || booking_details.admin_status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center">
<h4 style="margin-top:5%;"></h4>
@@ -29,7 +30,7 @@
<tbody>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Order Number :</div>
<div class="cell">Ref No :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.id }}</div>
@@ -201,7 +202,6 @@
<el-row :gutter="12" style="text-align:center">
<el-col :span="20" style="text-align:center">
<canvas id="myCanvas" ref="myCanvas" v-insert-message="supplier_booking"></canvas>
<img id="banklogo" src="/banklogo.png" style="display: none"/>
<br>
<el-button @click="downloadReport()" type="text">Download Now</el-button>
</el-col>
@@ -253,11 +253,12 @@
<script>
import ProgressTrack from '~/components/AdminProgressTrack'
import axios from 'axios'
import Canvas2Image from 'canvas2image'
import X2ProgressTrack from '~/components/X2AdminProgressTrack'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data() {
return {
@@ -313,43 +314,14 @@
axios.get('/api/supplier-booking/' + this.$route.params.id)
.then((response) => {
this.supplier_booking = response.data
loading.close()
}).catch((error) => {
console.log(error)
this.$router.push({
name: 'notfound'
})
loading.close()
})
axios.get('/api/active-bank')
.then((response) => {
axios.get('/api/setting-beneficiary/' + response.data.beneficiary_id)
.then((response) => {
loading.close();
this.supplier_booking.china_bank_name = response.data.bank_name;
this.supplier_booking.china_company_name = response.data.company_name;
this.supplier_booking.china_acc_no = response.data.acc_no;
})
.catch((error) => {
loading.close();
console.log(error);
this.$message({
showClose: true,
message: 'Fetch data fail',
type: 'error',
duration: 10000
});
});
})
.catch((error) => {
loading.close();
console.log(error);
this.$message({
showClose: true,
message: 'Fetch data fail',
type: 'error',
duration: 10000
});
});
},
methods: {
downloadReport(){
@@ -451,8 +423,8 @@
ctx.font = "13px Arial";
ctx.textAlign = "right";
//// Row 1
ctx.fillText("Payment Voucher :", column1X, rowHeight[1] - 5);
ctx.fillText(binding.value.id, column3X, rowHeight[1] - 5);
ctx.fillText("Ref No. :", column1X, rowHeight[1] - 5);
ctx.fillText(binding.value.booking_id, column3X, rowHeight[1] - 5);
//// Row 2
ctx.fillText("Date :", column1X, rowHeight[2] - 5);
ctx.fillText(binding.value.date, column3X, rowHeight[2] - 5);
@@ -460,15 +432,15 @@
ctx.fillText("Marking :", column1X, rowHeight[3] - 5);
ctx.font = "bold 14px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText("CIEF/605HOS", column3X, rowHeight[3] - 5);
ctx.fillText(binding.value.marking, column3X, rowHeight[3] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 4
ctx.fillText("Payment For(Order No.) :", column1X, rowHeight[4] - 5);
ctx.fillText(binding.value.id, column3X, rowHeight[4] - 5);
ctx.fillText(binding.value.order_no, column3X, rowHeight[4] - 5);
//// Row 4
ctx.fillText("Payment For :", column1X, rowHeight[5] - 5);
ctx.fillText("Full Payment", column3X, rowHeight[5] - 5);
ctx.fillText(binding.value.payment_for, column3X, rowHeight[5] - 5);
//// Row 5
ctx.fillText("Payment Method :", column1X, rowHeight[6] - 5);
ctx.fillText(binding.value.payment_method, column3X, rowHeight[6] - 5);
@@ -480,13 +452,17 @@
ctx.fillText("MYR/RM :", column1X, rowHeight[9] - 5);
ctx.fillText("MYR", column2X, rowHeight[9] - 5);
ctx.font = "bold 14px Arial";
ctx.fillText(binding.value.transfer_amount, column3X, rowHeight[9] - 5);
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[9] - 5);
ctx.font = "13px Arial";
//// Row 8
ctx.fillText("* RATE :", column1X, rowHeight[10] - 5);
ctx.fillText(binding.value.rate, column3X, rowHeight[10] - 5);
//// Row 9
// Empty
ctx.fillText("REBATE :", column1X, rowHeight[11] - 5);
ctx.fillText("MYR", column2X, rowHeight[11] - 5);
ctx.font = "14px Arial";
ctx.fillText(binding.value.rebate, column3X, rowHeight[11] - 5);
ctx.font = "13px Arial";
//// Row 10
ctx.font = "bold 14px Arial";
ctx.fillText("CNY", column2X, rowHeight[12] - 5);
@@ -506,25 +482,26 @@
//// Row 11
ctx.fillText("MYR/RM :", column1X, rowHeight[14] - 5);
ctx.fillText("MYR", column2X, rowHeight[14] - 5);
ctx.fillText("4830.68", column3X, rowHeight[14] - 5);
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[14] - 5);
//// Row 12
ctx.fillText("Billing(1.0%) :", column1X, rowHeight[15] - 5);
ctx.fillText("MYR", column2X, rowHeight[15] - 5);
ctx.fillText(binding.value.billing_amount, column3X, rowHeight[15] - 5);
// ctx.fillText("Billing(1.0%) :", column1X, rowHeight[15] - 5);
// ctx.fillText("MYR", column2X, rowHeight[15] - 5);
// ctx.fillText(binding.value.billing_amount, column3X, rowHeight[15] - 5);
//// Row 13
ctx.fillText("+ SALES TAX (10%) :", column1X, rowHeight[16] - 5);
ctx.fillText("+ TAX "+ (Math.round((binding.value.tax_rate * 100 - 100) * 100) / 100) + "% :", column1X, rowHeight[16] - 5); // TODO : Change to percentage
ctx.fillText("MYR", column2X, rowHeight[16] - 5);
ctx.fillText(binding.value.salestax_amount, column3X, rowHeight[16] - 5);
//// Row 14
ctx.fillText("+ GST 6% :", column1X, rowHeight[17] - 15);
ctx.fillText("MYR", column2X, rowHeight[17] - 15);
ctx.fillText("289.84", column3X, rowHeight[17] - 15);
// //// Row 14
// ctx.fillText("+ GST 6% :", column1X, rowHeight[17] - 15);
// ctx.fillText("MYR", column2X, rowHeight[17] - 15);
// ctx.fillText("289.84", column3X, rowHeight[17] - 15);
//// Row 15
ctx.font = "bold 14px Arial";
ctx.fillText("Customer Bank In Amount :", column1X, rowHeight[18] - 5);
ctx.fillText("Bank In Amount :", column1X, rowHeight[18] - 5);
ctx.fillStyle = "#0070D5";
ctx.fillText("MYR", column2X, rowHeight[18] - 5);
ctx.fillText(binding.value.amountInRMB, column3X, rowHeight[18] - 5);
ctx.fillText(binding.value.amount_after_tax, column3X, rowHeight[18] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//line
@@ -542,40 +519,41 @@
ctx.lineTo(column3X + 20, rowHeight[18] - 2);
ctx.stroke();
//// Row 16
ctx.fillText("Rebate :", column1X, rowHeight[19] - 25);
ctx.fillText("CNY", column2X, rowHeight[19] - 25);
ctx.fillText("224.68", column3X, rowHeight[19] - 25);
// ctx.fillText("Rebate :", column1X, rowHeight[19] - 25);
// ctx.fillText("CNY", column2X, rowHeight[19] - 25);
// ctx.fillText("224.68", column3X, rowHeight[19] - 25);
//// Row 16
ctx.font = "bold 14px Arial";
ctx.fillText("Bank In to Account Below :", column1X, rowHeight[20] - 5);
ctx.font = "bold italic 15px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText("CNY", column2X, rowHeight[20] - 5);
ctx.fillText("7692.17", column3X - 20, rowHeight[20] - 5);
ctx.fillText(binding.value.amountInRMB, column3X - 20, rowHeight[20] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 17
//// Row 18
//// Row 19
var img = new Image();
img.src = "/banklogo.png";
img.crossOrigin = "anonymous";
var maxwidth = 70;
var ratio = maxwidth / img.width;
var offset = ((rowHeight[22] - rowHeight[21]) / 2) - (img.height * ratio / 2);
var y = rowHeight[21] + offset; // to make it always center
// var img = new Image();
// img.src = "/banklogo.png";
// img.crossOrigin = "anonymous";
// var maxwidth = 70;
// var ratio = maxwidth / img.width;
// var offset = ((rowHeight[22] - rowHeight[21]) / 2) - (img.height * ratio / 2);
// var y = rowHeight[21] + offset; // to make it always center
img.onload=function(){
ctx.drawImage(img, 50, 530, 80, 50);
};
// img.onload=function(){
// ctx.drawImage(img, 50, 530, 80, 50);
// };
// text
ctx.font = "bold 14px Arial";
ctx.textAlign = "center";
ctx.fillText("China beneficiary Account", column2X - 40, rowHeight[22] - 80);
ctx.fillText("户名 : " + binding.value.china_company_name, column2X - 40, rowHeight[22] - 60);
ctx.fillText(binding.value.china_acc_no, column2X - 40, rowHeight[22] - 40);
ctx.fillText(binding.value.china_bank_name , column2X - 40, rowHeight[22] - 20);
ctx.fillText("户名 : " + binding.value.acc_name, column2X - 40, rowHeight[22] - 60);
ctx.fillText(binding.value.acc_no, column2X - 40, rowHeight[22] - 40);
ctx.fillText(binding.value.bank_name , column2X - 40, rowHeight[22] - 20);
ctx.fillText(binding.value.bank_branch , column2X - 40, rowHeight[22] - 2);
ctx.font = "13px Arial";
}, 1000,canvasElement,binding);
@@ -1,6 +1,8 @@
<template>
<el-main>
<progress-track v-model="trackerConfig" />
<x2-progress-track v-if="(booking_details.admin_status == 'x2_cash' || booking_details.admin_status == 'x2_cheque' || booking_details.admin_status == 'x2_ba')"
v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center">
<h4 style="margin-top:5%;"></h4>
@@ -9,6 +11,49 @@
<br>
<!-- <el-button type="primary" @click="$router.go(-1)">Go Back</el-button> -->
</div>
<br>
<el-row justify="center" align="center">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Upload China Bankslip</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12" style="text-align:center">
<el-col :span="20" style="text-align:center">
<el-form ref="chinaSlipForm" :model="chinaSlipForm" :rules="rules">
<div align="center">
<!-- upload image -->
<el-upload class="upload-demo" :action="'/api/booking/' + booking_id + '/upload-china-bankslip'" :on-preview="handlePreview"
:on-error="uploadError" accept=".jpeg, .jpg, .png, .bmp, .doc, .docx, .xls, .xlsx, .pdf" :on-remove="handleRemove"
:multiple="false" list-type="picture">
<el-button size="small" type="primary">Click to upload</el-button>
<div slot="tip" class="el-upload__tip">bmp/jpeg/jpg/png/pdf/xls/xlxs/doc/docx files with a size less than 3MB</div>
</el-upload>
<br>
<!-- upload image end -->
<!-- <el-form-item prop="date">
<el-date-picker v-model="chinaSlipForm.date" type="date" placeholder="Pick a day" :picker-options="pickerOptions1">
</el-date-picker>
</el-form-item> -->
<el-form-item prop="actual_transfer_amount">
<el-input v-model.number="chinaSlipForm.actual_transfer_amount" type="text" placeholder="Amount" style="width: 80%" />
</el-form-item>
<el-form-item prop="details">
<el-input v-model="chinaSlipForm.details" type="text" placeholder="Details" style="width: 80%" />
</el-form-item>
<el-form-item>
<el-button :loading="loading_btn" type="primary" @click="submitChinaSlip('chinaSlipForm')">Submit</el-button>
</el-form-item>
</div>
</el-form>
</el-col>
</el-row>
</el-card>
</el-row>
<br>
<el-row justify="center" align="center">
<el-card class="box-card">
@@ -29,7 +74,7 @@
<tbody>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Order Number :</div>
<div class="cell">Ref No :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.id }}</div>
@@ -166,72 +211,40 @@
<!---->
<!---->
</div>
<!---->
<!---->
<!---->
<!---->
<div class="el-table__column-resize-proxy" style="display: none;"></div>
</div>
</div>
</div>
<!-- <el-row :gutter="12">
<el-col :span="12">
<el-table :data="bookingConfirmTable" :show-header="false" align="center">
<el-table-column prop="data1" align="right" width="200" />
<el-table-column prop="data2" align="left" width="200" />
</el-table>
</el-col>
<el-col :span="12">
<el-table :data="bookingConfirmTable2" :show-header="false" align="center">
<el-table-column prop="data1" align="right" width="200" />
<el-table-column prop="data2" align="left" width="200" />
</el-table>
</el-col>
</el-row> -->
</el-card>
</el-row>
<br>
<br>
<el-row justify="center" align="center">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Upload China Bankslip</span>
<span>Supplier Report</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12" style="text-align:center">
<el-col :span="20" style="text-align:center">
<el-form ref="chinaSlipForm" :model="chinaSlipForm" :rules="rules">
<div align="center">
<!-- upload image -->
<el-upload class="upload-demo" :action="'/api/booking/' + booking_id + '/upload-china-bankslip'"
:on-preview="handlePreview"
:on-error="uploadError"
accept=".jpeg, .jpg, .png, .bmp, .doc, .docx, .xls, .xlsx, .pdf"
:on-remove="handleRemove" :multiple="false" list-type="picture">
<el-button size="small" type="primary">Click to upload</el-button>
<div slot="tip" class="el-upload__tip">bmp/jpeg/jpg/png/pdf/xls/xlxs/doc/docx files with a size less than 3MB</div>
</el-upload>
<br>
<!-- upload image end -->
<!-- <el-form-item prop="date">
<el-date-picker v-model="chinaSlipForm.date" type="date" placeholder="Pick a day" :picker-options="pickerOptions1">
</el-date-picker>
</el-form-item> -->
<el-form-item prop="actual_transfer_amount">
<el-input v-model="chinaSlipForm.actual_transfer_amount" type="text" placeholder="Amount" style="width: 80%" />
</el-form-item>
<el-form-item prop="details">
<el-input v-model="chinaSlipForm.details" type="text" placeholder="Details" style="width: 80%" />
</el-form-item>
<el-form-item>
<el-button :loading="loading_btn" type="primary" @click="submitChinaSlip('chinaSlipForm')">Submit</el-button>
</el-form-item>
</div>
</el-form>
<canvas id="myCanvas" ref="myCanvas" v-insert-message="supplier_booking"></canvas>
<br>
<el-button @click="downloadReport()" type="text">Download Now</el-button>
</el-col>
</el-row>
</el-card>
<br>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>User BankinSlip</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12">
<el-col :span="22" style="text-align:center">
<a target="_blank" :href="getURL(booking_details.user_bankslip_path)">
<img v-if="isImage(booking_details.user_bankslip_path)" v-bind:src="booking_details.user_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</el-col>
</el-row>
</el-card>
@@ -245,15 +258,17 @@
</style>
<script>
import ProgressTrack from '~/components/AdminProgressTrack'
import X2ProgressTrack from '~/components/X2AdminProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data() {
return {
trackerConfig :{
trackerConfig: {
status: 5,
term: null
},
@@ -266,6 +281,7 @@
user_bankslip_path: null,
},
supplier: null,
supplier_booking: {},
supplier_options: null,
chinaSlipForm: {
actual_transfer_amount: null,
@@ -274,10 +290,16 @@
},
rules: {
actual_transfer_amount: [{
required: true,
message: 'Please input transfer amount',
trigger: 'change'
}],
required: true,
message: 'Please input amount',
trigger: 'change'
},
{
type: 'number',
message: 'Amount must be a number',
trigger: 'change'
}
],
// date: [{
// required: true,
// message: 'Please input date',
@@ -326,7 +348,7 @@
axios
.get('/api/admin/booking/' + this.$route.params.id)
.then((response) => {
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term;
loading.close()
@@ -337,6 +359,18 @@
name: 'notfound'
})
})
axios.get('/api/supplier-booking/' + this.$route.params.id)
.then((response) => {
this.supplier_booking = response.data
loading.close()
}).catch((error) => {
console.log(error)
this.$router.push({
name: 'notfound'
})
loading.close()
})
},
methods: {
submitChinaSlip(formName) {
@@ -350,7 +384,7 @@
details: this.chinaSlipForm.details,
}
axios.patch('/api/booking/' + this.booking_id +'/update-china-bankslip', newChinaSlip)
axios.patch('/api/booking/' + this.booking_id + '/update-china-bankslip', newChinaSlip)
.then((response) => {
this.$message({
showClose: true,
@@ -376,11 +410,11 @@
} else {
this.loading_btn = false
this.$message({
showClose: true,
message: 'Please upload your bankin slip first.',
type: 'warning',
duration: 10000
})
showClose: true,
message: 'Please upload your bankin slip first.',
type: 'warning',
duration: 10000
})
}
})
},
@@ -390,8 +424,197 @@
handlePreview(file) {
console.log(file);
},
uploadError(file,fileList){
uploadError(file, fileList) {
this.$message.warning(`Incorrect file format or file size too big.`)
},
getExtension(path){
return path.slice(-3);
},
isImage(path){
var ext = this.getExtension(path);
return ext === 'jpg' || ext === 'jpeg' || ext === 'bmp' || ext === 'png';
},
getURL(path){
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
return baseUrl + path;
}
},
directives: {
insertMessage: function (canvasElement, binding) {
setTimeout(function (canvasElement, binding) {
////////////////// variable //////////////////////////
var canvasWidth = 450;
var rowHeight = [20, 40, 60, 80, 100, 120, 140, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350, 390,
410,
470, 490, 510, 610, 630
]
const canvasHeight = rowHeight[rowHeight.length - 1];
var column1X = 220;
var column2X = 320;
var column3X = 420;
///////////////////Canvast Init////////////////////
var canvas = document.getElementById("myCanvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// Get canvas context
var ctx = canvasElement.getContext("2d");
// Clear the canvas
ctx.clearRect(0, 0, 300, 150);
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, 0, canvasWidth, rowHeight[0]);
for (var i = 1; i < rowHeight.length; i++) {
if (i % 2 == 1)
ctx.fillStyle = "#A9D08E";
else
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, rowHeight[i - 1], canvasWidth, rowHeight[i]);
}
///////////// fillup with text////////////////
//// config canvas
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
ctx.textAlign = "right";
//// Row 1
ctx.fillText("Ref No. :", column1X, rowHeight[1] - 5);
ctx.fillText(binding.value.booking_id, column3X, rowHeight[1] - 5);
//// Row 2
ctx.fillText("Date :", column1X, rowHeight[2] - 5);
ctx.fillText(binding.value.date, column3X, rowHeight[2] - 5);
//// Row 3
ctx.fillText("Marking :", column1X, rowHeight[3] - 5);
ctx.font = "bold 14px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText(binding.value.marking, column3X, rowHeight[3] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 4
ctx.fillText("Payment For(Order No.) :", column1X, rowHeight[4] - 5);
ctx.fillText(binding.value.order_no, column3X, rowHeight[4] - 5);
//// Row 4
ctx.fillText("Payment For :", column1X, rowHeight[5] - 5);
ctx.fillText(binding.value.payment_for, column3X, rowHeight[5] - 5);
//// Row 5
ctx.fillText("Payment Method :", column1X, rowHeight[6] - 5);
ctx.fillText(binding.value.payment_method, column3X, rowHeight[6] - 5);
//// Row 6
ctx.fillText("Remark :", column1X, rowHeight[7] - 10);
//// Row 7
// Empty
//// Row 8
ctx.fillText("MYR/RM :", column1X, rowHeight[9] - 5);
ctx.fillText("MYR", column2X, rowHeight[9] - 5);
ctx.font = "bold 14px Arial";
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[9] - 5);
ctx.font = "13px Arial";
//// Row 8
ctx.fillText("* RATE :", column1X, rowHeight[10] - 5);
ctx.fillText(binding.value.rate, column3X, rowHeight[10] - 5);
//// Row 9
ctx.fillText("REBATE :", column1X, rowHeight[11] - 5);
ctx.fillText("MYR", column2X, rowHeight[11] - 5);
ctx.font = "14px Arial";
ctx.fillText(binding.value.rebate, column3X, rowHeight[11] - 5);
ctx.font = "13px Arial";
//// Row 10
ctx.font = "bold 14px Arial";
ctx.fillText("CNY", column2X, rowHeight[12] - 5);
ctx.fillText(binding.value.amountInRMB, column3X, rowHeight[12] - 5);
ctx.font = "13px Arial";
//line
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo(column1X + 30, rowHeight[11]);
ctx.lineTo(column3X + 20, rowHeight[11]);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(column1X + 30, rowHeight[12]);
ctx.lineTo(column3X + 20, rowHeight[12]);
ctx.stroke();
//// Row 11
ctx.fillText("MYR/RM :", column1X, rowHeight[14] - 5);
ctx.fillText("MYR", column2X, rowHeight[14] - 5);
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[14] - 5);
//// Row 12
// ctx.fillText("Billing(1.0%) :", column1X, rowHeight[15] - 5);
// ctx.fillText("MYR", column2X, rowHeight[15] - 5);
// ctx.fillText(binding.value.billing_amount, column3X, rowHeight[15] - 5);
//// Row 13
ctx.fillText("+ TAX " + (Math.round((binding.value.tax_rate * 100 - 100) * 100) / 100) + "% :",
column1X, rowHeight[16] - 5); // TODO : Change to percentage
ctx.fillText("MYR", column2X, rowHeight[16] - 5);
ctx.fillText(binding.value.salestax_amount, column3X, rowHeight[16] - 5);
// //// Row 14
// ctx.fillText("+ GST 6% :", column1X, rowHeight[17] - 15);
// ctx.fillText("MYR", column2X, rowHeight[17] - 15);
// ctx.fillText("289.84", column3X, rowHeight[17] - 15);
//// Row 15
ctx.font = "bold 14px Arial";
ctx.fillText("Bank In Amount :", column1X, rowHeight[18] - 5);
ctx.fillStyle = "#0070D5";
ctx.fillText("MYR", column2X, rowHeight[18] - 5);
ctx.fillText(binding.value.amount_after_tax, column3X, rowHeight[18] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//line
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[17]);
ctx.lineTo(column3X + 20, rowHeight[17]);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[18] + 1);
ctx.lineTo(column3X + 20, rowHeight[18] + 1);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[18] - 2);
ctx.lineTo(column3X + 20, rowHeight[18] - 2);
ctx.stroke();
//// Row 16
// ctx.fillText("Rebate :", column1X, rowHeight[19] - 25);
// ctx.fillText("CNY", column2X, rowHeight[19] - 25);
// ctx.fillText("224.68", column3X, rowHeight[19] - 25);
//// Row 16
ctx.font = "bold 14px Arial";
ctx.fillText("Bank In to Account Below :", column1X, rowHeight[20] - 5);
ctx.font = "bold italic 15px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText("CNY", column2X, rowHeight[20] - 5);
ctx.fillText(binding.value.amountInRMB, column3X - 20, rowHeight[20] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 17
//// Row 18
//// Row 19
// var img = new Image();
// img.src = "/banklogo.png";
// img.crossOrigin = "anonymous";
// var maxwidth = 70;
// var ratio = maxwidth / img.width;
// var offset = ((rowHeight[22] - rowHeight[21]) / 2) - (img.height * ratio / 2);
// var y = rowHeight[21] + offset; // to make it always center
// img.onload=function(){
// ctx.drawImage(img, 50, 530, 80, 50);
// };
// text
ctx.font = "bold 14px Arial";
ctx.textAlign = "center";
ctx.fillText("China beneficiary Account", column2X - 40, rowHeight[22] - 80);
ctx.fillText("户名 : " + binding.value.acc_name, column2X - 40, rowHeight[22] - 60);
ctx.fillText(binding.value.acc_no, column2X - 40, rowHeight[22] - 40);
ctx.fillText(binding.value.bank_name, column2X - 40, rowHeight[22] - 20);
ctx.fillText(binding.value.bank_branch, column2X - 40, rowHeight[22] - 2);
ctx.font = "13px Arial";
}, 1000, canvasElement, binding);
}
}
}
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="trackerConfig" />
<x2-progress-track v-if="(booking_details.admin_status == 'x2_cash' || booking_details.admin_status == 'x2_cheque' || booking_details.admin_status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center">
<h4 style="margin-top:5%;"></h4>
@@ -16,6 +17,56 @@
<br>
<!-- <el-button type="primary" @click="$router.go(-1)">Go Back</el-button> -->
</div>
<br>
<el-row v-if="booking_details.user_po_path" :gutter="12" justify="center" align="center">
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Upload Invoice</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<!-- upload image -->
<el-upload :action="'/api/booking/' + booking_id + '/upload-invoice'" :on-exceed="handleExceed" :on-preview="handlePreview"
:on-remove="handleRemove"
:on-error="uploadError"
accept=".jpeg, .jpg, .png, .bmp, .doc, .docx, .xls, .xlsx, .pdf"
class="upload-demo"
drag
multiple>
<i class="el-icon-upload"/>
<div class="el-upload__text">Drop file here or
<em>click to upload</em>
</div>
<div slot="tip" class="el-upload__tip">bmp/jpeg/jpg/png/pdf/xls/xlxs/doc/docx files with a size less than 3mb</div>
</el-upload>
<br>
<div class="bottom clearfix" style="text-align:right;">
<el-button :loading="loading_btn" type="primary" @click="confirmInvoice">Submit</el-button>
</div>
<!-- upload image end -->
</el-card>
</el-col>
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Customer Purchase Order</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12" type="flex">
<el-col :span="12" align="center">
<a target="_blank" :href="getURL(booking_details.user_po_path)">
<img v-if="isImage(booking_details.user_po_path)" v-bind:src="booking_details.user_po_path" class="image">
<p v-else>Download</p>
</a>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<br>
<el-row justify="center" align="center">
<el-card class="box-card">
@@ -36,7 +87,7 @@
<tbody>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Order Number :</div>
<div class="cell">Ref No :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.id }}</div>
@@ -88,10 +139,6 @@
<!---->
<!---->
</div>
<!---->
<!---->
<!---->
<!---->
<div class="el-table__column-resize-proxy" style="display: none;"></div>
</div>
</div>
@@ -181,55 +228,38 @@
</el-row>
<br>
<el-row v-if="booking_details.user_po_path" :gutter="12" justify="center" align="center">
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Upload Invoice</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<!-- upload image -->
<el-upload :action="'/api/booking/' + booking_id + '/upload-invoice'" :on-exceed="handleExceed" :on-preview="handlePreview"
:on-remove="handleRemove"
:on-error="uploadError"
accept=".jpeg, .jpg, .png, .bmp, .doc, .docx, .xls, .xlsx, .pdf"
class="upload-demo"
drag
multiple>
<i class="el-icon-upload"/>
<div class="el-upload__text">Drop file here or
<em>click to upload</em>
</div>
<div slot="tip" class="el-upload__tip">bmp/jpeg/jpg/png/pdf/xls/xlxs/doc/docx files with a size less than 3mb</div>
</el-upload>
<br>
<div class="bottom clearfix" style="text-align:right;">
<el-button :loading="loading_btn" type="primary" @click="confirmInvoice">Submit</el-button>
</div>
<!-- upload image end -->
</el-card>
</el-col>
<el-col :span="12">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Customer Purchase Order</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12" type="flex">
<el-col :span="12" align="center">
<a target="_blank" :href="getURL(booking_details.user_po_path)">
<img v-if="isImage(booking_details.user_po_path)" v-bind:src="booking_details.user_po_path" class="image">
<p v-else>Download</p>
</a>
</el-col>
</el-row>
</el-card>
</el-col>
<el-row justify="center" align="center">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Supplier Report</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12" style="text-align:center">
<el-col :span="20" style="text-align:center">
<canvas id="myCanvas" ref="myCanvas" v-insert-message="supplier_booking"></canvas>
<br>
<el-button @click="downloadReport()" type="text">Download Now</el-button>
</el-col>
</el-row>
</el-card>
<br>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>User BankinSlip</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12">
<el-col :span="22" style="text-align:center">
<a target="_blank" :href="getURL(booking_details.user_bankslip_path)">
<img v-if="isImage(booking_details.user_bankslip_path)" v-bind:src="booking_details.user_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</el-col>
</el-row>
</el-card>
<br>
</el-row>
<br>
</el-main>
</template>
<style>
@@ -250,16 +280,18 @@
</style>
<script>
import ProgressTrack from '~/components/AdminProgressTrack'
import X2ProgressTrack from '~/components/X2AdminProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data() {
return {
trackerConfig :{
status: 6,
status: null,
term: null
},
loading_btn: false,
@@ -272,6 +304,7 @@
},
supplier: null,
supplier_options: null,
supplier_booking : {},
chinaSlipForm: {
actual_transfer_amount: null,
date: null,
@@ -334,7 +367,8 @@
.then((response) => {
loading.close()
this.booking_details = response.data
this.trackerConfig.term = response.data.term;
this.trackerConfig.term = response.data.term
this.trackerConfig.status = response.data.admin_status
}).catch((error) => {
console.log(error)
loading.close()
@@ -342,6 +376,18 @@
name: 'notfound'
})
})
axios.get('/api/supplier-booking/' + this.$route.params.id)
.then((response) => {
this.supplier_booking = response.data
loading.close()
}).catch((error) => {
console.log(error)
this.$router.push({
name: 'notfound'
})
loading.close()
})
},
methods: {
confirmInvoice () {
@@ -383,6 +429,7 @@
uploadError(file,fileList){
this.$message.warning(`Incorrect file format or file size too big.`)
},
// TODO : refactor into library since many pages are using this
getExtension(path){
return path.slice(-3);
},
@@ -394,6 +441,182 @@
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
return baseUrl + path;
},
},
directives: {
insertMessage: function (canvasElement, binding) {
setTimeout(function (canvasElement, binding) {
////////////////// variable //////////////////////////
var canvasWidth = 450;
var rowHeight = [20, 40, 60, 80, 100, 120, 140, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350, 390, 410,
470, 490, 510, 610, 630
]
const canvasHeight = rowHeight[rowHeight.length - 1];
var column1X = 220;
var column2X = 320;
var column3X = 420;
///////////////////Canvast Init////////////////////
var canvas = document.getElementById("myCanvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// Get canvas context
var ctx = canvasElement.getContext("2d");
// Clear the canvas
ctx.clearRect(0, 0, 300, 150);
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, 0, canvasWidth, rowHeight[0]);
for (var i = 1; i < rowHeight.length; i++) {
if (i % 2 == 1)
ctx.fillStyle = "#A9D08E";
else
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, rowHeight[i - 1], canvasWidth, rowHeight[i]);
}
///////////// fillup with text////////////////
//// config canvas
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
ctx.textAlign = "right";
//// Row 1
ctx.fillText("Ref No. :", column1X, rowHeight[1] - 5);
ctx.fillText(binding.value.booking_id, column3X, rowHeight[1] - 5);
//// Row 2
ctx.fillText("Date :", column1X, rowHeight[2] - 5);
ctx.fillText(binding.value.date, column3X, rowHeight[2] - 5);
//// Row 3
ctx.fillText("Marking :", column1X, rowHeight[3] - 5);
ctx.font = "bold 14px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText(binding.value.marking, column3X, rowHeight[3] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 4
ctx.fillText("Payment For(Order No.) :", column1X, rowHeight[4] - 5);
ctx.fillText(binding.value.order_no, column3X, rowHeight[4] - 5);
//// Row 4
ctx.fillText("Payment For :", column1X, rowHeight[5] - 5);
ctx.fillText(binding.value.payment_for, column3X, rowHeight[5] - 5);
//// Row 5
ctx.fillText("Payment Method :", column1X, rowHeight[6] - 5);
ctx.fillText(binding.value.payment_method, column3X, rowHeight[6] - 5);
//// Row 6
ctx.fillText("Remark :", column1X, rowHeight[7] - 10);
//// Row 7
// Empty
//// Row 8
ctx.fillText("MYR/RM :", column1X, rowHeight[9] - 5);
ctx.fillText("MYR", column2X, rowHeight[9] - 5);
ctx.font = "bold 14px Arial";
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[9] - 5);
ctx.font = "13px Arial";
//// Row 8
ctx.fillText("* RATE :", column1X, rowHeight[10] - 5);
ctx.fillText(binding.value.rate, column3X, rowHeight[10] - 5);
//// Row 9
ctx.fillText("REBATE :", column1X, rowHeight[11] - 5);
ctx.fillText("MYR", column2X, rowHeight[11] - 5);
ctx.font = "14px Arial";
ctx.fillText(binding.value.rebate, column3X, rowHeight[11] - 5);
ctx.font = "13px Arial";
//// Row 10
ctx.font = "bold 14px Arial";
ctx.fillText("CNY", column2X, rowHeight[12] - 5);
ctx.fillText(binding.value.amountInRMB, column3X, rowHeight[12] - 5);
ctx.font = "13px Arial";
//line
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo(column1X + 30, rowHeight[11]);
ctx.lineTo(column3X + 20, rowHeight[11]);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(column1X + 30, rowHeight[12]);
ctx.lineTo(column3X + 20, rowHeight[12]);
ctx.stroke();
//// Row 11
ctx.fillText("MYR/RM :", column1X, rowHeight[14] - 5);
ctx.fillText("MYR", column2X, rowHeight[14] - 5);
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[14] - 5);
//// Row 12
// ctx.fillText("Billing(1.0%) :", column1X, rowHeight[15] - 5);
// ctx.fillText("MYR", column2X, rowHeight[15] - 5);
// ctx.fillText(binding.value.billing_amount, column3X, rowHeight[15] - 5);
//// Row 13
ctx.fillText("+ TAX "+ (Math.round((binding.value.tax_rate * 100 - 100) * 100) / 100) + "% :", column1X, rowHeight[16] - 5); // TODO : Change to percentage
ctx.fillText("MYR", column2X, rowHeight[16] - 5);
ctx.fillText(binding.value.salestax_amount, column3X, rowHeight[16] - 5);
// //// Row 14
// ctx.fillText("+ GST 6% :", column1X, rowHeight[17] - 15);
// ctx.fillText("MYR", column2X, rowHeight[17] - 15);
// ctx.fillText("289.84", column3X, rowHeight[17] - 15);
//// Row 15
ctx.font = "bold 14px Arial";
ctx.fillText("Bank In Amount :", column1X, rowHeight[18] - 5);
ctx.fillStyle = "#0070D5";
ctx.fillText("MYR", column2X, rowHeight[18] - 5);
ctx.fillText(binding.value.amount_after_tax, column3X, rowHeight[18] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//line
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[17]);
ctx.lineTo(column3X + 20, rowHeight[17]);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[18] + 1);
ctx.lineTo(column3X + 20, rowHeight[18] + 1);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[18] - 2);
ctx.lineTo(column3X + 20, rowHeight[18] - 2);
ctx.stroke();
//// Row 16
// ctx.fillText("Rebate :", column1X, rowHeight[19] - 25);
// ctx.fillText("CNY", column2X, rowHeight[19] - 25);
// ctx.fillText("224.68", column3X, rowHeight[19] - 25);
//// Row 16
ctx.font = "bold 14px Arial";
ctx.fillText("Bank In to Account Below :", column1X, rowHeight[20] - 5);
ctx.font = "bold italic 15px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText("CNY", column2X, rowHeight[20] - 5);
ctx.fillText(binding.value.amountInRMB, column3X - 20, rowHeight[20] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 17
//// Row 18
//// Row 19
// var img = new Image();
// img.src = "/banklogo.png";
// img.crossOrigin = "anonymous";
// var maxwidth = 70;
// var ratio = maxwidth / img.width;
// var offset = ((rowHeight[22] - rowHeight[21]) / 2) - (img.height * ratio / 2);
// var y = rowHeight[21] + offset; // to make it always center
// img.onload=function(){
// ctx.drawImage(img, 50, 530, 80, 50);
// };
// text
ctx.font = "bold 14px Arial";
ctx.textAlign = "center";
ctx.fillText("China beneficiary Account", column2X - 40, rowHeight[22] - 80);
ctx.fillText("户名 : " + binding.value.acc_name, column2X - 40, rowHeight[22] - 60);
ctx.fillText(binding.value.acc_no, column2X - 40, rowHeight[22] - 40);
ctx.fillText(binding.value.bank_name , column2X - 40, rowHeight[22] - 20);
ctx.fillText(binding.value.bank_branch , column2X - 40, rowHeight[22] - 2);
ctx.font = "13px Arial";
}, 1000,canvasElement,binding);
}
}
}
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="trackerConfig" />
<x2-progress-track v-if="(booking_details.admin_status == 'x2_cash' || booking_details.admin_status == 'x2_cheque' || booking_details.admin_status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center">
<h4 style="margin-top:5%;"></h4>
@@ -31,7 +32,7 @@
<tbody>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Order Number :</div>
<div class="cell">Ref No :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.id }}</div>
@@ -256,11 +257,13 @@
</style>
<script>
import ProgressTrack from '~/components/AdminProgressTrack'
import X2ProgressTrack from '~/components/X2AdminProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data() {
return {
@@ -306,6 +309,7 @@
approveUserSlip() {
this.loading_btn = true
// TODO : this no longer used
let newApprove = {
estimated_arrival_time: this.estimated_arrival_time
}
@@ -337,6 +341,7 @@
this.centerDialogVisible = false
let newApprove = {
// TODO : this no longer used
estimated_arrival_time: this.estimated_arrival_time,
reject_reason: this.reject_reason
}
@@ -0,0 +1,549 @@
<template>
<el-main>
<x2-progress-track v-if="(booking_details.admin_status == 'x2_cash' || booking_details.admin_status == 'x2_cheque' || booking_details.admin_status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center">
<h4 style="margin-top:5%;">Order Completed</h4>
<br>
<el-button type="primary" @click="$router.go(-1)">Go Back</el-button>
</div>
<br>
<!-- bankslip -->
<br>
<el-row justify="center" align="center">
<el-col>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>China Bank Slip</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row type="flex">
<el-col align="center">
<div v-for="cn_bankslip in booking_details.china_bankslip_path" :key='cn_bankslip'>
<a target="_blank" :href="getURL(cn_bankslip)">
<img v-if="isImage(cn_bankslip)" v-bind:src="cn_bankslip" class="image">
<p v-else>Download</p>
<br/>
</a>
</div>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<br>
<!-- bank slips END -->
<el-row justify="center" align="center">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Order Details</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<!-- <el-row :gutter="12">
<el-col :span="12">
<el-table :data="bookingConfirmTable" :show-header="false" align="center">
<el-table-column prop="data1" align="right" width="200" />
<el-table-column prop="data2" align="left" width="200" />
</el-table>
</el-col>
<el-col :span="12">
<el-table :data="bookingConfirmTable2" :show-header="false" align="center">
<el-table-column prop="data1" align="right" width="200" />
<el-table-column prop="data2" align="left" width="200" />
</el-table>
</el-col>
</el-row> -->
<div class="el-row" style="margin-left: -6px; margin-right: -6px;">
<div class="el-col el-col-12" style="padding-left: 6px; padding-right: 6px;">
<div class="el-table el-table--fit el-table--enable-row-hover el-table--enable-row-transition" align="center">
<div class="el-table__body-wrapper is-scrolling-none">
<table class="el-table__body" style="width: 400px;" cellspacing="0" cellpadding="0" border="0">
<colgroup>
<col name="el-table_2_column_9" width="210">
<col name="el-table_2_column_10" width="210">
</colgroup>
<tbody>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Ref No :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.id }}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Date :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.created_at }}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Customer Marking :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.marking }}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Term :</div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{ booking_details.term }}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Beneficiary Account : </div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{booking_details.account_name}}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table_2_column_9 is-right ">
<div class="cell">Beneficiary Account Number : </div>
</td>
<td class="el-table_2_column_10 is-left ">
<div class="cell">{{booking_details.account_num}}</div>
</td>
</tr>
<!---->
</tbody>
</table>
<!---->
<!---->
</div>
<!---->
<!---->
<!---->
<!---->
<div class="el-table__column-resize-proxy" style="display: none;"></div>
</div>
</div>
<div class="el-col el-col-12" style="padding-left: 6px; padding-right: 6px;">
<div class="el-table el-table--fit el-table--enable-row-hover el-table--enable-row-transition" align="center">
<div class="hidden-columns">
<div></div>
<div></div>
</div>
<!---->
<div class="el-table__body-wrapper is-scrolling-none">
<table class="el-table__body" style="width: 400px;" cellspacing="0" cellpadding="0" border="0">
<colgroup>
<col name="el-table_3_column_11" width="200">
<col name="el-table_3_column_12" width="200">
</colgroup>
<tbody>
<tr class="el-table__row">
<td class="el-table_3_column_11 is-right ">
<div class="cell">CNY/RMB :</div>
</td>
<td class="el-table_3_column_12 is-left ">
<div class="cell">CNY {{ booking_details.amount }}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table_3_column_11 is-right ">
<div class="cell">+ Service Charge :</div>
</td>
<td class="el-table_3_column_12 is-left ">
<div class="cell">CNY {{ booking_details.service_charge }}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table_3_column_11 is-right ">
<div class="cell">/ RATE :</div>
</td>
<td class="el-table_3_column_12 is-left ">
<div class="cell">{{ booking_details.rate }}</div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table_3_column_11 is-right ">
<div class="cell"></div>
</td>
<td class="el-table_3_column_12 is-left ">
<div class="cell">MYR {{ booking_details.bia }}</div>
</td>
</tr>
<!-- <tr class="el-table__row">
<td class="el-table_3_column_11 is-right ">
<div class="cell">+ GST 6% :</div>
</td>
<td class="el-table_3_column_12 is-left ">
<div class="cell">MYR 4,430.88</div>
</td>
</tr> -->
<tr class="el-table__row">
<td class="el-table_3_column_11 is-right ">
<div class="cell"></div>
</td>
<td class="el-table_3_column_12 is-left ">
<div class="cell"><b>MYR {{ booking_details.bia }}</b></div>
</td>
</tr>
<tr class="el-table__row">
<td class="el-table_3_column_11 is-right ">
<div class="cell"></div>
</td>
<td class="el-table_3_column_12 is-left ">
<div class="cell"></div>
</td>
</tr>
<!---->
</tbody>
</table>
<!---->
<!---->
</div>
<!---->
<!---->
<!---->
<!---->
<div class="el-table__column-resize-proxy" style="display: none;"></div>
</div>
</div>
</div>
<!-- <el-row :gutter="12">
<el-col :span="12">
<el-table :data="bookingConfirmTable" :show-header="false" align="center">
<el-table-column prop="data1" align="right" width="200" />
<el-table-column prop="data2" align="left" width="200" />
</el-table>
</el-col>
<el-col :span="12">
<el-table :data="bookingConfirmTable2" :show-header="false" align="center">
<el-table-column prop="data1" align="right" width="200" />
<el-table-column prop="data2" align="left" width="200" />
</el-table>
</el-col>
</el-row> -->
</el-card>
</el-row>
<br>
<el-row justify="center" align="center">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Supplier Report</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12" style="text-align:center">
<el-col :span="20" style="text-align:center">
<canvas id="myCanvas" ref="myCanvas" v-insert-message="supplier_booking"></canvas>
<br>
<el-button @click="downloadReport()" type="text">Download Now</el-button>
</el-col>
</el-row>
</el-card>
<br>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>User BankinSlip</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12">
<el-col :span="22" style="text-align:center">
<a target="_blank" :href="getURL(booking_details.user_bankslip_path)">
<img v-if="isImage(booking_details.user_bankslip_path)" v-bind:src="booking_details.user_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</el-col>
</el-row>
</el-card>
</el-row>
<br>
<el-row justify="center" align="center">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Payment Bankin Slip</span>
<!-- <el-button style="float: right; padding: 3px 0" type="text">Operation button</el-button> -->
</div>
<el-row :gutter="12">
<el-col :span="22" style="text-align:center">
<a target="_blank" :href="getURL(booking_details.user_bankslip_path)">
<img v-if="isImage(booking_details.user_bankslip_path)" v-bind:src="booking_details.user_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</el-col>
</el-row>
</el-card>
</el-row>
</el-main>
</template>
<style>
.booking-details {
font-weight: bold;
}
.image {
border: 1px solid #ddd;
border-radius: 4px;
margin-left: auto;
margin-right: auto;
width: 150px;
display: block;
}
.image:hover {
box-shadow: 0 0 2px 1px rgba(0, 140, 186, 0.5);
}
</style>
<script>
import ProgressTrack from '~/components/AdminProgressTrack'
import X2ProgressTrack from '~/components/X2AdminProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data () {
return {
trackerConfig :{
status: 8,
term: null
},
supplier_booking: {},
loading_btn: false,
booking_details:{
id: null,
amount: null,
bia: null,
user_bankslip_path: null,
}
}
},
beforeCreate () {
const loading = this.$loading({
lock: true,
text: 'Please wait..',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
axios
.get('/api/admin/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term;
loading.close()
}).catch((error) => {
console.log(error)
loading.close()
this.$router.push({
name: 'notfound'
})
})
axios.get('/api/supplier-booking/' + this.$route.params.id)
.then((response) => {
this.supplier_booking = response.data
loading.close()
}).catch((error) => {
console.log(error)
this.$router.push({
name: 'notfound'
})
loading.close()
})
},
methods: {
getExtension(path){
return path.slice(-3);
},
isImage(path){
var ext = this.getExtension(path);
return ext === 'jpg' || ext === 'jpeg' || ext === 'bmp' || ext === 'png';
},
getURL(path){
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
return baseUrl + path;
}
},
directives: {
insertMessage: function (canvasElement, binding) {
setTimeout(function (canvasElement, binding) {
////////////////// variable //////////////////////////
var canvasWidth = 450;
var rowHeight = [20, 40, 60, 80, 100, 120, 140, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350, 390,
410,
470, 490, 510, 610, 630
]
const canvasHeight = rowHeight[rowHeight.length - 1];
var column1X = 220;
var column2X = 320;
var column3X = 420;
///////////////////Canvast Init////////////////////
var canvas = document.getElementById("myCanvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// Get canvas context
var ctx = canvasElement.getContext("2d");
// Clear the canvas
ctx.clearRect(0, 0, 300, 150);
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, 0, canvasWidth, rowHeight[0]);
for (var i = 1; i < rowHeight.length; i++) {
if (i % 2 == 1)
ctx.fillStyle = "#A9D08E";
else
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, rowHeight[i - 1], canvasWidth, rowHeight[i]);
}
///////////// fillup with text////////////////
//// config canvas
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
ctx.textAlign = "right";
//// Row 1
ctx.fillText("Ref No. :", column1X, rowHeight[1] - 5);
ctx.fillText(binding.value.booking_id, column3X, rowHeight[1] - 5);
//// Row 2
ctx.fillText("Date :", column1X, rowHeight[2] - 5);
ctx.fillText(binding.value.date, column3X, rowHeight[2] - 5);
//// Row 3
ctx.fillText("Marking :", column1X, rowHeight[3] - 5);
ctx.font = "bold 14px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText(binding.value.marking, column3X, rowHeight[3] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 4
ctx.fillText("Payment For(Order No.) :", column1X, rowHeight[4] - 5);
ctx.fillText(binding.value.order_no, column3X, rowHeight[4] - 5);
//// Row 4
ctx.fillText("Payment For :", column1X, rowHeight[5] - 5);
ctx.fillText(binding.value.payment_for, column3X, rowHeight[5] - 5);
//// Row 5
ctx.fillText("Payment Method :", column1X, rowHeight[6] - 5);
ctx.fillText(binding.value.payment_method, column3X, rowHeight[6] - 5);
//// Row 6
ctx.fillText("Remark :", column1X, rowHeight[7] - 10);
//// Row 7
// Empty
//// Row 8
ctx.fillText("MYR/RM :", column1X, rowHeight[9] - 5);
ctx.fillText("MYR", column2X, rowHeight[9] - 5);
ctx.font = "bold 14px Arial";
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[9] - 5);
ctx.font = "13px Arial";
//// Row 8
ctx.fillText("* RATE :", column1X, rowHeight[10] - 5);
ctx.fillText(binding.value.rate, column3X, rowHeight[10] - 5);
//// Row 9
ctx.fillText("REBATE :", column1X, rowHeight[11] - 5);
ctx.fillText("MYR", column2X, rowHeight[11] - 5);
ctx.font = "14px Arial";
ctx.fillText(binding.value.rebate, column3X, rowHeight[11] - 5);
ctx.font = "13px Arial";
//// Row 10
ctx.font = "bold 14px Arial";
ctx.fillText("CNY", column2X, rowHeight[12] - 5);
ctx.fillText(binding.value.amountInRMB, column3X, rowHeight[12] - 5);
ctx.font = "13px Arial";
//line
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo(column1X + 30, rowHeight[11]);
ctx.lineTo(column3X + 20, rowHeight[11]);
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(column1X + 30, rowHeight[12]);
ctx.lineTo(column3X + 20, rowHeight[12]);
ctx.stroke();
//// Row 11
ctx.fillText("MYR/RM :", column1X, rowHeight[14] - 5);
ctx.fillText("MYR", column2X, rowHeight[14] - 5);
ctx.fillText(binding.value.amount_in_myr, column3X, rowHeight[14] - 5);
//// Row 12
// ctx.fillText("Billing(1.0%) :", column1X, rowHeight[15] - 5);
// ctx.fillText("MYR", column2X, rowHeight[15] - 5);
// ctx.fillText(binding.value.billing_amount, column3X, rowHeight[15] - 5);
//// Row 13
ctx.fillText("+ TAX " + (Math.round((binding.value.tax_rate * 100 - 100) * 100) / 100) + "% :",
column1X, rowHeight[16] - 5); // TODO : Change to percentage
ctx.fillText("MYR", column2X, rowHeight[16] - 5);
ctx.fillText(binding.value.salestax_amount, column3X, rowHeight[16] - 5);
// //// Row 14
// ctx.fillText("+ GST 6% :", column1X, rowHeight[17] - 15);
// ctx.fillText("MYR", column2X, rowHeight[17] - 15);
// ctx.fillText("289.84", column3X, rowHeight[17] - 15);
//// Row 15
ctx.font = "bold 14px Arial";
ctx.fillText("Bank In Amount :", column1X, rowHeight[18] - 5);
ctx.fillStyle = "#0070D5";
ctx.fillText("MYR", column2X, rowHeight[18] - 5);
ctx.fillText(binding.value.amount_after_tax, column3X, rowHeight[18] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//line
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[17]);
ctx.lineTo(column3X + 20, rowHeight[17]);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[18] + 1);
ctx.lineTo(column3X + 20, rowHeight[18] + 1);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(column1X + 30, rowHeight[18] - 2);
ctx.lineTo(column3X + 20, rowHeight[18] - 2);
ctx.stroke();
//// Row 16
// ctx.fillText("Rebate :", column1X, rowHeight[19] - 25);
// ctx.fillText("CNY", column2X, rowHeight[19] - 25);
// ctx.fillText("224.68", column3X, rowHeight[19] - 25);
//// Row 16
ctx.font = "bold 14px Arial";
ctx.fillText("Bank In to Account Below :", column1X, rowHeight[20] - 5);
ctx.font = "bold italic 15px Arial";
ctx.fillStyle = "#0070D5";
ctx.fillText("CNY", column2X, rowHeight[20] - 5);
ctx.fillText(binding.value.amountInRMB, column3X - 20, rowHeight[20] - 5);
ctx.fillStyle = "#000000";
ctx.font = "13px Arial";
//// Row 17
//// Row 18
//// Row 19
// var img = new Image();
// img.src = "/banklogo.png";
// img.crossOrigin = "anonymous";
// var maxwidth = 70;
// var ratio = maxwidth / img.width;
// var offset = ((rowHeight[22] - rowHeight[21]) / 2) - (img.height * ratio / 2);
// var y = rowHeight[21] + offset; // to make it always center
// img.onload=function(){
// ctx.drawImage(img, 50, 530, 80, 50);
// };
// text
ctx.font = "bold 14px Arial";
ctx.textAlign = "center";
ctx.fillText("China beneficiary Account", column2X - 40, rowHeight[22] - 80);
ctx.fillText("户名 : " + binding.value.acc_name, column2X - 40, rowHeight[22] - 60);
ctx.fillText(binding.value.acc_no, column2X - 40, rowHeight[22] - 40);
ctx.fillText(binding.value.bank_name, column2X - 40, rowHeight[22] - 20);
ctx.fillText(binding.value.bank_branch, column2X - 40, rowHeight[22] - 2);
ctx.font = "13px Arial";
}, 1000, canvasElement, binding);
}
}
}
</script>
@@ -6,7 +6,7 @@
</div>
<h1 align="center" style="margin-bottom:50px;">Completed Orders</h1>
<el-table :data="tableData" stripe height="500" style="width: 100%">
<el-table-column label="No." prop="id" sortable></el-table-column>
<el-table-column label="Ref No." prop="id" sortable></el-table-column>
<el-table-column label="Order Date" prop="created_at" width="180" sortable></el-table-column>
<el-table-column label="Marking" width="120" prop="marking"></el-table-column>
<el-table-column label="Rate" prop="rate" width="74"></el-table-column>
+139 -18
View File
@@ -4,15 +4,16 @@
<el-button :loading="loading_btn" type="primary" size="mini" @click="RefreshBooking()">Refresh</el-button>
</div>
<!-- Booking Table -->
<el-tabs type="border-card" class="table-switch">
<el-tab-pane label="Booking Table">
<el-row :gutter="20">
<div>
<el-table :data="bookingTable">
<el-table-column label="No." width="100">
<el-table-column label="Ref No." width="100">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">Update</el-button>
<el-button slot-scope="scope" type="text" @click="(event) => { BookingStatus(scope.row.admin_status, scope.row.id) }"> {{ scope.row.id }}</el-button>
<el-button slot-scope="scope" type="text" @click="(event) => { BookingStatus(scope.row.admin_status, scope.row.id, scope.row.term) }"> {{ scope.row.id }}</el-button>
</el-table-column>
<el-table-column label="DateTime" prop="created_at" width="180" sortable/>
<el-table-column label="Marking" width="120" prop="marking" />
@@ -38,19 +39,92 @@
<!-- <el-table-column label="Balance" prop="transfer_amount" sortable width="100"/> -->
<!-- <el-table-column prop="timeout" label="Bankin Timeout" /> -->
<el-table-column label="" width="180">
<el-button slot-scope="scope" type="text" @click="(event) => { BookingStatus(scope.row.admin_status, scope.row.id) }"> View Status </el-button>
<el-button slot-scope="scope" type="text" @click="(event) => { BookingStatus(scope.row.admin_status, scope.row.id, scope.row.term) }"> View Status </el-button>
<!-- <template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">View Status</el-button>
<el-button size="mini" type="danger" @click="BookingStatus(scope.$index, scope.row)">Cancel</el-button>
</template> -->
</el-table-column>
</el-table>
</el-table-column>
</el-table>
<div align="right">
<el-button type="primary" size="mini" @click="fetchPaginateBooking(pagination.prev_page_url)" :disabled="!pagination.prev_page_url">
Previous
</el-button>
<span>Page {{pagination.current_page}} of {{pagination.last_page}}</span>
<el-button type="primary" size="mini" @click="fetchPaginateBooking(pagination.next_page_url)" :disabled="!pagination.next_page_url">
Next
</el-button>
</div>
</el-row>
<!-- Booking Table-end -->
</div>
</el-row><br><br></el-tab-pane>
<el-tab-pane label="Completed">
<el-row :gutter="20">
<div>
<el-table :data="bookingTableComplete">
<el-table-column label="Ref No." width="100">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">Update</el-button>
<el-button slot-scope="scope" type="text" @click="(event) => { BookingStatus(scope.row.status, scope.row.id) }"> {{ scope.row.id }}</el-button>
</el-table-column>
<el-table-column label="DateTime" prop="created_at" width="180" sortable/>
<el-table-column :filters="[{text: 'X1', value: 'X1'}, {text: 'X2', value: 'X2'}]" :filter-method="filterHandler" label="Term" prop="term" width="100"/> -->
<el-table-column label="Rate" width="74" prop="rate" />
<el-table-column label="Amount" prop="amount" justify="center" width="110" />
<el-table-column :filters="[{text: 'RMB', value: 'RMB'}, {text: 'USD', value: 'USD'}]" :filter-method="filterHandler" label="Transfer Amount"
prop="transfer_amount" width="170" />
<!-- <el-table-column label="ETA" sortable width="100"/> -->
<!-- <el-table-column label="Payment Method" :filters="[{text: 'Cash', value: 'Cash'}, {text: 'Cheque', value: 'Cheque'}, {text: 'BA', value: 'BA'}]" :filter-method="filterHandler">
</el-table-column> -->
<!-- <el-table-column :filters="[{text: '(1/6)', value: '(1/6) Order Done'}, {text: '(2/6)', value: '(2/6) Waiting for Upload Bank in Slip'}, {text: '(3/6)', value: '(3/6) Order Confirmation'}, {text: '(4/6)', value: '(4/6) Processing Transfer'}, {text: '(5/6)', value: '(5/6) Waiting for Upload PO'}, {text: '(6/6)', value: '(6/6) Order Complete'}]" :filter-method="filterHandler" prop="status" label="Status"/> -->
<el-table-column label="Status" width="106">
<template slot-scope="scope">
<el-popover trigger="click" placement="top">
<p>{{ scope.row.status_desc }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.track_status }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<!-- <el-table-column label="Balance" prop="transfer_amount" sortable width="100"/> -->
<!-- <el-table-column prop="timeout" label="Bankin Timeout" /> -->
<el-table-column :filters="[{ text: 'Success', value: 'Success' }, { text: 'Pending', value: 'Pending' }]" :filter-method="filterTag"
label="" width="180" filter-placement="bottom-end">
<el-button slot-scope="scope" type="text" @click="(event) => { BookingStatus(scope.row.status, scope.row.id) }"> View Status </el-button>
<!-- <template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">View Status</el-button>
<el-button size="mini" type="danger" @click="BookingStatus(scope.$index, scope.row)">Cancel</el-button>
</template> -->
</el-table-column>
</el-table>
<div align="right">
<el-button type="primary" size="mini" @click="fetchCompletePaginateBooking(completePagination.prev_page_url)" :disabled="!completePagination.prev_page_url">
Previous
</el-button>
<span>Page {{completePagination.current_page}} of {{completePagination.last_page}}</span>
<el-button type="primary" size="mini" @click="fetchCompletePaginateBooking(completePagination.next_page_url)" :disabled="!completePagination.next_page_url">
Next
</el-button>
</div>
</div>
</el-row><br><br>
</el-tab-pane>
</el-tabs>
<!-- Booking Table-end -->
</div>
</template>
<style type="text/css">
.el-table__column-filter-trigger i {
font-size: 18px;
font-weight: 900;
vertical-align: sub;
}
</style>
<script>
import axios from 'axios'
@@ -59,20 +133,33 @@ export default {
data () {
return {
status: null,
bookingTable: [
],
url: 'api/admin/booking',
bookingTable: [],
bookingTableComplete: [],
url: 'api/admin/booking',
completeBookingurl : "api/admin-complete-booking",
pagination: [],
completePagination: [],
loading_btn: false,
}
},
mounted () {
this.getBooking()
this.getBooking();
this.getBookingTableComplete();
},
methods: {
getBooking() {
getBooking(){
let $this = this
axios.get(this.url).then(response => {
this.bookingTable = response.data
this.bookingTable = response.data.data;
$this.makePagination(response.data);
})
},
getBookingTableComplete(){
let $this = this
axios.get(this.completeBookingurl).then(response => {
this.bookingTableComplete = response.data.data
$this.makeCompletePagination(response.data)
})
},
RefreshBooking() {
@@ -80,7 +167,7 @@ export default {
this.loading_btn = true
axios.get(this.url).then(response => {
this.loading_btn = false;
this.bookingTable = response.data
this.bookingTable = response.data.data
this.$message({
showClose: true,
message: 'Booking is updated',
@@ -89,6 +176,33 @@ export default {
})
})
},
makePagination(data){
let pagination ={
current_page: data.current_page,
last_page: data.last_page,
next_page_url: data.next_page_url,
prev_page_url: data.prev_page_url
}
this.pagination = pagination
},
makeCompletePagination(data){
let pagination ={
current_page: data.current_page,
last_page: data.last_page,
next_page_url: data.next_page_url,
prev_page_url: data.prev_page_url
}
this.completePagination = pagination
},
fetchPaginateBooking(url) {
this.url = url
this.getBooking()
},
fetchCompletePaginateBooking(url) {
this.completeBookingurl = url
this.getBookingTableComplete()
},
filterHandlerStatus (value, row, column) {
const status = row.track_status;
if(value ==="Success")
@@ -104,7 +218,7 @@ export default {
const term = row.term;
return value.toLowerCase() === term.substring(0,2);
},
BookingStatus (status, booking_id) {
BookingStatus (status, booking_id, term) {
// TODO : Get booking status from server
this.status = status
switch (this.status) {
@@ -140,6 +254,13 @@ export default {
break
case 6:
if(term == 'x2_cash' || term == 'x2_cheque' || term == 'x2_ba'){
this.$router.push({
name: 'booking.admin.x2complete',
params: {id: booking_id }
})
break
}
this.$router.push({
name: 'booking.admin.invoice',
params: {id: booking_id }
@@ -5,7 +5,7 @@
<el-button type="primary" icon="el-icon-plus" @click="AddNewDialogVisible = true">Add New</el-button>
</div><br>
<el-table :data="tableData" stripe style="width: 100%">
<el-table-column label="Order No" sortable></el-table-column>
<el-table-column label="Ref No" sortable></el-table-column>
<el-table-column label="Amount (RMB)" sortable></el-table-column>
<el-table-column label="Date" sortable></el-table-column>
<el-table-column label="Bank Slip File"></el-table-column>
+1 -3
View File
@@ -26,9 +26,7 @@
<div class="form-group row">
<div class="col-md-3"/>
<div class="col-md-7 d-flex">
<checkbox v-model="remember" name="remember">
{{ $t('remember_me') }}
</checkbox>
<router-link :to="{ name: 'password.request' }" class="small ml-auto my-auto">
{{ $t('forgot_password') }}
+15 -18
View File
@@ -5,65 +5,64 @@
<card :title="$t('register')">
<form @submit.prevent="register" @keydown="form.onKeydown($event)">
<!-- Marking -->
<div class="form-group row" :class="{'has-error': errors.has('marking') }">
<div class="form-group row">
<label class="col-md-3 col-form-label text-md-right">{{ $t('Marking') }}</label>
<div class="col-md-7">
<el-input v-model="form.marking" v-validate="'required|max:255'" type="text" name="marking" placeholder="Marking Number">
</el-input>
<span class="text-danger" v-if="errors.has('marking')">{{ errors.first('marking') }}<br/></span>
<input v-model="form.marking" :class="{ 'is-invalid': form.errors.has('marking') }" class="form-control" type="text" name="marking">
<has-error :form="form" field="marking"/>
</div>
</div>
<!-- Email -->
<div class="form-group row" :class="{'has-error': errors.has('email') }">
<div class="form-group row">
<label class="col-md-3 col-form-label text-md-right">{{ $t('email') }}</label>
<div class="col-md-7">
<el-input v-model="form.email" v-validate="'required|max:255'" type="email" name="email" placeholder="Email">
<el-input v-model="form.email" type="email" name="email" placeholder="Email">
</el-input>
<span class="text-danger" v-if="errors.has('email')">{{ errors.first('email') }}</span>
<has-error :form="form" field="email"/>
</div>
</div>
<!-- Password -->
<div class="form-group row" :class="{'has-error': errors.has('password') }">
<div class="form-group row">
<label class="col-md-3 col-form-label text-md-right">{{ $t('password') }}</label>
<div class="col-md-7">
<el-input v-if="password_visible" v-model="form.password" v-validate="'required|min:6|max:255'" type="text" name="password" placeholder="Password">
<el-input v-if="password_visible" v-model="form.password" type="text" name="password" placeholder="Password">
<template slot="append">
<el-button type="primary" @click="password_visible = !password_visible"><i class="fas fa-eye"></i></el-button>
</template>
</el-input>
<el-input v-else v-model="form.password" v-validate="'required|min:6|max:255'" type="password" name="password" placeholder="Password">
<el-input v-else v-model="form.password" type="password" name="password" placeholder="Password">
<template slot="append">
<el-button type="primary" @click="password_visible = !password_visible"><i class="fas fa-eye-slash"></i></el-button>
</template>
</el-input>
<span class="text-danger" v-if="errors.has('password')">{{ errors.first('password') }}</span>
<has-error :form="form" field="password"/>
</div>
</div>
<!-- Password Confirmation -->
<div class="form-group row" :class="{'has-error': errors.has('confirm_password') }">
<div class="form-group row">
<label class="col-md-3 col-form-label text-md-right">{{ $t('confirm_password') }}</label>
<div class="col-md-7">
<el-input v-if="password_confirmation_visible" v-model="form.password_confirmation" v-validate="'required|min:6|max:255'" type="text" name="password_confirmation" placeholder="Confirm Password">
<el-input v-if="password_confirmation_visible" v-model="form.password_confirmation" type="text" name="password_confirmation" placeholder="Confirm Password">
<template slot="append">
<el-button type="primary" @click="password_confirmation_visible = !password_confirmation_visible"><i class="fas fa-eye"></i></el-button>
</template>
</el-input>
<el-input v-else v-model="form.password_confirmation" v-validate="'required|min:6|max:255'" type="password" name="password_confirmation" placeholder="Confirm Password">
<el-input v-else v-model="form.password_confirmation" type="password" name="password_confirmation" placeholder="Confirm Password">
<template slot="append">
<el-button type="primary" @click="password_confirmation_visible = !password_confirmation_visible"><i class="fas fa-eye-slash"></i></el-button>
</template>
</el-input>
<span class="text-danger" v-if="errors.has('password_confirmation')">{{ errors.first('password_confirmation') }}<br/></span>
<has-error :form="form" field="password_confirmation"/>
</div>
</div>
<div class="form-group row">
<div class="col-md-7 offset-md-3 d-flex">
<!-- Submit Button -->
<v-button :loading="form.busy" :disabled="errors.any() || form.password=='' || form.password_confirmation=='' || form.email=='' || form.marking=='' ? true : false">
<v-button :loading="form.busy" :disabled="form.password=='' || form.password_confirmation=='' || form.email=='' || form.marking=='' ? true : false">
{{ $t('register') }}
</v-button>
@@ -83,8 +82,6 @@ import Form from 'vform'
import LoginWithGithub from '~/components/LoginWithGithub'
import store from '~/store'
import Vue from 'vue'
import VeeValidate from 'vee-validate';
Vue.use(VeeValidate);
export default {
middleware: 'guest',
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="status"/>
<x2-progress-track v-if="(booking_details.status == 'x2_cash' || booking_details.status == 'x2_cheque' || booking_details.status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<h1>Order Completed</h1>
<div class="goBackButton">
<el-button type="primary" @click="$router.go(-1)">Go Back</el-button>
@@ -24,7 +25,7 @@
<div class="card">
<div class="card-header">China Bank Slip</div>
<div class="row">
<div v-for="cn_bankslip in booking_details.china_bankslip_path">
<div v-for="cn_bankslip in booking_details.china_bankslip_path" :key='cn_bankslip'>
<a target="_blank" :href="getURL(cn_bankslip)">
<img v-if="isImage(cn_bankslip)" v-bind:src="cn_bankslip" class="image">
<p v-else>Download</p>
@@ -57,7 +58,7 @@
<table class="table table-striped">
<tbody>
<tr>
<td>Order Number :</td>
<td>Ref No :</td>
<td>{{ booking_details.id }}</td>
</tr>
<tr>
@@ -148,17 +149,21 @@
}
</style>
<script>
import VueCountdown from '@dmaksimovic/vue-countdown'
import ProgressTrack from '~/components/ProgressTrack'
import X2ProgressTrack from '~/components/X2ProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data () {
return {
status: 7,
trackerConfig :{
status: 7,
term: null,
},
loading_btn: false,
booking_details:{
id: null,
@@ -180,6 +185,7 @@ export default {
.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term
loading.close();
}).catch((error) => {
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="status"/>
<x2-progress-track v-if="(booking_details.status == 'x2_cash' || booking_details.status == 'x2_cheque' || booking_details.status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<h1>Bankin Slip Verification in Progress</h1>
<div class="goBackButton">
<el-button type="primary" @click="$router.go(-1)">Go Back</el-button>
@@ -13,7 +14,7 @@
<table class="table table-striped">
<tbody>
<tr>
<td>Order Number :</td>
<td>Ref No :</td>
<td>{{ booking_details.id }}</td>
</tr>
<tr>
@@ -102,17 +103,21 @@
}
</style>
<script>
import VueCountdown from '@dmaksimovic/vue-countdown'
import ProgressTrack from '~/components/ProgressTrack'
import X2ProgressTrack from '~/components/X2ProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data () {
return {
status: 3,
trackerConfig :{
status: 3,
term: null
},
loading_btn: false,
booking_details:{
id: null,
@@ -134,6 +139,7 @@ export default {
.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term
loading.close()
}).catch((error) => {
+11 -5
View File
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="status"/>
<x2-progress-track v-if="(booking_details.status == 'x2_cash' || booking_details.status == 'x2_cheque' || booking_details.status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<h1>Processing Invoice</h1>
<div class="goBackButton">
<el-button type="primary" @click="$router.go(-1)">Go Back</el-button>
@@ -53,7 +54,7 @@
<table class="table table-striped">
<tbody>
<tr>
<td>Order Number :</td>
<td>Ref No :</td>
<td>{{ booking_details.id }}</td>
</tr>
<tr>
@@ -144,17 +145,21 @@
}
</style>
<script>
import VueCountdown from '@dmaksimovic/vue-countdown'
import ProgressTrack from '~/components/ProgressTrack'
import X2ProgressTrack from '~/components/X2ProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data () {
return {
status: 6,
trackerConfig :{
status: 6,
term: null
},
loading_btn: false,
booking_details:{
id: null,
@@ -176,6 +181,7 @@ export default {
.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term
loading.close()
}).catch((error) => {
@@ -1,7 +1,7 @@
<template>
<el-main>
<progress-track v-model="status"/>
<x2-progress-track v-if="(booking_details.status == 'x2_cash' || booking_details.status == 'x2_cheque' || booking_details.status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center">
<h4 style="margin-top:5%;">Processing Invoice</h4>
<br>
@@ -69,7 +69,7 @@
<table class="table table-striped">
<tbody>
<tr>
<td>Order Number :</td>
<td>Ref No :</td>
<td>{{ booking_details.id }}</td>
</tr>
<tr>
@@ -131,17 +131,21 @@
}
</style>
<script>
import VueCountdown from '@dmaksimovic/vue-countdown'
import ProgressTrack from '~/components/ProgressTrack'
import X2ProgressTrack from '~/components/X2ProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data () {
return {
status: 6,
trackerConfig :{
status: 6,
term: null
},
loading_btn: false,
booking_details:{
id: null,
@@ -163,6 +167,7 @@ export default {
.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term
loading.close()
}).catch((error) => {
+23 -13
View File
@@ -1,6 +1,7 @@
<template>
<el-main>
<progress-track v-model="status"/>
<x2-progress-track v-if="(booking_details.status == 'x2_cash' || booking_details.status == 'x2_cheque' || booking_details.status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<h1>Bankin Slip Approved</h1>
<h2>Transfer In Progress</h2>
<div class="goBackButton">
@@ -15,7 +16,7 @@
<table class="table table-striped">
<tbody>
<tr>
<td>Order Number :</td>
<td>Ref No:</td>
<td>{{ booking_details.id }}</td>
</tr>
<tr>
@@ -72,7 +73,7 @@
<div class="card-body">
<a target="_blank" :href="booking_details.user_bankslip_path">
<a target="_blank" :href="getURL(booking_details.user_bankslip_path)">
<img v-if="isImage(booking_details.user_bankslip_path)" v-bind:src="booking_details.user_bankslip_path" class="image">
<img v-if="this.bankslip_is_image" v-bind:src="booking_details.user_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</a>
@@ -123,18 +124,23 @@
}
</style>
<script>
import VueCountdown from '@dmaksimovic/vue-countdown'
import ProgressTrack from '~/components/ProgressTrack'
import X2ProgressTrack from '~/components/X2ProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data () {
return {
status: 4,
trackerConfig :{
status: 4,
term: null
},
loading_btn: false,
bankslip_is_image: false,
booking_details:{
id: null,
amount: null,
@@ -155,6 +161,14 @@ export default {
.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term
// check if path is image
var ext = this.booking_details.user_bankslip_path.split('.').pop();
if (ext === 'jpg' || ext === 'jpeg' || ext === 'bmp' || ext === 'png'){
this.bankslip_is_image = true
}
loading.close()
}).catch((error) => {
@@ -164,15 +178,11 @@ export default {
name: 'notfound'
})
})
},
methods: {
getExtension(path){
return path.slice(-3);
},
isImage(path){
var ext = this.getExtension(path);
return ext === 'jpg' || ext === 'jpeg' || ext === 'bmp' || ext === 'png';
},
getURL(path){
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
+169 -159
View File
@@ -1,79 +1,72 @@
<template>
<el-main>
<progress-track v-model="status"/>
<h1>Transfer Completed</h1>
<h2> Please upload your purchase order </h2>
<!-- upload card -->
<div class="row">
<div class="col">
<div class="card">
<div class="card-header">Upload PO</div>
<!-- upload image -->
<div class="card-body">
<el-upload :action="'/api/booking/' + booking_id + '/upload-po'" :on-exceed="handleExceed" :on-preview="handlePreview"
:on-remove="handleRemove"
:on-error="uploadError"
class="upload-demo uploadAreaOne"
accept=".jpeg, .jpg, .png, .bmp, .doc, .docx, .xls, .xlsx, .pdf"
drag
multiple>
<i class="el-icon-upload"/>
<div class="el-upload__text">Drop file here or
<em>click to upload</em>
</div>
<div slot="tip" class="el-upload__tip">bmp/jpeg/jpg/png/pdf/xls/xlxs/doc/docx files with a size less than 3MB</div>
</el-upload>
<el-upload
class="upload-demo uploadAreaTwo"
:action="'/api/booking/' + booking_id + '/upload-po'"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:file-list="fileList">
<el-button size="small" type="primary">Click to upload</el-button>
<div slot="tip" class="el-upload__tip">jpg/png files with a size less than 500kb</div>
</el-upload>
<div class="bottom clearfix" style="text-align:right;">
<el-button :loading="loading_btn" type="primary" @click="uploadPo">Submit</el-button>
<el-main>
<x2-progress-track v-if="(booking_details.status == 'x2_cash' || booking_details.status == 'x2_cheque' || booking_details.status == 'x2_ba')" v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<h1>Transfer Completed</h1>
<h2> Please upload your purchase order </h2>
<!-- upload card -->
<div class="row">
<div class="col">
<div class="card">
<div class="card-header">Upload PO
<a href="/po-format.xls" target="_blank">(Download Po Format)</a>
</div>
<!-- upload image -->
<div class="card-body">
<el-upload :action="'/api/booking/' + booking_id + '/upload-po'" :on-exceed="handleExceed" :on-preview="handlePreview" :on-remove="handleRemove"
:on-error="uploadError" class="upload-demo uploadAreaOne" accept=".jpeg, .jpg, .png, .bmp, .doc, .docx, .xls, .xlsx, .pdf"
drag multiple>
<i class="el-icon-upload" />
<div class="el-upload__text">Drop file here or
<em>click to upload</em>
</div>
<div slot="tip" class="el-upload__tip">bmp/jpeg/jpg/png/pdf/xls/xlxs/doc/docx files with a size less than 3MB</div>
</el-upload>
<el-upload class="upload-demo uploadAreaTwo" :action="'/api/booking/' + booking_id + '/upload-po'" :on-preview="handlePreview"
:on-remove="handleRemove" :before-remove="beforeRemove" multiple :file-list="fileList">
<el-button size="small" type="primary">Click to upload</el-button>
<div slot="tip" class="el-upload__tip">jpg/png files with a size less than 500kb</div>
</el-upload>
<div class="bottom clearfix" style="text-align:right;">
<el-button :loading="loading_btn" type="primary" @click="uploadPo">Submit</el-button>
</div>
<!-- upload image end -->
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-header">China Bank Slip</div>
<div class="card-body">
<a target="_blank" :href="getURL(booking_details.china_bankslip_path)">
<img v-if="isImage(booking_details.china_bankslip_path)" v-bind:src="booking_details.china_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</div>
<!-- upload image end -->
</div>
</div>
</div>
<div class="col">
<div class="card">
<div class="card-header">China Bank Slip</div>
<div class="card-body">
<a target="_blank" :href="getURL(booking_details.china_bankslip_path)">
<img v-if="isImage(booking_details.china_bankslip_path)" v-bind:src="booking_details.china_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</div>
</div>
</div>
</div>
<!-- order details -->
<div class="card">
<div class="card-header">Order Details</div>
<div class="card-body">
<!-- order details -->
<div class="card">
<div class="card-header">Order Details</div>
<div class="card-body">
<div class="row">
<div class="col">
<table class="table table-striped">
<tbody>
<tr>
<td>Order Number :</td>
<td>Ref No :</td>
<td>{{ booking_details.id }}</td>
</tr>
<tr>
<td>Date :</td>
<td>{{ booking_details.created_at }}</td>
<td>{{ booking_details.created_at }}</td>
</tr>
<tr>
<td>Customer Marking :</td>
<td>{{ booking_details.marking }}</td>
<td>{{ booking_details.marking }}</td>
</tr>
<tr>
<td>Term: </td>
@@ -95,15 +88,17 @@
</tr>
<tr>
<td>+ Service Charge :</td>
<td>CNY {{ booking_details.service_charge }}</td>
<td>CNY {{ booking_details.service_charge }}</td>
</tr>
<tr>
<td>RATE :</td>
<td>{{ booking_details.rate }}</td>
<td>{{ booking_details.rate }}</td>
</tr>
<tr>
<td></td>
<td><b>MYR {{ booking_details.bia }}</b></td>
<td>
<b>MYR {{ booking_details.bia }}</b>
</td>
</tr>
<tr>
<td>Beneficiary Account Number : </td>
@@ -120,9 +115,9 @@
<div class="row">
<div class="card-body">
<a target="_blank" :href="getURL(booking_details.user_bankslip_path)">
<img v-if="isImage(booking_details.user_bankslip_path)" v-bind:src="booking_details.user_bankslip_path" class="image">
<p v-else>Download</p>
</a>
<img v-if="isImage(booking_details.user_bankslip_path)" v-bind:src="booking_details.user_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</div>
</div>
</div>
@@ -132,19 +127,23 @@
* {
box-sizing: border-box;
}
h1 {
margin-top:5%;
font-size:3vw;
text-align:center;
margin-top: 5%;
font-size: 3vw;
text-align: center;
}
h2 {
font-size:2vw;
text-align:center;
margin-bottom:3%;
font-size: 2vw;
text-align: center;
margin-bottom: 3%;
}
.booking-details {
font-weight: bold;
}
.bankinSlipImage {
border: 1px solid #ddd;
border-radius: 4px;
@@ -153,26 +152,30 @@
width: 150px;
display: block;
}
.bankinSlipImage:hover {
box-shadow: 0 0 2px 1px rgba(0, 140, 186, 0.5);
}
.uploadAreaTwo {
display: none;
}
.card {
margin-bottom: 3%;
}
@media only screen and (max-width : 767px) {
@media only screen and (max-width: 767px) {
.uploadAreaOne {
display: none;
}
.uploadAreaTwo {
display: unset;
}
.table {
font-size: 3.5vmin;
}
h1 {
.table {
font-size: 3.5vmin;
}
h1 {
font-size: 1em;
}
h2 {
@@ -181,104 +184,111 @@
}
</style>
<script>
import VueCountdown from '@dmaksimovic/vue-countdown'
import ProgressTrack from '~/components/ProgressTrack'
import ProgressTrack from '~/components/ProgressTrack'
import X2ProgressTrack from '~/components/X2ProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data () {
return {
booking_id: this.$route.params.id,
status: 5,
loading_btn: false,
booking_details:{
id: null,
amount: null,
bia: null,
user_bankslip_path: null,
china_bankslip_path: null,
data() {
return {
booking_id: this.$route.params.id,
trackerConfig :{
status: 5,
term: null
},
loading_btn: false,
booking_details: {
id: null,
amount: null,
bia: null,
user_bankslip_path: null,
china_bankslip_path: null,
}
}
}
},
beforeCreate () {
const loading = this.$loading({
lock: true,
text: 'Please wait..',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
axios
.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
loading.close()
}).catch((error) => {
console.log(error)
loading.close()
this.$router.push({
name: 'notfound'
})
},
beforeCreate() {
const loading = this.$loading({
lock: true,
text: 'Please wait..',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
},
methods: {
uploadPo () {
this.loading_btn = true
axios
.post('/api/booking/' + this.$route.params.id + '/confirm-po')
.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.$message({
showClose: true,
message: 'Your PO has been uploaded. We are processing the Invoice.',
type: 'success',
duration: 5000
})
this.$router.push({
name: 'home'
})
this.loading_btn = false
this.booking_details = response.data
this.trackerConfig.term = response.data.term
loading.close()
}).catch((error) => {
console.log(error)
loading.close()
this.$router.push({
name: 'notfound'
})
})
},
methods: {
uploadPo() {
this.loading_btn = true
axios
.post('/api/booking/' + this.$route.params.id + '/confirm-po')
.then((response) => {
this.$message({
showClose: true,
message: 'Your PO has been uploaded. We are processing the Invoice.',
type: 'success',
duration: 5000
})
this.$router.push({
name: 'home'
})
this.loading_btn = false
}).catch((error) => {
this.$message({
showClose: true,
message: "Please upload your purchase order",
type: 'error',
duration: 30000
})
this.loading_btn = false
})
},
handleRemove (file, fileList) {
console.log(file, fileList)
// Should send some reqeust to controller to delete the file
},
handlePreview (file) {
console.log(file)
},
handleExceed (files, fileList) {
this.$message.warning(`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + fileList.length} totally`)
},
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`)
},
uploadError(file,fileList){
this.$message.warning(`Incorrect file format or file size too big.`)
},
getExtension(path){
return path.slice(-3);
},
isImage(path){
var ext = this.getExtension(path);
return ext === 'jpg' || ext === 'jpeg' || ext === 'bmp' || ext === 'png';
},
getURL(path){
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
return baseUrl + path;
this.loading_btn = false
})
},
handleRemove(file, fileList) {
console.log(file, fileList)
// Should send some reqeust to controller to delete the file
},
handlePreview(file) {
console.log(file)
},
handleExceed(files, fileList) {
this.$message.warning(
`The limit is 3, you selected ${files.length} files this time, add up to ${files.length + fileList.length} totally`
)
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${file.name}`)
},
uploadError(file, fileList) {
this.$message.warning(`Incorrect file format or file size too big.`)
},
getExtension(path) {
return path.slice(-3);
},
isImage(path) {
var ext = this.getExtension(path);
return ext === 'jpg' || ext === 'jpeg' || ext === 'bmp' || ext === 'png';
},
getURL(path) {
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
return baseUrl + path;
}
}
}
}
</script>
</script>
@@ -1,100 +1,117 @@
<template>
<el-main>
<progress-track v-model="status"/>
<div align="center" v-if="booking.user_bankslip_path">
<h4 style="margin-top:5%" >
Your Bankslip Has Been Rejected, Please Reupload Your Bankslip <br>
Reason : {{ booking.reject_reason }}
</h4>
<br>
<br>
</div>
<div v-else align="center">
<h1>Waiting For Payment</h1>
</div>
<x2-progress-track v-if="(booking.status == 'x2_cash' || booking.status == 'x2_cheque' || booking.status == 'x2_ba')"
v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<div align="center" v-if="booking.user_bankslip_path">
<h4 style="margin-top:5%">
Your Bankslip Has Been Rejected, Please Reupload Your Bankslip
<br> Reason : {{ booking.reject_reason }}
</h4>
<br>
<br>
</div>
<div v-else align="center">
<h1>Please Upload Bankslip</h1>
</div>
<div class="row">
<table class="table table-striped">
<tbody>
<tr>
<td>Amount : </td>
<td><b>RMB {{ booking.amount }}</b></td>
</tr>
<tr>
<td>Bankin Amount : </td>
<td><b> MYR {{ booking.bankin_amount }}</b></td>
</tr>
<tr>
<td colspan="2">
<b>{{ bankDetail.company_name }}</b><br>
{{ bankDetail.bank_name }} : {{ bankDetail.acc_no }}
</td>
</tr>
</tbody>
</table>
</div>
<div class="row timer">
<div class="col">
<vue-countdown :countdownend="handleCoutdownend" :time="booking.timeout">
<template slot-scope="props">Time Remaining<br>{{ props.days }} days, {{ props.hours }} hours, {{ props.minutes }} minutes, {{ props.seconds }} seconds.</template>
</vue-countdown>
<div class="row">
<table class="table table-striped">
<tbody>
<tr>
<td>Amount : </td>
<td>
<b>RMB {{ booking.amount }}</b>
</td>
</tr>
<tr>
<td>Bankin Amount : </td>
<td>
<b> MYR {{ booking.bankin_amount }}</b>
</td>
</tr>
<tr>
<td colspan="2">
<b>{{ bankDetail.company_name }}</b>
<br> {{ bankDetail.bank_name }} : {{ bankDetail.acc_no }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- upload image -->
<div class="row upload">
<div class="col">
<el-upload :action="'/api/booking/' + booking_id + '/upload-user-bankslip'"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:on-error="uploadError"
accept=".jpeg, .jpg, .png, .bmp, .doc, .docx, .xls, .xlsx, .pdf"
list-type="picture-card" align="center">
<i class="el-icon-plus" />
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img :src="dialogImageUrl" width="100%" alt="">
</el-dialog>
<div class="row timer">
<div class="col">
<vue-countdown :countdownend="handleCoutdownend" :time="booking.timeout">
<template slot-scope="props">Time Remaining
<br>{{ props.days }} days, {{ props.hours }} hours, {{ props.minutes }} minutes, {{ props.seconds }} seconds.</template>
</vue-countdown>
</div>
</div>
</div>
<!-- upload image end -->
<div class="row bankinAmount">
<div class="col">
Bankin Amount (RM) :<br>
<el-form ref="user_slip_form" :model="user_slip_form" :rules="rules">
<el-form-item prop="transfer_amount">
<el-input class="transferAmountInput" v-model="user_slip_form.transfer_amount" type="text" placeholder="Transfer Amount"/>
</el-form-item>
<el-form-item>
<el-button :loading="loading" type="primary" @click="submitUserSlip('user_slip_form')">Submit</el-button>
<router-link :to="{ name: 'home' }" class="small ml-auto my-auto">
Upload Later
</router-link>
</el-form-item>
</el-form>
<!-- upload image -->
<div class="row upload">
<div class="col">
<!-- <el-upload :action="'/api/booking/' + booking_id + '/upload-user-bankslip'" :show-file-list="false" :on-preview="handlePictureCardPreview"
:on-remove="handleRemove" :on-error="uploadError" accept=".jpeg, .jpg, .png, .bmp, .doc, .docx, .xls, .xlsx, .pdf" list-type="picture-card"
align="center">
<i class="el-icon-plus" />
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img :src="dialogImageUrl" width="100%" alt="">
</el-dialog> -->
<el-upload class="avatar-uploader" :action="'/api/booking/' + booking_id + '/upload-user-bankslip'" :show-file-list="false"
:on-success="handleUploadSuccess" :before-upload="beforeFileUpload" algin="center">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
</div>
<!-- upload image end -->
<div class="row bankinAmount">
<div class="col">
Bankin Amount (RM) :
<br>
<el-form ref="user_slip_form" :model="user_slip_form" :rules="rules">
<el-form-item prop="transfer_amount">
<el-input class="transferAmountInput" v-model="user_slip_form.transfer_amount" type="text" placeholder="Transfer Amount"
/>
</el-form-item>
<el-form-item>
<el-button :loading="loading" type="primary" @click="submitUserSlip('user_slip_form')">Submit</el-button>
<router-link :to="{ name: 'home' }" class="small ml-auto my-auto">
Upload Later
</router-link>
</el-form-item>
</el-form>
</div>
</div>
</div>
</el-main>
</template>
<style>
h1 {
margin-top:5%;
font-size:3vw;
text-align:center;
margin-bottom:3%;
}
.timer, .upload, .bankinAmount {
margin-top: 5%;
font-size: 3vw;
text-align: center;
margin-bottom: 3%;
}
.timer,
.upload,
.bankinAmount {
text-align: center;
}
.transferAmountInput {
width: 20%;
}
.row {
margin-bottom: 3%;
}
td:last-child {
text-align:center;
margin-bottom: 3%;
}
td:last-child {
text-align: center;
}
@media screen and (max-width: 767px) {
.transferAmountInput {
width: 60%;
@@ -103,200 +120,266 @@
font-size: 3.5vmin;
}
h1 {
font-size: 1em;
}
font-size: 1em;
}
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
<script>
import VueCountdown from '@xkeshi/vue-countdown'
import ProgressTrack from '~/components/ProgressTrack'
import axios from 'axios'
import VueCountdown from '@xkeshi/vue-countdown'
import ProgressTrack from '~/components/ProgressTrack'
import X2ProgressTrack from '~/components/X2ProgressTrack'
import axios from 'axios'
export default {
middleware: ['auth'],
name: 'MyComponent',
components: {
'vue-countdown': VueCountdown,
'progress-track': ProgressTrack
},
data () {
return {
status: 2,
start: false,
loading: false,
dialogImageUrl: '',
dialogVisible: false,
booking_id: this.$route.params.id,
user_slip_form: {
transfer_amount: ''
},
booking: {
amount: '',
bankin_amount: '',
timeout: 1,
term : '123',
user_bankslip_path: null,
reject_reason: null,
},
rules: {
transfer_amount: [{
required: true,
message: 'Please input amount',
trigger: 'change'
}]
},
active_bank_setting: {
x1_bank_id: null,
x2_bank_id: null,
beneficiary_id: null
},
bankDetail: {}
}
},
beforeCreate () {
const loading = this.$loading({
lock: true,
text: 'Please wait..',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
axios.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.booking.amount = response.data.amount;
this.booking.bankin_amount = response.data.bia;
this.booking.timeout = response.data.timeout * 1000;
this.booking.term = response.data.term;
if (response.data.user_bankslip_path)
{
this.booking.user_bankslip_path = response.data.user_bankslip_path
this.booking.reject_reason = response.data.reject_reason
}
console.log(this.booking);
this.start = true;
if (this.booking.timeout < 0){
this.$message({
showClose: true,
message: 'Booking timeout, please make another booking.',
type: 'error',
duration: 30000
export default {
middleware: ['auth'],
name: 'MyComponent',
components: {
'vue-countdown': VueCountdown,
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data() {
return {
trackerConfig: {
status: 2,
term: null
},
start: false,
loading: false,
dialogImageUrl: '',
imageUrl: null,
dialogVisible: false,
booking_id: this.$route.params.id,
user_slip_form: {
transfer_amount: ''
},
booking: {
amount: '',
bankin_amount: '',
timeout: 1,
term: '123',
user_bankslip_path: null,
reject_reason: null,
},
rules: {
transfer_amount: [{
required: true,
message: 'Please input amount',
trigger: 'change'
}]
},
active_bank_setting: {
x1_bank_id: null,
x2_bank_id: null,
beneficiary_id: null
},
bankDetail: {}
}
},
beforeCreate() {
const loading = this.$loading({
lock: true,
text: 'Please wait..',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
this.$router.push({
name: 'home'
})
}
}).catch((error) => {
this.$router.push({
name: 'notfound'
})
console.log(error)
})
axios.get('/api/active-bank')
.then((response) => {
this.active_bank_setting = response.data;
var url = '';
if(this.booking.term === 'x1_cash' || this.booking.term === 'x1_cheque' ||this.booking.term === 'x1_ba'){
url = '/api/malaysia-bank/' + this.active_bank_setting.x1_bank_id;
}
else if(this.booking.term === 'x2_cash' || this.booking.term === 'x2_cheque' ||this.booking.term === 'x2_ba'){
url = '/api/malaysia-bank/' + this.active_bank_setting.x2_bank_id;
}
axios.get(url)
.then((response) => {
this.bankDetail = response.data;
loading.close()
})
.catch((error) => {
loading.close()
console.log(error);
axios.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.booking.amount = response.data.amount;
this.booking.bankin_amount = response.data.bia;
this.booking.timeout = response.data.timeout * 1000;
this.booking.term = response.data.term;
this.booking.status = response.data.status; this.trackerConfig.term = response.data.term
if (response.data.user_bankslip_path) {
this.booking.user_bankslip_path = response.data.user_bankslip_path
this.booking.reject_reason = response.data.reject_reason
}
console.log(this.booking);
this.start = true;
if (this.booking.timeout < 0) {
this.$message({
showClose: true,
message: 'Fetch data fail',
message: 'Booking timeout, please make another booking.',
type: 'error',
duration: 10000
duration: 30000
})
this.$router.push({
name: 'home'
})
}
}).catch((error) => {
this.$router.push({
name: 'notfound'
})
console.log(error)
})
axios.get('/api/active-bank')
.then((response) => {
this.active_bank_setting = response.data;
var url = '';
if (this.booking.term === 'x1_cash' || this.booking.term === 'x1_cheque' || this.booking.term === 'x1_ba') {
url = '/api/malaysia-bank/' + this.active_bank_setting.x1_bank_id;
} else if (this.booking.term === 'x2_cash' || this.booking.term === 'x2_cheque' || this.booking.term === 'x2_ba') {
url = '/api/malaysia-bank/' + this.active_bank_setting.x2_bank_id;
}
axios.get(url)
.then((response) => {
this.bankDetail = response.data;
loading.close()
})
.catch((error) => {
loading.close()
console.log(error);
this.$message({
showClose: true,
message: 'Fetch data fail',
type: 'error',
duration: 10000
});
});
})
.catch((error) => {
console.log(error);
this.$message({
showClose: true,
message: 'Fetch bank details fail',
type: 'error',
duration: 10000
});
})
.catch((error) => {
console.log(error);
});
},
methods: {
handleUploadSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw);
this.$message({
showClose: true,
message: 'Fetch data fail',
type: 'error',
duration: 10000
});
});
},
methods: {
handleCoutdownend () {
this.$message({
showClose: true,
message: 'Booking timeout, please make another booking.',
type: 'error',
duration: 30000
})
this.$router.push({
name: 'home'
})
},
handleRemove (file, fileList) {
// console.log(file, fileList)
},
uploadError(file,fileList){
this.$message.warning(`Incorrect file format or file size too big.`)
},
handlePictureCardPreview (file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
submitUserSlip (formName) {
this.loading = true
this.$refs[formName].validate((valid) => {
if (valid) {
let newConfirmation = {
amount: this.booking.amount,
term: this.term
}
} else {
this.loading = false
}
})
let newUserSlip = {
transfer_amount: this.user_slip_form.transfer_amount
}
axios.patch('/api/booking/' + this.booking_id + '/bankslip-amount', newUserSlip)
.then((response) => {
this.$message({
showClose: true,
message: 'Your bankinslip has been submitted, please wait admin to approve.',
type: 'success',
duration: 5000
message: 'Uploaded.',
type: 'success',
duration: 5000
})
},
beforeFileUpload(file) {
//const isJPG = file.type === 'image/jpeg';
const isLt10M = file.size / 10240 / 10240 < 2;
// if (!isJPG) {
// this.$message.error('Avatar picture must be JPG format!');
// }
if (!isLt10M) {
this.$message.error('File size can not exceed 10MB!');
}
this.$router.push({
name: 'home'
})
})
.catch((error) => {
this.loading = false
this.$message({
showClose: true,
message: 'Please upload your bankin slip first.',
type: 'warning',
duration: 10000
showClose: true,
message: 'Uploading..',
type: 'success',
duration: 5000
})
console.log(error)
})
},
handleTimeExpire () {
alert('Booking expired')
},
startTimer () {
this.start = true;
// return isJPG && isLt2M;
return isLt10M;
},
handleCoutdownend() {
this.$message({
showClose: true,
message: 'Booking timeout, please make another booking.',
type: 'error',
duration: 30000
})
this.$router.push({
name: 'home'
})
},
handleRemove(file, fileList) {
// console.log(file, fileList)
},
uploadError(file, fileList) {
this.$message.warning(`Incorrect file format or file size too big.`)
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
submitUserSlip(formName) {
this.loading = true
this.$refs[formName].validate((valid) => {
if (valid) {
let newConfirmation = {
amount: this.booking.amount,
term: this.term
}
} else {
this.loading = false
}
})
let newUserSlip = {
transfer_amount: this.user_slip_form.transfer_amount
}
axios.patch('/api/booking/' + this.booking_id + '/bankslip-amount/', newUserSlip)
.then((response) => {
console.log(response);
this.$message({
showClose: true,
message: 'Your bankinslip has been submitted, please wait admin to approve.',
type: 'success',
duration: 5000
})
this.$router.push({
name: 'home'
})
})
.catch((error) => {
this.loading = false
this.$message({
showClose: true,
message: 'Please upload your bankin slip first.',
type: 'warning',
duration: 10000
})
console.log(error)
})
},
handleTimeExpire() {
alert('Booking expired')
},
startTimer() {
this.start = true;
}
}
}
}
</script>
</script>
@@ -0,0 +1,196 @@
<template>
<el-main>
<x2-progress-track v-if="(booking_details.status == 'x2_cash' || booking_details.status == 'x2_cheque' || booking_details.status == 'x2_ba')"
v-model="trackerConfig" />
<progress-track v-else v-model="trackerConfig" />
<h1>Order Completed</h1>
<div class="goBackButton">
<el-button type="primary" @click="$router.go(-1)">Go Back</el-button>
</div>
<!-- bankslip -->
<div class="row">
<div class="col">
<div class="card">
<div class="card-header">China Bank Slip</div>
<div class="row">
<div v-for="cn_bankslip in booking_details.china_bankslip_path" :key='cn_bankslip'>
<a target="_blank" :href="getURL(cn_bankslip)">
<img v-if="isImage(cn_bankslip)" v-bind:src="cn_bankslip" class="image">
<p v-else>Download</p>
<br/>
</a>
</div>
</div>
</div>
</div>
</div>
<!-- order details -->
<div class="card">
<div class="card-header">Order Details</div>
<div class="card-body">
<div class="row">
<div class="col">
<table class="table table-striped">
<tbody>
<tr>
<td>Ref No :</td>
<td>{{ booking_details.id }}</td>
</tr>
<tr>
<td>Date :</td>
<td>{{ booking_details.created_at }}</td>
</tr>
<tr>
<td>Customer Marking :</td>
<td>{{ booking_details.marking }}</td>
</tr>
<tr>
<td>Term: </td>
<td>{{ booking_details.term }}</td>
</tr>
</tbody>
</table>
</div>
<div class="col">
<table class="table table-striped">
<tbody>
<tr>
<td>CNY/RMB :</td>
<td>CNY {{ booking_details.amount }}</td>
</tr>
<tr>
<td>+ Service Charge :</td>
<td>CNY {{ booking_details.service_charge }}</td>
</tr>
<tr>
<td>RATE :</td>
<td>{{ booking_details.rate }}</td>
</tr>
<tr>
<td></td>
<td>
<b>MYR {{ booking_details.bia }}</b>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">Order Bankin Slip</div>
<div class="row">
<div class="card-body">
<a target="_blank" :href="getURL(booking_details.user_bankslip_path)">
<img v-if="isImage(booking_details.user_bankslip_path)" v-bind:src="booking_details.user_bankslip_path" class="image">
<p v-else>Download</p>
</a>
</div>
</div>
</div>
</el-main>
</template>
<style>
h1 {
margin-top: 5%;
font-size: 3vw;
text-align: center;
margin-bottom: 3%;
}
.goBackButton {
text-align: center;
margin-bottom: 3%;
}
.uploadedImage {
border: 1px solid #ddd;
border-radius: 4px;
margin-left: auto;
margin-right: auto;
width: 150px;
display: block;
}
.uploadedImage:hover {
box-shadow: 0 0 2px 1px rgba(0, 140, 186, 0.5);
}
.card {
margin-bottom: 3%;
}
@media screen and (max-width: 767px) {
.table {
font-size: 3.5vmin;
}
h1 {
font-size: 1em;
}
}
</style>
<script>
import ProgressTrack from '~/components/ProgressTrack'
import X2ProgressTrack from '~/components/X2ProgressTrack'
import axios from 'axios'
export default {
components: {
'progress-track': ProgressTrack,
'x2-progress-track': X2ProgressTrack
},
data() {
return {
trackerConfig: {
status: 7,
term: null,
},
loading_btn: false,
booking_details: {
id: null,
amount: null,
bia: null,
user_bankslip_path: null,
}
}
},
beforeCreate() {
const loading = this.$loading({
lock: true,
text: 'Please wait..',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
axios
.get('/api/booking/' + this.$route.params.id)
.then((response) => {
this.booking_details = response.data
this.trackerConfig.term = response.data.term
loading.close();
}).catch((error) => {
console.log(error)
loading.close()
this.$router.push({
name: 'notfound'
})
})
},
methods: {
getExtension(path) {
return path.slice(-3);
},
isImage(path) {
var ext = this.getExtension(path);
return ext === 'jpg' || ext === 'jpeg' || ext === 'bmp' || ext === 'png';
},
getURL(path) {
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
return baseUrl + path;
}
}
}
</script>
+192 -34
View File
@@ -22,7 +22,7 @@
<!-- Input-Amount-end -->
<div align="right">
<el-button icon="el-icon-refresh" type="primary" size="mini" @click="refreshRate()">Refresh Rate</el-button></div>
<el-button type="primary" :loading="loading_btn" size="mini" @click="refreshRate()">Refresh Rate</el-button></div>
<hr>
<!-- Rate-Display -->
@@ -142,18 +142,26 @@
<!-- Form_popup -->
<el-dialog :visible.sync="dialogFormVisible" :fullscreen="true" title="Booking" center>
<el-form ref="bookingForm" :model="bookingForm" :rules="rules">
<div align="center">
<div align="center">
<el-form-item prop="payment_for"> <!-- TODO : this should be payment for order number -->
<el-select v-model="bookingForm.payment_for" placeholder="Payment For" style="width: 80%" required="true">
<el-option v-for="item in options3" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item prop="order_no">
<el-input v-model="bookingForm.order_no" placeholder="Order No. (Optional)" style="width: 80%" required="true" />
</el-form-item>
<el-form-item prop="account_name">
<el-input v-model="bookingForm.account_name" placeholder="China Beneficiary Account" style="width: 80%" required="true" />
<el-input v-model="bookingForm.account_name" placeholder="China Beneficiary Name" style="width: 80%" required="true" />
</el-form-item>
<el-form-item prop="bank_name">
<el-input v-model="bookingForm.bank_name" type="text" placeholder="Bank Name / AliPay / WechatPay" style="width: 80%" />
<el-input v-model="bookingForm.bank_name" type="text" placeholder="Bank Name" style="width: 80%" />
</el-form-item>
<el-form-item prop="bank_branch">
<el-input v-model="bookingForm.bank_branch" type="text" placeholder="Branch / 分行/支行" style="width: 80%" />
</el-form-item>
<el-form-item prop="account_num">
<el-input v-model="bookingForm.account_num" type="text" placeholder="Account Number / AliPay_ID / WechatPay_ID" style="width: 80%"
<el-input v-model="bookingForm.account_num" type="text" placeholder="Account Number" style="width: 80%"
/>
</el-form-item>
<el-form-item>
@@ -178,9 +186,13 @@
<td>Customer Marking : </td>
<td> {{ bookingConfirmTable.marking }}</td>
</tr>
<tr>
<tr v-if="bookingConfirmTable.order_no != null">
<td>Payment for (Order No.) : </td>
<td> {{ bookingConfirmTable.payment_order }}</td>
<td> {{ bookingConfirmTable.order_no }}</td>
</tr>
<tr>
<td>Payment for : </td>
<td> {{ bookingConfirmTable.payment_for }}</td>
</tr>
<tr>
<td>Payment Method : </td>
@@ -197,45 +209,62 @@
<tr>
<td>CNY/RMB :</td>
<td>
<b> RM {{ bookingConfirmTable.amount }}</b>
<b> CNY {{ bookingConfirmTable.amount }}</b>
</td>
</tr>
<tr>
<td>+ Service Charges :</td>
<td>
RM {{ bookingConfirmTable.service_charge }}
CNY {{ bookingConfirmTable.service_charge }}
</td>
</tr>
<tr>
<td>/ Rate :</td>
<td>
{{ bookingConfirmTable.rate }}
{{ bookingConfirmTable.rate }}
</td>
</tr>
<tr>
<td></td>
<td>
RM {{ bookingConfirmTable.subtotal }}
MYR {{ bookingConfirmTable.subtotal }}
</td>
</tr>
<tr>
<td>+ Tax :</td>
<td>
RM {{ bookingConfirmTable.taxAmount }}
MYR {{ bookingConfirmTable.taxAmount }}
</td>
</tr>
<tr>
<td>+ Billing Charge :</td>
<td>
RM {{ bookingConfirmTable.billingChargeAmount }}
MYR {{ bookingConfirmTable.billingChargeAmount }}
</td>
</tr>
<tr>
<td>Bank In Amount :</td>
<td>
<b> RM {{ bookingConfirmTable.bankin_amount }}</b>
<b> MYR {{ bookingConfirmTable.bankin_amount }}</b>
</td>
</tr>
<tr>
<td>China Beneficiary Acc : <br>
Name : {{ bookingConfirmTable.acc_name }} <br>
Account No. : {{ bookingConfirmTable.acc_no }} <br>
Bank : {{ bookingConfirmTable.bank_name }}<br>
Branch. : {{ bookingConfirmTable.bank_branch }}
</td>
<td></td>
</tr>
<tr>
<td>Bank In Amount :</td>
<td><b>RM {{ bookingConfirmTable.bankin_amount }}</b></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<span slot="footer" class="dialog-footer">
@@ -251,10 +280,65 @@
<div align="right">
<el-button :loading="loading_btn" type="primary" size="mini" @click="RefreshBooking()">Refresh</el-button></div>
<!-- Booking Table -->
<el-row :gutter="20">
<el-tabs type="border-card" class="table-switch">
<el-tab-pane label="Booking Table">
<el-row :gutter="20">
<div>
<el-table :data="bookingTable">
<el-table-column label="No." width="100">
<el-table-column label="Ref No." width="100">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">Update</el-button>
<el-button slot-scope="scope" type="text" @click="(event) => { BookingStatus(scope.row.status, scope.row.id, scope.row.term) }"> {{ scope.row.id }}</el-button>
</el-table-column>
<el-table-column label="DateTime" prop="created_at" width="180" sortable/>
<el-table-column :filters="[{text: 'X1', value: 'X1'}, {text: 'X2', value: 'X2'}]" :filter-method="filterHandler" label="Term" prop="term" width="100"/> -->
<el-table-column label="Rate" width="74" prop="rate" />
<el-table-column label="Amount" prop="amount" justify="center" width="110" />
<el-table-column :filters="[{text: 'RMB', value: 'RMB'}, {text: 'USD', value: 'USD'}]" :filter-method="filterHandler" label="Transfer Amount"
prop="transfer_amount" width="170" />
<!-- <el-table-column label="ETA" sortable width="100"/> -->
<!-- <el-table-column label="Payment Method" :filters="[{text: 'Cash', value: 'Cash'}, {text: 'Cheque', value: 'Cheque'}, {text: 'BA', value: 'BA'}]" :filter-method="filterHandler">
</el-table-column> -->
<!-- <el-table-column :filters="[{text: '(1/6)', value: '(1/6) Order Done'}, {text: '(2/6)', value: '(2/6) Waiting for Upload Bank in Slip'}, {text: '(3/6)', value: '(3/6) Order Confirmation'}, {text: '(4/6)', value: '(4/6) Processing Transfer'}, {text: '(5/6)', value: '(5/6) Waiting for Upload PO'}, {text: '(6/6)', value: '(6/6) Order Complete'}]" :filter-method="filterHandler" prop="status" label="Status"/> -->
<el-table-column label="Status" width="106">
<template slot-scope="scope">
<el-popover trigger="click" placement="top">
<p>{{ scope.row.status_desc }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.track_status }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<!-- <el-table-column label="Balance" prop="transfer_amount" sortable width="100"/> -->
<!-- <el-table-column prop="timeout" label="Bankin Timeout" /> -->
<el-table-column :filters="[{ text: 'Success', value: 'Success' }, { text: 'Pending', value: 'Pending' }]" :filter-method="filterTag"
label="" width="180" filter-placement="bottom-end">
<el-button slot-scope="scope" type="text" @click="(event) => { BookingStatus(scope.row.status, scope.row.id, scope.row.term) }"> View Status </el-button>
<!-- <template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">View Status</el-button>
<el-button size="mini" type="danger" @click="BookingStatus(scope.$index, scope.row)">Cancel</el-button>
</template> -->
</el-table-column>
</el-table>
<div align="right">
<el-button type="primary" size="mini" @click="fetchPaginateBooking(pagination.prev_page_url)" :disabled="!pagination.prev_page_url">
Previous
</el-button>
<span>Page {{pagination.current_page}} of {{pagination.last_page}}</span>
<el-button type="primary" size="mini" @click="fetchPaginateBooking(pagination.next_page_url)" :disabled="!pagination.next_page_url">
Next
</el-button>
</div>
</div>
</el-row><br><br></el-tab-pane>
<el-tab-pane label="Completed">
<el-row :gutter="20">
<div>
<el-table :data="bookingTableComplete">
<el-table-column label="Ref No." width="100">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">Update</el-button>
<el-button slot-scope="scope" type="text" @click="(event) => { BookingStatus(scope.row.status, scope.row.id) }"> {{ scope.row.id }}</el-button>
</el-table-column>
@@ -288,19 +372,24 @@
<el-button size="mini" type="danger" @click="BookingStatus(scope.$index, scope.row)">Cancel</el-button>
</template> -->
</el-table-column>
</el-table>
</div>
</el-row><br><br>
<div align="right">
<el-button type="primary" size="mini" @click="fetchPaginateBooking(pagination.prev_page_url)" :disabled="!pagination.prev_page_url">
<div align="right">
<el-button type="primary" size="mini" @click="fetchCompletePaginateBooking(completePagination.prev_page_url)" :disabled="!completePagination.prev_page_url">
Previous
</el-button>
<span>Page {{pagination.current_page}} of {{pagination.last_page}}</span>
<el-button type="primary" size="mini" @click="fetchPaginateBooking(pagination.next_page_url)" :disabled="!pagination.next_page_url">
<span>Page {{completePagination.current_page}} of {{completePagination.last_page}}</span>
<el-button type="primary" size="mini" @click="fetchCompletePaginateBooking(completePagination.next_page_url)" :disabled="!completePagination.next_page_url">
Next
</el-button>
</div>
</div>
</el-row><br><br>
</el-tab-pane>
</el-tabs>
<!-- Booking Table-end -->
</el-main>
</template>
<style>
@@ -319,6 +408,7 @@ export default {
data () {
return {
loading_btn: false,
confirmForm: new Form({
term: '',
amount: ''
@@ -338,13 +428,23 @@ export default {
amount: '',
rate: ''
},
bookingForm: [{
bookingForm: {
account_name: '',
bank_name: '',
bank_branch: '',
account_num: ''
}],
},
rules: {
// order_no: [{
// required: true,
// message: 'Please input order number',
// trigger: 'change'
// }],
payment_for: [{
required: true,
message: 'Please input payment for',
trigger: 'change'
}],
amount: [{
required: true,
message: 'Please input amount',
@@ -380,14 +480,32 @@ export default {
value2: 'MYR',
label2: 'MYR'
}],
options3: [{
value: 'Full Payment',
label: 'Full Payment'
},
{
value: 'Deposit',
label: 'Deposit'
},
{
value: 'Balance',
label: 'Balance'
},
{
value: 'Others',
label: 'Others'
}],
value: 'RMB',
dialogFormVisible: false,
dialogFormVisible1: false,
formLabelWidth: '0px',
bookingTable: [
],
bookingTable: [],
bookingTableComplete: [],
url: 'api/booking',
completeBookingurl : "api/user-complete-booking",
pagination: [],
completePagination: [],
bookingConfirmTable: {
date: 'undefined',
marking: 'undefined',
@@ -397,6 +515,8 @@ export default {
rate: 'undefined',
bankin_amount: 'undefined',
china_beneficiary: 'undefined',
bank_name: null,
bank_branch: null,
status: 2
}
}
@@ -405,6 +525,7 @@ export default {
this.getBooking();
this.initBooking();
this.getRate();
this.getCompleteBooking();
},
methods: {
getBooking(){
@@ -412,7 +533,13 @@ export default {
axios.get(this.url).then(response => {
this.bookingTable = response.data.data
$this.makePagination(response.data)
console.log(response)
})
},
getCompleteBooking(){
let $this = this
axios.get(this.completeBookingurl).then(response => {
this.bookingTableComplete = response.data.data
$this.makeCompletePagination(response.data)
})
},
getRate() {
@@ -423,7 +550,9 @@ export default {
},
refreshRate() {
let $this = this
this.loading_btn = true
axios.get('api/rate').then(response => {
this.loading_btn = false
this.rate = response.data
this.$message({
showClose: true,
@@ -461,12 +590,28 @@ export default {
prev_page_url: data.prev_page_url
}
this.pagination = pagination
console.log(this.pagination)
},
makeCompletePagination(data){
let pagination ={
current_page: data.current_page,
last_page: data.last_page,
next_page_url: data.next_page_url,
prev_page_url: data.prev_page_url
}
this.completePagination = pagination
},
fetchPaginateBooking(url) {
this.url = url
this.getBooking()
},
fetchCompletePaginateBooking(url) {
this.completeBookingurl = url
this.getCompleteBooking()
},
// TODO fetch booking data on load
formatter (row, column) {
return row.address
@@ -496,16 +641,18 @@ export default {
if (valid) {
let newConfirmation = {
amount: this.booking.amount,
term: this.term
term: this.term,
order_no: this.bookingForm.order_no,
payment_for: this.bookingForm.payment_for,
acc_name: this.bookingForm.account_name,
acc_no: this.bookingForm.account_num,
bank_name: this.bookingForm.bank_name,
bank_branch: this.bookingForm.bank_branch
}
axios.post('api/booking/calculation', newConfirmation)
.then((response) => {
this.loading = false
console.log(response)
this.bookingConfirmTable = response.data;
this.bookingConfirmTable.payment_for = 'Full Payment';//For future purpose
this.bookingConfirmTable.remark = '';//For future purpose
this.bookingConfirmTable.payment_order = '';//For future purpose
this.dialogFormVisible = false
this.dialogFormVisible1 = true
})
@@ -534,6 +681,8 @@ export default {
this.loading = true,
this.dialogFormVisible1 = true
let newBooking = {
order_no: this.bookingForm.order_no,
payment_for: this.bookingForm.payment_for,
account_name: this.bookingForm.account_name,
account_num: this.bookingForm.account_num,
bank_name: this.bookingForm.bank_name,
@@ -543,6 +692,7 @@ export default {
}
axios.post('api/booking', newBooking)
.then((response) => {
console.log(response);
this.loading = false
// push with return id
this.$router.push({
@@ -563,7 +713,7 @@ export default {
})
},
BookingStatus (status, booking_id) {
BookingStatus (status, booking_id, term) {
console.log(status)
// TODO : Get booking status from server
this.status = status
@@ -595,6 +745,14 @@ export default {
break
case 5:
console.log(term)
if(term == 'x2_cash' || term == 'x2_cheque' || term == 'x2_ba'){
this.$router.push({
name: 'booking.user.x2complete',
params: {id: booking_id }
})
break
}
this.$router.push({
name: 'booking.user.uploadpo',
params: {id: booking_id }
@@ -99,6 +99,10 @@ export default {
label : item.acc_no,
};
});
this.options_china_bank.unshift({
value : 0,
label : "Use Customer's Beneficiary"
});
})
.catch((error) => {
console.log(error);
@@ -22,38 +22,38 @@
<!-- popup add new data -->
<el-dialog title="Add New Data" align="center" :visible.sync="AddDatadialogVisible" width="40%">
<el-form label-width="150px">
<el-form-item label="Company Name" :class="{'has-error': errors.has('company_name') }">
<el-form-item label="Company Name">
<el-input v-model="beneficiariesForm.company_name" v-validate="'required|max:191'" name="company_name"></el-input>
<span class="error-message text-danger" v-if="errors.has('company_name')">{{ errors.first('company_name') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Name" :class="{'has-error': errors.has('bank_name') }">
<el-form-item label="Bank Name">
<el-input v-model="beneficiariesForm.bank_name" v-validate="'required|max:191'" name="bank_name"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_name')">{{ errors.first('bank_name') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Account No" :class="{'has-error': errors.has('acc_no') }">
<el-form-item label="Bank Account No">
<el-input v-model="beneficiariesForm.acc_no" v-validate="'required|max:191'" name="acc_no"></el-input>
<span class="error-message text-danger" v-if="errors.has('acc_no')">{{ errors.first('acc_no') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Address" :class="{'has-error': errors.has('bank_address') }">
<el-form-item label="Bank Address">
<el-input v-model="beneficiariesForm.bank_address" v-validate="'required|max:191'" name="bank_address"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_address')">{{ errors.first('bank_address') }}<br/></span>
</el-form-item>
<el-form-item label="SWIFT Code" :class="{'has-error': errors.has('swift') }">
<el-form-item label="SWIFT Code">
<el-input v-model="beneficiariesForm.swift" v-validate="'required|max:191'" name="swift"></el-input>
<span class="error-message text-danger" v-if="errors.has('swift')">{{ errors.first('swift') }}<br/></span>
</el-form-item>
<el-form-item label="CNAP" :class="{'has-error': errors.has('cnap') }">
<el-form-item label="CNAP">
<el-input v-model="beneficiariesForm.cnap" v-validate="'required|max:191'" name="cnap" ></el-input>
<span class="error-message text-danger" v-if="errors.has('cnap')">{{ errors.first('cnap') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Branch" :class="{'has-error': errors.has('bank_branch') }">
<el-form-item label="Bank Branch">
<el-input v-model="beneficiariesForm.bank_branch" v-validate="'required|max:191'" name="bank_branch"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_branch')">{{ errors.first('bank_branch') }}<br/></span>
</el-form-item>
</el-form>
<div align="center">
<el-button @click="AddDatadialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="CreateBeneficiaries" :disabled="errors.any() || beneficiariesForm.company_name=='' || beneficiariesForm.bank_name=='' || beneficiariesForm.acc_no=='' || beneficiariesForm.bank_address=='' || beneficiariesForm.swift =='' || beneficiariesForm.cnap=='' || beneficiariesForm.bank_branch=='' ? true : false">OK</el-button>
<el-button type="primary" :loading="loading_btn" @click="CreateBeneficiaries" :disabled="beneficiariesForm.company_name=='' || beneficiariesForm.bank_name=='' || beneficiariesForm.acc_no=='' || beneficiariesForm.bank_address=='' || beneficiariesForm.swift =='' || beneficiariesForm.cnap=='' || beneficiariesForm.bank_branch=='' ? true : false">OK</el-button>
</div>
<span slot="footer" class="dialog-footer">
* Please key in the data in Chinese
@@ -62,45 +62,43 @@
<el-dialog align="center" :visible.sync="DoneAddDatadialogVisible" width="30%">
<span>Data Added Successfully</span><br><br>
<div align="center">
<el-button type="primary" @click="DoneAddDatadialogVisible = false">OK</el-button>
<el-button type="primary" :loading="loading_btn" @click="DoneAddDatadialogVisible = false">OK</el-button>
</div>
</el-dialog>
<!-- popup add new data end -->
<!-- popup edit data -->
<el-dialog title="Edit Data" align="center" :visible.sync="EditDatadialogVisible" width="40%">
<el-form label-width="150px">
<el-form-item label="Company Name" :class="{'has-error': errors.has('company_name') }">
<el-input v-model="beneficiariesForm.company_name" v-validate="'required|max:191'" name="company_name"></el-input>
<span class="error-message text-danger" v-if="errors.has('company_name')">{{ errors.first('company_name') }}<br/></span>
<el-form-item label="Company Name">
<el-input v-model="beneficiariesForm.company_name" v-validate="'required|max:191'" name="company_name"></el-input>
</el-form-item>
<el-form-item label="Bank Name" :class="{'has-error': errors.has('bank_name') }">
<el-form-item label="Bank Name">
<el-input v-model="beneficiariesForm.bank_name" v-validate="'required|max:191'" name="bank_name"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_name')">{{ errors.first('bank_name') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Account No" :class="{'has-error': errors.has('acc_no') }">
<el-form-item label="Bank Account No">
<el-input v-model="beneficiariesForm.acc_no" v-validate="'required|max:191'" name="acc_no"></el-input>
<span class="error-message text-danger" v-if="errors.has('acc_no')">{{ errors.first('acc_no') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Address" :class="{'has-error': errors.has('bank_address') }">
<el-form-item label="Bank Address">
<el-input v-model="beneficiariesForm.bank_address" v-validate="'required|max:191'" name="bank_address"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_address')">{{ errors.first('bank_address') }}<br/></span>
</el-form-item>
<el-form-item label="SWIFT Code" :class="{'has-error': errors.has('swift') }">
<el-form-item label="SWIFT Code">
<el-input v-model="beneficiariesForm.swift" v-validate="'required|max:191'" name="swift"></el-input>
<span class="error-message text-danger" v-if="errors.has('swift')">{{ errors.first('swift') }}<br/></span>
</el-form-item>
<el-form-item label="CNAP" :class="{'has-error': errors.has('cnap') }">
<el-form-item label="CNAP">
<el-input v-model="beneficiariesForm.cnap" v-validate="'required|max:191'" name="cnap" ></el-input>
<span class="error-message text-danger" v-if="errors.has('cnap')">{{ errors.first('cnap') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Branch" :class="{'has-error': errors.has('bank_branch') }">
<el-form-item label="Bank Branch">
<el-input v-model="beneficiariesForm.bank_branch" v-validate="'required|max:191'" name="bank_branch"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_branch')">{{ errors.first('bank_branch') }}<br/></span>
</el-form-item>
</el-form>
<div align="center">
<el-button @click="EditDatadialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="EditBeneficiaries" :disabled="errors.any() || beneficiariesForm.company_name=='' || beneficiariesForm.bank_name=='' || beneficiariesForm.acc_no=='' || beneficiariesForm.bank_address=='' || beneficiariesForm.swift =='' || beneficiariesForm.cnap=='' || beneficiariesForm.bank_branch=='' ? true : false">Submit</el-button>
<el-button type="primary" :loading="loading_btn" @click="EditBeneficiaries" :disabled="beneficiariesForm.company_name=='' || beneficiariesForm.bank_name=='' || beneficiariesForm.acc_no=='' || beneficiariesForm.bank_address=='' || beneficiariesForm.swift =='' || beneficiariesForm.cnap=='' || beneficiariesForm.bank_branch=='' ? true : false">Submit</el-button>
</div>
<span slot="footer" class="dialog-footer">
* Please key in the data in Chinese
@@ -109,7 +107,7 @@
<el-dialog align="center" :visible.sync="DoneUpdateDatadialogVisible" width="30%">
<span>Data Updated Successfully</span><br><br>
<div align="center">
<el-button type="primary" @click="DoneUpdateDatadialogVisible = false">OK</el-button>
<el-button type="primary" :loading="loading_btn" @click="DoneUpdateDatadialogVisible = false">OK</el-button>
</div>
</el-dialog>
<!-- popup edit data end -->
@@ -117,7 +115,7 @@
<el-dialog align="center" :visible.sync="DeleteAdddialogVisible" width="30%">
<span>Data Deleted</span><br><br>
<div align="center">
<el-button type="primary" @click="DeleteAdddialogVisible = false">OK</el-button>
<el-button type="primary" :loading="loading_btn" @click="DeleteAdddialogVisible = false">OK</el-button>
</div>
</el-dialog>
<!-- popup delete end -->
@@ -130,6 +128,7 @@
export default {
data() {
return {
loading_btn: false,
tableData: [],
beneficiariesForm : {
company_name : '',
@@ -153,14 +152,17 @@
},
methods: {
CreateBeneficiaries : function(){
this.loading_btn = true
this.AddDatadialogVisible = false;
axios.post('/api/setting-beneficiary', this.beneficiariesForm)
.then((response) => {
this.loading_btn = false
this.DoneAddDatadialogVisible = true;
this.ClearBeneficiariesForm();
this.UpdateTableData();
})
.catch((error) => {
this.loading_btn = false
console.log(error);
this.$message({
showClose: true,
@@ -172,11 +174,17 @@
});
},
UpdateTableData : function(){
this.loading_btn = true
axios.get('/api/setting-beneficiary', this.beneficiariesForm)
.then((response) => {
this.loading_btn = false
this.tableData = response.data;
})
.catch((error) => {
this.loading_btn = false
console.log(error);
this.$message({
showClose: true,
@@ -187,12 +195,21 @@
})
},
DeleteBeneficiaries : function(beneficiaries_id){
this.loading_btn = true
this.DeleteAdddialogVisible = true;
axios.delete('/api/setting-beneficiary/' + beneficiaries_id)
.then((response) => {
this.loading_btn = false
this.UpdateTableData();
this.$message({
showClose: true,
message: 'Data Deleted Successfully',
type: 'success',
duration: 5000
});
})
.catch((error) => {
this.loading_btn = false
console.log(error);
this.$message({
showClose: true,
@@ -203,14 +220,24 @@
});
},
EditBeneficiaries : function(){
this.loading_btn = true
this.EditDatadialogVisible = false;
this.DoneUpdateDatadialogVisible = true;
axios.put('/api/setting-beneficiary/' + this.currentEdit, this.beneficiariesForm)
.then((response) => {
this.loading_btn = false
this.UpdateTableData();
this.$message({
showClose: true,
message: 'Data Updated Succesfully',
type: 'success',
duration: 5000
});
})
.catch((error) => {
this.loading_btn = false
console.log(error);
this.$message({
showClose: true,
@@ -40,29 +40,19 @@
this.getCreditSetting();
},
methods: {
ValidateAll : function(){
var working;
this.$validator.validateAll().then((result) => {
working = result;
}).catch(() => {
});
},
getCreditSetting() {
axios.get('/api/setting-credit').then(response => {
this.credit_setting = response.data
})
},
updateCreditSetting (){
if(this.ValidateAll())
return;
this.loading_btn = true
axios.put('/api/setting-credit', this.credit_setting)
.then((response) => {
this.loading_btn = false
this.$message({
showClose: true,
message: 'Success',
message: 'Time Limit and Credit Limit Updated Successfully',
type: 'success',
duration: 5000
});
@@ -11,8 +11,8 @@
<el-table-column prop="bank_branch" label="Bank Branch"></el-table-column>
<el-table-column label="Action">
<template slot-scope="scope">
<el-button type="text" size="small" @click="PopOutEditMalaysiaBank(scope.$index)">Edit</el-button>
<el-button type="text" size="small" @click="DeleteMalaysiaBank(tableData[scope.$index].id)">Delete</el-button>
<el-button type="text" size="small" :loading="loading_btn" @click="PopOutEditMalaysiaBank(scope.$index)">Edit</el-button>
<el-button type="text" size="small" :loading="loading_btn" @click="DeleteMalaysiaBank(tableData[scope.$index].id)">Delete</el-button>
</template>
</el-table-column>
</el-table><br>
@@ -22,38 +22,38 @@
<!-- popup add new data -->
<el-dialog title="Add New Data" align="center" :visible.sync="AddDatadialogVisible" width="40%">
<el-form label-width="150px">
<el-form-item label="Company Name" :class="{'has-error': errors.has('company_name') }">
<el-form-item label="Company Name">
<el-input v-model="malaysiaBankForm.company_name" v-validate="'required|max:191'" name="company_name"></el-input>
<span class="error-message text-danger" v-if="errors.has('company_name')">{{ errors.first('company_name') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Name" :class="{'has-error': errors.has('bank_name') }">
<el-form-item label="Bank Name">
<el-input v-model="malaysiaBankForm.bank_name" v-validate="'required|max:191'" name="bank_name"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_name')">{{ errors.first('bank_name') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Account No" :class="{'has-error': errors.has('acc_no') }">
<el-form-item label="Bank Account No">
<el-input v-model="malaysiaBankForm.acc_no" v-validate="'required|max:191'" name="acc_no"></el-input>
<span class="error-message text-danger" v-if="errors.has('acc_no')">{{ errors.first('acc_no') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Address" :class="{'has-error': errors.has('bank_address') }">
<el-form-item label="Bank Address">
<el-input v-model="malaysiaBankForm.bank_address" v-validate="'required|max:191'" name="bank_address"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_address')">{{ errors.first('bank_address') }}<br/></span>
</el-form-item>
<el-form-item label="SWIFT Code" :class="{'has-error': errors.has('swift') }">
<el-form-item label="SWIFT Code">
<el-input v-model="malaysiaBankForm.swift" v-validate="'required|max:191'" name="swift"></el-input>
<span class="error-message text-danger" v-if="errors.has('swift')">{{ errors.first('swift') }}<br/></span>
</el-form-item>
<el-form-item label="CNAP" :class="{'has-error': errors.has('cnap') }">
<el-form-item label="CNAP">
<el-input v-model="malaysiaBankForm.cnap" v-validate="'required|max:191'" name="cnap" ></el-input>
<span class="error-message text-danger" v-if="errors.has('cnap')">{{ errors.first('cnap') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Branch" :class="{'has-error': errors.has('bank_branch') }">
<el-form-item label="Bank Branch">
<el-input v-model="malaysiaBankForm.bank_branch" v-validate="'required|max:191'" name="bank_branch"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_branch')">{{ errors.first('bank_branch') }}<br/></span>
</el-form-item>
</el-form>
<div align="center">
<el-button @click="AddDatadialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="CreateMalaysiaBank" :disabled="errors.any() || malaysiaBankForm.company_name=='' || malaysiaBankForm.bank_name=='' || malaysiaBankForm.acc_no=='' || malaysiaBankForm.bank_address=='' || malaysiaBankForm.swift =='' || malaysiaBankForm.cnap=='' || malaysiaBankForm.bank_branch=='' ? true : false">OK</el-button>
<el-button type="primary" :loading="loading_btn" @click="CreateMalaysiaBank" :disabled="malaysiaBankForm.company_name=='' || malaysiaBankForm.bank_name=='' || malaysiaBankForm.acc_no=='' || malaysiaBankForm.bank_address=='' || malaysiaBankForm.swift =='' || malaysiaBankForm.cnap=='' || malaysiaBankForm.bank_branch=='' ? true : false">OK</el-button>
</div>
<span slot="footer" class="dialog-footer">
* Please key in the data in Chinese
@@ -62,45 +62,45 @@
<el-dialog align="center" :visible.sync="DoneAddDatadialogVisible" width="30%">
<span>Data Added Successfully</span><br><br>
<div align="center">
<el-button type="primary" @click="DoneAddDatadialogVisible = false">OK</el-button>
<el-button type="primary" :loading="loading_btn" @click="DoneAddDatadialogVisible = false">OK</el-button>
</div>
</el-dialog>
<!-- popup add new data end -->
<!-- popup edit data -->
<el-dialog title="Edit Data" align="center" :visible.sync="EditDatadialogVisible" width="40%">
<el-form label-width="150px">
<el-form-item label="Company Name" :class="{'has-error': errors.has('company_name') }">
<el-form-item label="Company Name">
<el-input v-model="malaysiaBankForm.company_name" v-validate="'required|max:191'" name="company_name"></el-input>
<span class="error-message text-danger" v-if="errors.has('company_name')">{{ errors.first('company_name') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Name" :class="{'has-error': errors.has('bank_name') }">
<el-form-item label="Bank Name">
<el-input v-model="malaysiaBankForm.bank_name" v-validate="'required|max:191'" name="bank_name"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_name')">{{ errors.first('bank_name') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Account No" :class="{'has-error': errors.has('acc_no') }">
<el-form-item label="Bank Account No">
<el-input v-model="malaysiaBankForm.acc_no" v-validate="'required|max:191'" name="acc_no"></el-input>
<span class="error-message text-danger" v-if="errors.has('acc_no')">{{ errors.first('acc_no') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Address" :class="{'has-error': errors.has('bank_address') }">
<el-form-item label="Bank Address">
<el-input v-model="malaysiaBankForm.bank_address" v-validate="'required|max:191'" name="bank_address"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_address')">{{ errors.first('bank_address') }}<br/></span>
</el-form-item>
<el-form-item label="SWIFT Code" :class="{'has-error': errors.has('swift') }">
<el-form-item label="SWIFT Code">
<el-input v-model="malaysiaBankForm.swift" v-validate="'required|max:191'" name="swift"></el-input>
<span class="error-message text-danger" v-if="errors.has('swift')">{{ errors.first('swift') }}<br/></span>
</el-form-item>
<el-form-item label="CNAP" :class="{'has-error': errors.has('cnap') }">
<el-form-item label="CNAP">
<el-input v-model="malaysiaBankForm.cnap" v-validate="'required|max:191'" name="cnap" ></el-input>
<span class="error-message text-danger" v-if="errors.has('cnap')">{{ errors.first('cnap') }}<br/></span>
</el-form-item>
<el-form-item label="Bank Branch" :class="{'has-error': errors.has('bank_branch') }">
<el-form-item label="Bank Branch">
<el-input v-model="malaysiaBankForm.bank_branch" v-validate="'required|max:191'" name="bank_branch"></el-input>
<span class="error-message text-danger" v-if="errors.has('bank_branch')">{{ errors.first('bank_branch') }}<br/></span>
</el-form-item>
</el-form>
<div align="center">
<el-button @click="EditDatadialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="EditMalaysiaBank" :disabled="errors.any() || malaysiaBankForm.company_name=='' || malaysiaBankForm.bank_name=='' || malaysiaBankForm.acc_no=='' || malaysiaBankForm.bank_address=='' || malaysiaBankForm.swift =='' || malaysiaBankForm.cnap=='' || malaysiaBankForm.bank_branch=='' ? true : false">Submit</el-button>
<el-button type="primary" :loading="loading_btn" @click="EditMalaysiaBank" :disabled="malaysiaBankForm.company_name=='' || malaysiaBankForm.bank_name=='' || malaysiaBankForm.acc_no=='' || malaysiaBankForm.bank_address=='' || malaysiaBankForm.swift =='' || malaysiaBankForm.cnap=='' || malaysiaBankForm.bank_branch=='' ? true : false">Submit</el-button>
</div>
<span slot="footer" class="dialog-footer">
* Please key in the data in Chinese
@@ -109,7 +109,7 @@
<el-dialog align="center" :visible.sync="DoneUpdateDatadialogVisible" width="30%">
<span>Data Updated Successfully</span><br><br>
<div align="center">
<el-button type="primary" @click="DoneUpdateDatadialogVisible = false">OK</el-button>
<el-button type="primary" :loading="loading_btn" @click="DoneUpdateDatadialogVisible = false">OK</el-button>
</div>
</el-dialog>
<!-- popup edit data end -->
@@ -117,7 +117,7 @@
<el-dialog align="center" :visible.sync="DeleteAdddialogVisible" width="30%">
<span>Data Deleted</span><br><br>
<div align="center">
<el-button type="primary" @click="DeleteAdddialogVisible = false">OK</el-button>
<el-button type="primary" :loading="loading_btn" @click="DeleteAdddialogVisible = false">OK</el-button>
</div>
</el-dialog>
<!-- popup delete end -->
@@ -130,6 +130,7 @@
export default {
data() {
return {
loading_btn: false,
tableData: [],
malaysiaBankForm : {
company_name : '',
@@ -153,14 +154,23 @@
},
methods: {
CreateMalaysiaBank : function(){
this.loading_btn = true
this.AddDatadialogVisible = false;
axios.post('/api/setting-malaysia-bank', this.malaysiaBankForm)
.then((response) => {
this.loading_btn = false
this.DoneAddDatadialogVisible = true;
this.ClearMalaysiaBankForm();
this.UpdateTableData();
})
this.$message({
showClose: true,
message: 'Success',
type: 'success',
duration: 5000
});
})
.catch((error) => {
this.loading_btn = false
console.log(error);
this.$message({
showClose: true,
@@ -172,11 +182,16 @@
});
},
UpdateTableData : function(){
this.loading_btn = true
axios.get('/api/setting-malaysia-bank', this.malaysiaBankForm)
.then((response) => {
this.loading_btn = false;
this.tableData = response.data;
})
.catch((error) => {
this.loading_btn = false
console.log(error);
this.$message({
showClose: true,
@@ -187,12 +202,21 @@
})
},
DeleteMalaysiaBank : function(malaysiaBank_id){
this.loading_btn = true;
this.DeleteAdddialogVisible = true;
axios.delete('/api/setting-malaysia-bank/' + malaysiaBank_id)
.then((response) => {
this.UpdateTableData();
this.$message({
showClose: true,
message: 'Data Deleted Successfully',
type: 'success',
duration: 5000
});
})
.catch((error) => {
this.loading_btn = false;
console.log(error);
this.$message({
showClose: true,
@@ -203,11 +227,20 @@
});
},
EditMalaysiaBank : function(){
this.loading_btn = true;
this.EditDatadialogVisible = false;
this.DoneUpdateDatadialogVisible = true;
axios.put('/api/setting-malaysia-bank/' + this.currentEdit, this.malaysiaBankForm)
.then((response) => {
this.loading_btn = false;
this.UpdateTableData();
this.$message({
showClose: true,
message: 'Updated Successfully',
type: 'success',
duration: 5000
});
})
.catch((error) => {
console.log(error);
@@ -222,8 +255,6 @@
PopOutAddMalaysiaBank : function(){
this.AddDatadialogVisible = true;
this.ClearMalaysiaBankForm();
this.$validator.validateAll();
console.log(this.errors.count());
},
PopOutEditMalaysiaBank : function(tableDataRow){
this.EditDatadialogVisible = true;

Some files were not shown because too many files have changed in this diff Show More