Subiendo proyecto completo sin restricciones de git ignore

This commit is contained in:
Jose Sanchez
2023-08-17 11:44:02 -04:00
parent a0d4f5ba3b
commit 20f1c60600
19921 changed files with 2509159 additions and 45 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -0,0 +1,57 @@
{
"name" : "club_point",
"unique_identifier" : "club_point",
"version" : "1.7",
"minimum_item_version" : "7.0.0",
"addon_banner" : "club_points.png",
"directory" :
[
{
"name" : ["resources/views/club_points", "resources/views/club_points/frontend"]
}
],
"sql_file" : "",
"files" :
[
{
"root_directory" : "addons/club_point/views/club_points/club_point_details.blade.php",
"update_directory" : "resources/views/club_points/club_point_details.blade.php"
},
{
"root_directory" : "addons/club_point/views/club_points/config.blade.php",
"update_directory" : "resources/views/club_points/config.blade.php"
},
{
"root_directory" : "addons/club_point/views/club_points/index.blade.php",
"update_directory" : "resources/views/club_points/index.blade.php"
},
{
"root_directory" : "addons/club_point/views/club_points/product_point_edit.blade.php",
"update_directory" : "resources/views/club_points/product_point_edit.blade.php"
},
{
"root_directory" : "addons/club_point/views/club_points/set_point.blade.php",
"update_directory" : "resources/views/club_points/set_point.blade.php"
},
{
"root_directory" : "addons/club_point/views/club_points/frontend/index.blade.php",
"update_directory" : "resources/views/club_points/frontend/index.blade.php"
},
{
"root_directory" : "addons/club_point/controllers/ClubPointController.php",
"update_directory" : "app/Http/Controllers/ClubPointController.php"
},
{
"root_directory" : "addons/club_point/assets/club_points.png",
"update_directory" : "public/club_points.png"
}
]
}

View File

@@ -0,0 +1,171 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\BusinessSetting;
use App\Models\ClubPointDetail;
use App\Models\ClubPoint;
use App\Models\Product;
use App\Models\Wallet;
use App\Models\Order;
use Artisan;
use Auth;
class ClubPointController extends Controller
{
public function __construct() {
// Staff Permission Check
$this->middleware(['permission:club_point_configurations'])->only('configure_index');
$this->middleware(['permission:set_club_points'])->only('set_point');
$this->middleware(['permission:view_users_club_points'])->only('index');
}
public function configure_index()
{
return view('club_points.config');
}
public function index()
{
$club_points = ClubPoint::latest()->paginate(15);
return view('club_points.index', compact('club_points'));
}
public function userpoint_index()
{
$club_points = ClubPoint::where('user_id', Auth::user()->id)->latest()->paginate(15);
return view('club_points.frontend.index', compact('club_points'));
}
public function set_point()
{
$products = Product::latest()->paginate(15);
return view('club_points.set_point', compact('products'));
}
public function set_products_point(Request $request)
{
$products = Product::whereBetween('unit_price', [$request->min_price, $request->max_price])->get();
foreach ($products as $product) {
$product->earn_point = $request->point;
$product->save();
}
flash(translate('Point has been inserted successfully for ').count($products).translate(' products'))->success();
return redirect()->route('set_product_points');
}
public function set_all_products_point(Request $request)
{
$products = Product::all();
foreach ($products as $product) {;
$product->earn_point = $product->unit_price * $request->point;
$product->save();
}
flash(translate('Point has been inserted successfully for ').count($products).translate(' products'))->success();
return redirect()->route('set_product_points');
}
public function set_point_edit($id)
{
$product = Product::findOrFail(decrypt($id));
return view('club_points.product_point_edit', compact('product'));
}
public function update_product_point(Request $request, $id)
{
$product = Product::findOrFail($id);
$product->earn_point = $request->point;
$product->save();
flash(translate('Point has been updated successfully'))->success();
return redirect()->route('set_product_points');
}
public function convert_rate_store(Request $request)
{
$club_point_convert_rate = BusinessSetting::where('type', $request->type)->first();
if ($club_point_convert_rate != null) {
$club_point_convert_rate->value = $request->value;
}
else {
$club_point_convert_rate = new BusinessSetting;
$club_point_convert_rate->type = $request->type;
$club_point_convert_rate->value = $request->value;
}
$club_point_convert_rate->save();
Artisan::call('cache:clear');
flash(translate('Point convert rate has been updated successfully'))->success();
return redirect()->route('club_points.configs');
}
public function processClubPoints(Order $order)
{
$club_point = new ClubPoint;
$club_point->user_id = $order->user_id;
$club_point->points = 0;
foreach ($order->orderDetails as $key => $orderDetail) {
$total_pts = ($orderDetail->earn_point) * $orderDetail->quantity;
$club_point->points += $total_pts;
}
if($club_point->points > 0){
$club_point->order_id = $order->id;
$club_point->convert_status = 0;
$club_point->save();
foreach ($order->orderDetails as $key => $orderDetail) {
$club_point_detail = new ClubPointDetail;
$club_point_detail->club_point_id = $club_point->id;
$club_point_detail->product_id = $orderDetail->product_id;
$club_point_detail->point = ($orderDetail->earn_point) * $orderDetail->quantity;
$club_point_detail->save();
}
}
}
public function club_point_detail($id)
{
$club_point_details = ClubPointDetail::where('club_point_id', decrypt($id))->paginate(12);
return view('club_points.club_point_details', compact('club_point_details'));
}
public function convert_point_into_wallet(Request $request)
{
$club_point = ClubPoint::findOrFail($request->el);
if($club_point->convert_status == 0) {
$amount = 0;
foreach ($club_point->club_point_details as $club_point_detail) {
if($club_point_detail->refunded == 0){
$club_point_detail->converted_amount = floatval($club_point_detail->point / get_setting('club_point_convert_rate'));
$club_point_detail->save();
$amount += $club_point_detail->converted_amount;
}
}
// Wallet history
$wallet = new Wallet;
$wallet->user_id = Auth::user()->id;
$wallet->amount = $amount;
$wallet->payment_method = 'Club Point Convert';
$wallet->payment_details = 'Club Point Convert';
$wallet->save();
// converted money from the club point, add to the user balance
$user = Auth::user();
$user->balance = $user->balance + $amount;
$user->save();
$club_point->convert_status = 1;
}
if ($club_point->save()) {
return 1;
}
else {
return 0;
}
}
}

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1,2 @@
ALTER TABLE `club_points` ADD `order_id` INT NOT NULL AFTER `points`;
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1,5 @@
ALTER TABLE `club_point_details`
ADD `converted_amount` DOUBLE(25,2) NULL DEFAULT '0.00' AFTER `point`,
ADD `refunded` INT(1) NOT NULL DEFAULT '0' AFTER `converted_amount`;
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1,128 @@
-- phpMyAdmin SQL Dump
-- version 4.9.1
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Mar 16, 2020 at 06:38 AM
-- Server version: 10.4.8-MariaDB
-- PHP Version: 7.3.11
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `shop`
--
-- --------------------------------------------------------
--
-- Table structure for table `club_points`
--
INSERT INTO `business_settings` (`id`, `type`, `value`, `created_at`, `updated_at`) VALUES (NULL, 'club_point_convert_rate', '10', '2019-03-12 05:58:23', '2019-03-12 05:58:23');
CREATE TABLE `club_points` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`points` double(18,2) NOT NULL,
`convert_status` int(1) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `club_points`
--
ALTER TABLE `club_points`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `club_points`
--
ALTER TABLE `club_points`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `shop`
--
-- --------------------------------------------------------
--
-- Table structure for table `club_point_details`
--
CREATE TABLE `club_point_details` (
`id` int(11) NOT NULL,
`club_point_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`product_qty` int(11) NOT NULL,
`point` double(8,2) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `club_point_details`
--
ALTER TABLE `club_point_details`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `club_point_details`
--
ALTER TABLE `club_point_details`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
ALTER TABLE `products` ADD `earn_point` DOUBLE(8,2) NOT NULL DEFAULT '0' AFTER `slug`;
ALTER TABLE `club_points` ADD `order_id` INT NOT NULL AFTER `points`;
ALTER TABLE `club_point_details`
ADD `converted_amount` DOUBLE(8,2) NULL DEFAULT '0.00' AFTER `point`,
ADD `refunded` INT(1) NOT NULL DEFAULT '0' AFTER `converted_amount`;

View File

@@ -0,0 +1,43 @@
@extends('backend.layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<table class="table aiz-table mb-0">
<thead>
<tr>
<th>#</th>
<th>{{translate('Product Name')}}</th>
<th>{{translate('Points')}}</th>
<th data-breakpoints="lg">{{translate('Earned At')}}</th>
</tr>
</thead>
<tbody>
@foreach($club_point_details as $key => $club_point)
<tr>
<td>{{ ($key+1) + ($club_point_details->currentPage() - 1)*$club_point_details->perPage() }}</td>
@if ($club_point->product != null)
<td>{{ $club_point->product->getTranslation('name') }}</td>
@else
<td>{{ translate('Deleted Product') }}</td>
@endif
<td>{{ $club_point->point }}</td>
<td>{{ $club_point->created_at }}</td>
</tr>
@endforeach
</tbody>
</table>
<div class="clearfix">
<div class="pull-right">
{{ $club_point_details->appends(request()->input())->links() }}
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,35 @@
@extends('backend.layouts.app')
@section('content')
<div class="row">
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('Convert Point To Wallet')}}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('point_convert_rate_store') }}" method="POST">
@csrf
<input type="hidden" name="type" value="club_point_convert_rate">
<div class="form-group row">
<div class="col-lg-4">
<label class="col-from-label">{{translate('Set Point For ')}} {{ single_price(1) }}</label>
</div>
<div class="col-lg-5">
<input type="number" min="0" step="0.01" class="form-control" name="value" value="{{ get_setting('club_point_convert_rate') }}" placeholder="100" required>
</div>
<div class="col-lg-3">
<label class="col-from-label">{{translate('Points')}}</label>
</div>
</div>
<div class="form-group mb-3 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{translate('Save')}}</button>
</div>
</form>
<i class="fs-12"><b>{{ translate('Note: You need to activate wallet option first before using club point addon.') }}</b></i>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,113 @@
@extends('frontend.layouts.app')
@section('content')
<section class="py-5">
<div class="container">
<div class="d-flex align-items-start">
@include('frontend.inc.user_side_nav')
<div class="aiz-user-panel">
<div class="aiz-titlebar mt-2 mb-4">
<div class="row align-items-center">
<div class="col-md-6">
<h1 class="fs-20 fw-700 text-dark">{{ translate('My Clubpoints') }}</h1>
</div>
</div>
</div>
<div class="bg-dark overflow-hidden">
<div class="px-3 py-4">
<div class="fs-14 fw-400 text-center text-secondary mb-1">{{ translate('Exchange Rate') }}</div>
<div class="fs-30 fw-700 text-center text-white">{{ get_setting('club_point_convert_rate') }} {{ translate(' Points') }} = {{ single_price(1) }} {{ translate('Wallet Money') }}</div>
</div>
</div>
<br>
<div class="card rounded-0 shadow-none border">
<div class="card-header border-bottom-0">
<h5 class="mb-0 fs-20 fw-700 text-dark">{{ translate('Clubpoint Earning History')}}</h5>
</div>
<div class="card-body">
<table class="table aiz-table mb-0">
<thead class="text-gray fs-12">
<tr>
<th class="pl-0">#</th>
<th>{{translate('Code')}}</th>
<th data-breakpoints="lg">{{translate('Points')}}</th>
<th data-breakpoints="lg">{{translate('Converted')}}</th>
<th data-breakpoints="lg">{{translate('Date') }}</th>
<th class="text-right pr-0">{{translate('Action')}}</th>
</tr>
</thead>
<tbody class="fs-14">
@foreach ($club_points as $key => $club_point)
@php
$convertible_club_point = $club_point->club_point_details->where('refunded',0)->sum('point');
@endphp
<tr>
<td class="pl-0" style="vertical-align: middle;">{{ sprintf('%02d', $key+1) }}</td>
<td class="fw-700 text-primary" style="vertical-align: middle;">
@if ($club_point->order != null)
{{ $club_point->order->code }}
@else
{{ translate('Order not found') }}
@endif
</td>
<td class="fw-700" style="vertical-align: middle;">
@if($convertible_club_point > 0)
{{ $convertible_club_point }} {{ translate(' pts') }}
@else
{{ translate('Refunded') }}
@endif
</td>
<td style="vertical-align: middle;">
@if ($club_point->convert_status == 1)
<span class="badge badge-inline badge-success p-3 fs-12" style="border-radius: 25px;">{{ translate('Yes') }}</strong></span>
@else
<span class="badge badge-inline badge-info p-3 fs-12" style="border-radius: 25px;">{{ translate('No') }}</strong></span>
@endif
</td>
<td style="vertical-align: middle;">{{ date('d-m-Y', strtotime($club_point->created_at)) }}</td>
<td class="text-right pr-0" style="vertical-align: middle;">
@if ($club_point->convert_status == 0 && $convertible_club_point > 0)
<button onclick="convert_point({{ $club_point->id }})" class="btn btn-sm btn-styled btn-primary" style="border-radius: 25px;">{{translate('Convert Now')}}</button>
@elseif($convertible_club_point == 0)
<span class="badge badge-inline text-white badge-warning p-3 fs-12" style="border-radius: 25px; min-width: 80px !important;">{{ translate('Refunded') }}</span>
@else
<span class="badge badge-inline badge-success p-3 fs-12" style="border-radius: 25px; min-width: 80px !important;">{{ translate('Done') }}</span>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="aiz-pagination mt-3">
{{ $club_points->links() }}
</div>
</div>
</div>
</div>
</div>
</div>
</section>
@endsection
@section('script')
<script type="text/javascript">
function convert_point(el)
{
$.post('{{ route('convert_point_into_wallet') }}',{_token:'{{ csrf_token() }}', el:el}, function(data){
if (data == 1) {
location.reload();
AIZ.plugins.notify('success', '{{ translate('Convert has been done successfully Check your Wallets') }}');
}
else {
AIZ.plugins.notify('danger', '{{ translate('Something went wrong') }}');
}
});
}
</script>
@endsection

View File

@@ -0,0 +1,66 @@
@extends('backend.layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<table class="table aiz-table mb-0">
<thead>
<tr>
<th>#</th>
<th>{{translate('Order Code')}}</th>
<th data-breakpoints="lg">{{translate('Customer Name')}}</th>
<th>{{translate('Points')}}</th>
<th data-breakpoints="lg">{{translate('Convert Status')}}</th>
<th data-breakpoints="lg">{{translate('Earned At')}}</th>
<th class="text-right" width="10%">{{translate('Options')}}</th>
</tr>
</thead>
<tbody>
@foreach($club_points as $key => $club_point)
<tr>
<td>{{ ($key+1) + ($club_points->currentPage() - 1)*$club_points->perPage() }}</td>
<td>
@if ($club_point->order != null)
{{ $club_point->order->code }}
@else
{{ translate('Order not found') }}
@endif
</td>
<td>
@if ($club_point->user != null)
{{ $club_point->user->name }}
@else
{{ translate('User not found') }}
@endif
</td>
<td>{{ $club_point->points }}</td>
<td>
@if ($club_point->convert_status == 1)
<span class="badge badge-inline badge-success">{{translate('Converted')}}</span>
@else
<span class="badge badge-inline badge-info">{{translate('Pending')}}</span>
@endif
</td>
<td>{{ $club_point->created_at }}</td>
<td class="text-right">
<a class="btn btn-soft-primary btn-icon btn-circle btn-sm" href="{{route('club_point.details', encrypt($club_point->id))}}" title="{{ translate('View') }}">
<i class="las la-eye"></i>
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="aiz-pagination">
{{ $club_points->appends(request()->input())->links() }}
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,32 @@
@extends('backend.layouts.app')
@section('content')
<div class="row">
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('Set Point for Product')}}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('product_point.update', $product->id) }}" method="POST">
@csrf
<div class="form-group row">
<div class="col-lg-3">
<label class="col-from-label">{{translate('Set Point')}}</label>
</div>
<div class="col-lg-8">
<input type="number" min="0" step="0.01" class="form-control" name="point" value="{{ $product->earn_point }}" placeholder="100" required>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{translate('Save')}}</button>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,126 @@
@extends('backend.layouts.app')
@section('content')
<div class="row">
<div class="col-lg-8">
<div class="card">
<div class="card-body px-3">
<table class="table aiz-table mb-0">
<thead>
<tr>
<th>#</th>
<th>{{translate('Name')}}</th>
<th data-breakpoints="lg">{{translate('Owner')}}</th>
<th data-breakpoints="lg">{{translate('Price')}}</th>
<th data-breakpoints="lg">{{translate('Point')}}</th>
<th>{{translate('Options')}}</th>
</tr>
</thead>
<tbody>
@foreach($products as $key => $product)
<tr>
<td>{{ ($key+1) + ($products->currentPage() - 1)*$products->perPage() }}</td>
<td>
<a href="{{ route('product', $product->slug) }}" target="_blank">
<div class="form-group row">
<div class="col-auto">
<img src="{{ uploaded_asset($product->thumbnail_img)}}" alt="Image" class="size-50px">
</div>
<div class="col">
<span class="text-muted text-truncate-2">{{ $product->getTranslation('name') }}</span>
</div>
</div>
</a>
</td>
<td>
@if ($product->user != null)
{{ $product->user->name }}
@endif
</td>
<td>{{ number_format($product->unit_price,2) }}</td>
<td>{{ $product->earn_point }}</td>
<td class="text-right">
<a class="btn btn-soft-primary btn-icon btn-circle btn-sm" href="{{route('product_club_point.edit', encrypt($product->id))}}" title="{{ translate('Edit') }}">
<i class="las la-edit"></i>
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="aiz-pagination">
{{ $products->appends(request()->input())->links() }}
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('Set Point for Product Within a Range')}}</h5>
</div>
<div class="card-body">
<div class="mb-3 text-muted">
<small>{{ translate('Set any specific point for those products what are between Min-price and Max-price. Min-price should be less than Max-price') }}</small>
</div>
<form class="form-horizontal" action="{{ route('set_products_point.store') }}" method="POST">
@csrf
<div class="form-group row">
<div class="col-lg-6">
<label class="col-from-label">{{translate('Set Point for multiple products')}}</label>
</div>
<div class="col-lg-6">
<input type="number" min="0" step="0.01" class="form-control" name="point" placeholder="100" required>
</div>
</div>
<div class="form-group row">
<div class="col-lg-6">
<label class="col-from-label">{{translate('Min Price')}}</label>
</div>
<div class="col-lg-6">
<input type="number" min="0" step="0.01" class="form-control" name="min_price" value="{{ \App\Models\Product::min('unit_price') }}" placeholder="50" required>
</div>
</div>
<div class="form-group row">
<div class="col-lg-6">
<label class="col-from-label">{{translate('Max Price')}}</label>
</div>
<div class="col-lg-6">
<input type="number" min="0" step="0.01" class="form-control" name="max_price" value="{{ \App\Models\Product::max('unit_price') }}" placeholder="110" required>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{translate('Save')}}</button>
</div>
</form>
</div>
</div>
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('Set Point for all Products')}}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('set_all_products_point.store') }}" method="POST">
@csrf
<div class="form-group row">
<div class="col-lg-4">
<label class="col-from-label">{{translate('Set Point For ')}} {{ single_price(1) }}</label>
</div>
<div class="col-lg-6">
<input type="number" step="0.001" class="form-control" name="point" placeholder="1" required>
</div>
<div class="col-lg-2">
<label class="col-from-label">{{translate('Points')}}</label>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{translate('Save')}}</button>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@@ -0,0 +1,112 @@
{
"name": "OTP",
"unique_identifier": "otp_system",
"version": "2.3",
"minimum_item_version": "7.5.0",
"addon_banner": "otp_system.png",
"directory": [
{
"name": [
"resources/views/otp_systems",
"resources/views/backend/otp_systems",
"resources/views/backend/otp_systems/configurations",
"resources/views/backend/otp_systems/configurations/partials",
"resources/views/backend/otp_systems/sms",
"resources/views/otp_systems/frontend",
"resources/views/otp_systems/frontend/auth",
"resources/views/otp_systems/frontend/auth/passwords"
]
}
],
"sql_file": "",
"files": [
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/index.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/index.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/activation.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/activation.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/sms_templates.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/sms_templates.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/partials/twillo.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/partials/twillo.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/partials/nexmo.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/partials/nexmo.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/partials/fast2sms.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/partials/fast2sms.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/partials/mimo.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/partials/mimo.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/partials/mimsms.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/partials/mimsms.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/partials/msegat.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/partials/msegat.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/partials/sparrow.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/partials/sparrow.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/partials/ssl_wireless.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/partials/ssl_wireless.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/configurations/partials/zender.blade.php",
"update_directory": "resources/views/backend/otp_systems/configurations/partials/zender.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/sms/index.blade.php",
"update_directory": "resources/views/backend/otp_systems/sms/index.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/frontend/auth/passwords/reset_with_phone.blade.php",
"update_directory": "resources/views/otp_systems/frontend/auth/passwords/reset_with_phone.blade.php"
},
{
"root_directory": "addons/otp_system/views/otp_systems/frontend/user_verification.blade.php",
"update_directory": "resources/views/otp_systems/frontend/user_verification.blade.php"
},
{
"root_directory": "addons/otp_system/controllers/OTPController.php",
"update_directory": "app/Http/Controllers/OTPController.php"
},
{
"root_directory": "addons/otp_system/controllers/SmsController.php",
"update_directory": "app/Http/Controllers/SmsController.php"
},
{
"root_directory": "addons/otp_system/controllers/OTPVerificationController.php",
"update_directory": "app/Http/Controllers/OTPVerificationController.php"
},
{
"root_directory": "addons/otp_system/controllers/SmsTemplateController.php",
"update_directory": "app/Http/Controllers/SmsTemplateController.php"
},
{
"root_directory": "addons/otp_system/utility/MimoUtility.php",
"update_directory": "app/Utility/MimoUtility.php"
},
{
"root_directory": "addons/otp_system/utility/SmsUtility.php",
"update_directory": "app/Utility/SmsUtility.php"
},
{
"root_directory": "addons/otp_system/assets/otp_system.png",
"update_directory": "public/otp_system.png"
}
]
}

View File

@@ -0,0 +1,94 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\OtpConfiguration;
class OTPController extends Controller
{
public function __construct() {
// Staff Permission Check
$this->middleware(['permission:otp_configurations'])->only('configure_index');
$this->middleware(['permission:sms_providers_configurations'])->only('credentials_index');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function configure_index()
{
$otp_configurations = OtpConfiguration::all();
return view('backend.otp_systems.configurations.activation', compact('otp_configurations'));
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function credentials_index()
{
$otp_configurations = OtpConfiguration::all();
return view('backend.otp_systems.configurations.index', compact('otp_configurations'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function updateActivationSettings(Request $request)
{
$business_settings = OtpConfiguration::where('type', $request->type)->first();
if($business_settings!=null){
$business_settings->value = $request->value;
$business_settings->save();
}
else{
$business_settings = new OtpConfiguration;
$business_settings->type = $request->type;
$business_settings->value = $request->value;
$business_settings->save();
}
return '1';
}
/**
* Update the specified resource in .env
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function update_credentials(Request $request)
{
foreach ($request->types as $key => $type) {
$this->overWriteEnvFile($type, $request[$type]);
}
flash("Settings updated successfully")->success();
return back();
}
/**
*.env file overwrite
*/
public function overWriteEnvFile($type, $val)
{
$path = base_path('.env');
if (file_exists($path)) {
$val = '"'.trim($val).'"';
if(is_numeric(strpos(file_get_contents($path), $type)) && strpos(file_get_contents($path), $type) >= 0){
file_put_contents($path, str_replace(
$type.'="'.env($type).'"', $type.'='.$val, file_get_contents($path)
));
}
else{
file_put_contents($path, file_get_contents($path)."\r\n".$type.'='.$val);
}
}
}
}

View File

@@ -0,0 +1,143 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\PasswordReset;
use Auth;
use App\Models\User;
use App\Utility\SmsUtility;
use Hash;
class OTPVerificationController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function verification(Request $request){
if (Auth::check() && Auth::user()->email_verified_at == null) {
return view('otp_systems.frontend.user_verification');
}
else {
flash('You have already verified your number')->warning();
return redirect()->route('home');
}
}
/**
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function verify_phone(Request $request){
$user = Auth::user();
if ($user->verification_code == $request->verification_code) {
$user->email_verified_at = date('Y-m-d h:m:s');
$user->save();
flash('Your phone number has been verified successfully')->success();
return redirect()->route('home');
}
else{
flash('Invalid Code')->error();
return back();
}
}
/**
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function resend_verificcation_code(Request $request){
$user = Auth::user();
$user->verification_code = rand(100000,999999);
$user->save();
SmsUtility::phone_number_verification($user);
return back();
}
/**
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function reset_password_with_code(Request $request)
{
$phone = "+{$request['country_code']}{$request['phone']}";
if (($user = User::where('phone', $phone)->where('verification_code', $request->code)->first()) != null) {
if ($request->password == $request->password_confirmation) {
$user->password = Hash::make($request->password);
$user->email_verified_at = date('Y-m-d h:m:s');
$user->save();
event(new PasswordReset($user));
auth()->login($user, true);
if (auth()->user()->user_type == 'admin' || auth()->user()->user_type == 'staff') {
flash("Password has been reset successfully")->success();
return redirect()->route('admin.dashboard');
}
flash("Password has been reset successfully")->success();
return redirect()->route('home');
} else {
flash("Password and confirm password didn't match")->warning();
return view('otp_systems.frontend.auth.passwords.reset_with_phone');
}
} else {
flash("Verification code mismatch")->error();
return view('otp_systems.frontend.auth.passwords.reset_with_phone');
}
}
/**
* @param User $user
* @return void
*/
public function send_code($user){
SmsUtility::phone_number_verification($user);
}
/**
* @param Order $order
* @return void
*/
public function send_order_code($order){
$phone = json_decode($order->shipping_address)->phone;
if($phone != null){
SmsUtility::order_placement($phone, $order);
}
}
/**
* @param Order $order
* @return void
*/
public function send_delivery_status($order){
$phone = json_decode($order->shipping_address)->phone;
if($phone != null){
SmsUtility::delivery_status_change($phone, $order);
}
}
/**
* @param Order $order
* @return void
*/
public function send_payment_status($order){
$phone = json_decode($order->shipping_address)->phone;
if($phone != null){
SmsUtility::payment_status_change($phone, $order);
}
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Services\SendSmsService;
use App\Models\User;
class SmsController extends Controller
{
public function __construct() {
// Staff Permission Check
$this->middleware(['permission:send_bulk_sms'])->only('index');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$users = User::all();
return view('backend.otp_systems.sms.index',compact('users'));
}
//send message to multiple users
public function send(Request $request)
{
foreach ($request->user_phones as $key => $phone) {
(new SendSmsService())->sendSMS($phone, env('APP_NAME'), $request->content, $request->template_id);
}
flash(translate('SMS has been sent.'))->success();
return redirect()->route('admin.dashboard');
}
}

View File

@@ -0,0 +1,109 @@
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\SmsTemplate;
class SmsTemplateController extends Controller
{
public function __construct() {
// Staff Permission Check
$this->middleware(['permission:sms_templates'])->only('index');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$sms_templates = SmsTemplate::all();
return view('backend.otp_systems.configurations.sms_templates', compact('sms_templates'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$sms_template = SmsTemplate::where('id', $id)->first();
$sms_template->sms_body = str_replace("\r\n",'',$request->body);
$sms_template->template_id = $request->template_id;
if ($request->status == 1) {
$sms_template->status = 1;
}
else{
$sms_template->status = 0;
}
if($sms_template->save()){
flash(translate('SMS Template has been updated successfully'))->success();
return back();
} else {
flash(translate('Sorry! Something went wrong.'))->error();
return back();
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View File

@@ -0,0 +1,2 @@
INSERT INTO `otp_configurations` (`id`, `type`, `value`, `created_at`, `updated_at`) VALUES (NULL, 'ssl_wireless', '0', current_timestamp(), current_timestamp());
COMMIT;

View File

@@ -0,0 +1,2 @@
INSERT INTO `otp_configurations` (`id`, `type`, `value`, `created_at`, `updated_at`) VALUES (NULL, 'fast2sms', '0', current_timestamp(), current_timestamp());
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1,2 @@
INSERT INTO `otp_configurations` (`id`, `type`, `value`, `created_at`, `updated_at`) VALUES (NULL, 'mimo', '0', current_timestamp(), current_timestamp());
COMMIT;

View File

@@ -0,0 +1,25 @@
CREATE TABLE `sms_templates` (
`id` int(11) NOT NULL,
`identifier` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`sms_body` longtext COLLATE utf8_unicode_ci NOT NULL,
`template_id` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`status` tinyint(1) NOT NULL DEFAULT 1,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `sms_templates` (`id`, `identifier`, `sms_body`, `template_id`, `status`, `created_at`, `updated_at`) VALUES
(1, 'phone_number_verification', '[[code]] is your verification code for [[site_name]].', NULL, 0, '2021-06-07 13:29:22', '2021-06-08 02:38:18'),
(2, 'password_reset', 'Your password reset code is [[code]].', NULL, 1, '2021-06-07 13:29:34', '2021-06-07 13:29:34'),
(3, 'order_placement', 'Your order has been placed and Order Code is [[order_code]]', NULL, 1, '2021-06-07 13:32:22', '2021-06-08 02:39:25'),
(4, 'delivery_status_change', 'Your delivery status has been updated to [[delivery_status]] for Order code : [[order_code]]', NULL, 1, '2021-06-07 13:33:14', '2021-06-08 02:39:28'),
(5, 'payment_status_change', 'Your payment status has been updated to [[payment_status]] for Order code : [[order_code]]', NULL, 1, '2021-06-07 13:35:23', '2021-06-08 02:39:31'),
(6, 'assign_delivery_boy', 'You are assigned to deliver an order. Order code : [[order_code]]', NULL, 1, '2021-06-07 13:38:10', '2021-06-08 02:39:34');
ALTER TABLE `sms_templates`
ADD PRIMARY KEY (`id`);
ALTER TABLE `sms_templates`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
COMMIT;

View File

@@ -0,0 +1,2 @@
INSERT INTO `otp_configurations` (`id`, `type`, `value`, `created_at`, `updated_at`) VALUES (NULL, 'mimsms', '0', current_timestamp(), current_timestamp());
COMMIT;

View File

@@ -0,0 +1,2 @@
INSERT INTO `otp_configurations` (`id`, `type`, `value`, `created_at`, `updated_at`) VALUES (NULL, 'msegat', '0', current_timestamp(), current_timestamp());
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1,13 @@
INSERT INTO `otp_configurations` (`id`, `type`, `value`, `created_at`, `updated_at`)
SELECT NULL, 'sparrow', '0', current_timestamp(), current_timestamp() FROM DUAL
WHERE NOT EXISTS (SELECT * FROM `otp_configurations` WHERE `type`='sparrow' LIMIT 1);
INSERT INTO `otp_configurations` (`id`, `type`, `value`, `created_at`, `updated_at`)
SELECT NULL, 'zender', '0', current_timestamp(), current_timestamp() FROM DUAL
WHERE NOT EXISTS (SELECT * FROM `otp_configurations` WHERE `type`='zender' LIMIT 1);
DELETE FROM `otp_configurations` WHERE `type` = 'otp_for_order';
DELETE FROM `otp_configurations` WHERE `type` = 'otp_for_delivery_status';
DELETE FROM `otp_configurations` WHERE `type` = 'otp_for_paid_status';
COMMIT;

View File

@@ -0,0 +1,107 @@
-- phpMyAdmin SQL Dump
-- version 5.0.1
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Mar 23, 2020 at 07:35 AM
-- Server version: 10.4.11-MariaDB
-- PHP Version: 7.4.2
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*Column will be added on user table*/
ALTER TABLE `users` CHANGE `verification_code` `verification_code` TEXT NULL DEFAULT NULL;
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `shop`
--
-- --------------------------------------------------------
--
-- Table structure for table `otp_configurations`
--
CREATE TABLE `otp_configurations` (
`id` int(11) NOT NULL,
`type` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
`value` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Dumping data for table `otp_configurations`
--
INSERT INTO `otp_configurations` (`id`, `type`, `value`, `created_at`, `updated_at`) VALUES
(1, 'nexmo', '1', '2020-03-22 09:19:07', '2020-03-22 09:19:07'),
(5, 'twillo', '0', '2020-03-22 09:54:03', '2020-03-22 03:54:20'),
(6, 'ssl_wireless', '0', '2020-03-22 09:54:03', '2020-03-22 03:54:20'),
(7, 'fast2sms', '0', '2020-03-22 09:54:03', '2020-03-22 03:54:20'),
(8, 'mimsms', '0', '2020-03-22 09:54:03', '2020-03-22 03:54:20'),
(9, 'mimo', '0', '2020-12-27 09:54:03', '2020-12-28 03:54:20'),
(10, 'msegat', '0', '2020-12-27 09:54:03', '2020-12-28 03:54:20'),
(11, 'sparrow', '0', '2020-12-27 09:54:03', '2020-12-28 03:54:20'),
(12, 'zender', '0', '2020-12-27 09:54:03', '2020-12-28 03:54:20');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `otp_configurations`
--
ALTER TABLE `otp_configurations`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `otp_configurations`
--
ALTER TABLE `otp_configurations`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;
CREATE TABLE `sms_templates` (
`id` int(11) NOT NULL,
`identifier` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`sms_body` longtext COLLATE utf8_unicode_ci NOT NULL,
`template_id` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`status` tinyint(1) NOT NULL DEFAULT 1,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `sms_templates` (`id`, `identifier`, `sms_body`, `template_id`, `status`, `created_at`, `updated_at`) VALUES
(1, 'phone_number_verification', '[[code]] is your verification code for [[site_name]].', NULL, 0, '2021-06-07 13:29:22', '2021-06-08 02:38:18'),
(2, 'password_reset', 'Your password reset code is [[code]].', NULL, 1, '2021-06-07 13:29:34', '2021-06-07 13:29:34'),
(3, 'order_placement', 'Your order has been placed and Order Code is [[order_code]]', NULL, 1, '2021-06-07 13:32:22', '2021-06-08 02:39:25'),
(4, 'delivery_status_change', 'Your delivery status has been updated to [[delivery_status]] for Order code : [[order_code]]', NULL, 1, '2021-06-07 13:33:14', '2021-06-08 02:39:28'),
(5, 'payment_status_change', 'Your payment status has been updated to [[payment_status]] for Order code : [[order_code]]', NULL, 1, '2021-06-07 13:35:23', '2021-06-08 02:39:31'),
(6, 'assign_delivery_boy', 'You are assigned to deliver an order. Order code : [[order_code]]', NULL, 1, '2021-06-07 13:38:10', '2021-06-08 02:39:34');
ALTER TABLE `sms_templates`
ADD PRIMARY KEY (`id`);
ALTER TABLE `sms_templates`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@@ -0,0 +1,91 @@
<?php
namespace App\Utility;
class MimoUtility
{
public static function getToken()
{
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => '52.30.114.86:8080/mimosms/v1/user/login',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"username": "'.env('MIMO_USERNAME').'",
"password": "'.env('MIMO_PASSWORD').'"
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response)->token;
}
public static function sendMessage($text, $to, $token)
{
$curl = curl_init();
$fields = array(
"sender" => env("MIMO_SENDER_ID"),
"text" => $text,
"recipients" => $to
);
// dd($to);
curl_setopt_array($curl, array(
CURLOPT_URL => '52.30.114.86:8080/mimosms/v1/message/send?token='.$token,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($fields),
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
// dd($response);
curl_close($curl);
return 1;
}
public static function logout($token)
{
// dd('Hello world');
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => '52.30.114.86:8080/mimosms/v1/user/logout?token='.$token,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$response = curl_exec($curl);
curl_close($curl);
// dd($response, $token);
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace App\Utility;
use App\Models\OtpConfiguration;
use App\Models\SmsTemplate;
use App\Models\User;
use App\Services\SendSmsService;
class SmsUtility
{
public static function phone_number_verification($user = '')
{
$sms_template = SmsTemplate::where('identifier', 'phone_number_verification')->first();
$sms_body = $sms_template->sms_body;
$sms_body = str_replace('[[code]]', $user->verification_code, $sms_body);
$sms_body = str_replace('[[site_name]]', env('APP_NAME'), $sms_body);
$template_id = $sms_template->template_id;
(new SendSmsService())->sendSMS($user->phone, env('APP_NAME'), $sms_body, $template_id);
}
public static function password_reset($user = '')
{
$sms_template = SmsTemplate::where('identifier', 'password_reset')->first();
$sms_body = $sms_template->sms_body;
$sms_body = str_replace('[[code]]', $user->verification_code, $sms_body);
$template_id = $sms_template->template_id;
(new SendSmsService())->sendSMS($user->phone, env('APP_NAME'), $sms_body, $template_id);
}
public static function order_placement($phone = '', $order = '')
{
$sms_template = SmsTemplate::where('identifier', 'order_placement')->first();
$sms_body = $sms_template->sms_body;
$sms_body = str_replace('[[order_code]]', $order->code, $sms_body);
$template_id = $sms_template->template_id;
(new SendSmsService())->sendSMS($phone, env('APP_NAME'), $sms_body, $template_id);
}
public static function delivery_status_change($phone = '', $order)
{
$sms_template = SmsTemplate::where('identifier', 'delivery_status_change')->first();
$sms_body = $sms_template->sms_body;
$delivery_status = translate(ucfirst(str_replace('_', ' ', $order->delivery_status)));
$sms_body = str_replace('[[delivery_status]]', $delivery_status, $sms_body);
$sms_body = str_replace('[[order_code]]', $order->code, $sms_body);
$template_id = $sms_template->template_id;
(new SendSmsService())->sendSMS($phone, env('APP_NAME'), $sms_body, $template_id);
}
public static function payment_status_change($phone = '', $order = '')
{
$sms_template = SmsTemplate::where('identifier', 'payment_status_change')->first();
$sms_body = $sms_template->sms_body;
$sms_body = str_replace('[[payment_status]]', translate(ucfirst($order->payment_status)), $sms_body);
$sms_body = str_replace('[[order_code]]', $order->code, $sms_body);
$template_id = $sms_template->template_id;
(new SendSmsService())->sendSMS($phone, env('APP_NAME'), $sms_body, $template_id);
}
public static function assign_delivery_boy($phone = '', $code = '')
{
$sms_template = SmsTemplate::where('identifier', 'assign_delivery_boy')->first();
$sms_body = $sms_template->sms_body;
$sms_body = str_replace('[[order_code]]', $code, $sms_body);
$template_id = $sms_template->template_id;
(new SendSmsService())->sendSMS($phone, env('APP_NAME'), $sms_body, $template_id);
}
}

View File

@@ -0,0 +1,45 @@
@extends('backend.layouts.app')
@section('content')
<h4 class="text-center text-muted">{{translate('Activate OTP')}}</h4>
<div class="row">
@foreach ($otp_configurations as $otp_configuration)
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h3 class="mb-0 h6">
{{translate(Str::replace('_', ' ',Str::title($otp_configuration->type)).' OTP')}}
</h3>
</div>
<div class="card-body text-center">
<label class="aiz-switch aiz-switch-success mb-0">
<input type="checkbox" onchange='updateSettings(this, "{{ $otp_configuration->type }}")' @if($otp_configuration->value == 1) checked @endif>
<span class="slider round"></span>
</label>
</div>
</div>
</div>
@endforeach
</div>
@endsection
@section('script')
<script type="text/javascript">
function updateSettings(el, type){
if($(el).is(':checked')){
var value = 1;
}
else{
var value = 0;
}
$.post('{{ route('otp_configurations.update.activation') }}', {_token:'{{ csrf_token() }}', type:type, value:value}, function(data){
if(data == 1){
AIZ.plugins.notify('success', '{{ translate('Settings updated successfully') }}');
}
else{
AIZ.plugins.notify('danger', '{{ translate('Something went wrong') }}');
}
});
}
</script>
@endsection

View File

@@ -0,0 +1,28 @@
@extends('backend.layouts.app')
@section('content')
<div class="row">
@foreach ($otp_configurations as $otp_configuration)
@include('backend.otp_systems.configurations.partials.'.$otp_configuration->type)
@endforeach
</div>
@endsection
@section('script')
<script type="text/javascript">
$("#ZENDER_MODE").change(function() {
var value = $(this).val();
let changeVal = '';
if (value == "devices") {
changeVal = 'device';
} else {
changeVal = 'gateway';
}
$("#ZENDER_MODE_TYPE").val(changeVal).change();
});
</script>
@endsection

View File

@@ -0,0 +1,76 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{ translate('Fast2SMS Credential') }}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('update_credentials') }}" method="POST">
<input type="hidden" name="otp_method" value="fast2sms">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="AUTH_KEY">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('AUTH KEY') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="AUTH_KEY"
value="{{ env('AUTH_KEY') }}" placeholder="AUTH KEY" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="ENTITY_ID">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('ENTITY ID') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="ENTITY_ID"
value="{{ env('ENTITY_ID') }}" placeholder="{{ translate('Entity ID') }}">
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="ROUTE">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('ROUTE') }}</label>
</div>
<div class="col-lg-6">
<select class="form-control aiz-selectpicker" name="ROUTE" required>
<option value="dlt_manual" @if (env('ROUTE') == 'dlt_manual') selected @endif>
{{ translate('DLT Manual') }}</option>
<option value="p" @if (env('ROUTE') == 'p') selected @endif>
{{ translate('Promotional Use') }}</option>
<option value="t" @if (env('ROUTE') == 't') selected @endif>
{{ translate('Transactional Use') }}</option>
</select>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="LANGUAGE">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('LANGUAGE') }}</label>
</div>
<div class="col-lg-6">
<select class="form-control aiz-selectpicker" name="LANGUAGE" required>
<option value="english" @if (env('LANGUAGE') == 'english') selected @endif>English
</option>
<option value="unicode" @if (env('LANGUAGE') == 'unicode') selected @endif>Unicode
</option>
</select>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="SENDER_ID">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('SENDER ID') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="SENDER_ID"
value="{{ env('SENDER_ID') }}" placeholder="6 digit SENDER ID">
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,46 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{ translate('MIMO Credential') }}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('update_credentials') }}" method="POST">
<input type="hidden" name="otp_method" value="mimo">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="MIMO_USERNAME">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MIMO_USERNAME') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MIMO_USERNAME"
value="{{ env('MIMO_USERNAME') }}" placeholder="MIMO_USERNAME" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="MIMO_PASSWORD">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MIMO_PASSWORD') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MIMO_PASSWORD"
value="{{ env('MIMO_PASSWORD') }}" placeholder="MIMO_PASSWORD" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="MIMO_SENDER_ID">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MIMO_SENDER_ID') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MIMO_SENDER_ID"
value="{{ env('MIMO_SENDER_ID') }}" placeholder="MIMO_SENDER_ID" required>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,46 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{ translate('MIMSMS Credential') }}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('update_credentials') }}" method="POST">
<input type="hidden" name="otp_method" value="mimsms">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="MIM_API_KEY">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MIM_API_KEY') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MIM_API_KEY"
value="{{ env('MIM_API_KEY') }}" placeholder="MIM_API_KEY" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="MIM_SENDER_ID">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MIM_SENDER_ID') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MIM_SENDER_ID"
value="{{ env('MIM_SENDER_ID') }}" placeholder="MIM_SENDER_ID" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="MIM_BASE_URL">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MIM_BASE_URL') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MIM_BASE_URL"
value="{{ env('MIM_BASE_URL') }}" placeholder="MIM_BASE_URL" required>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,46 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{ translate('MSEGAT Credential') }}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('update_credentials') }}" method="POST">
<input type="hidden" name="otp_method" value="msegat">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="MSEGAT_API_KEY">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MSEGAT_API_KEY') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MSEGAT_API_KEY"
value="{{ env('MSEGAT_API_KEY') }}" placeholder="MSEGAT_API_KEY" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="MSEGAT_USERNAME">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MSEGAT_USERNAME') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MSEGAT_USERNAME"
value="{{ env('MSEGAT_USERNAME') }}" placeholder="MSEGAT_USERNAME" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="MSEGAT_USER_SENDER">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MSEGAT_USER_SENDER') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MSEGAT_USER_SENDER"
value="{{ env('MSEGAT_USER_SENDER') }}" placeholder="MSEGAT_USER_SENDER" required>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,50 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{ translate('Nexmo Credential') }}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('update_credentials') }}" method="POST">
<input type="hidden" name="otp_method" value="nexmo">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="NEXMO_KEY">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('NEXMO KEY') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="NEXMO_KEY" value="{{ env('NEXMO_KEY') }}"
placeholder="NEXMO KEY" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="NEXMO_SECRET">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('NEXMO SECRET') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="NEXMO_SECRET"
value="{{ env('NEXMO_SECRET') }}" placeholder="NEXMO SECRET" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="NEXMO_SENDER_ID">
<div class="col-lg-3">
<label class="col-from-label">{{translate('NEXMO SENDER ID')}}</label>
</div>
<div class="col-lg-8">
<input type="text" class="form-control" name="NEXMO_SENDER_ID" value="{{ env('NEXMO_SENDER_ID') }}" placeholder="NEXMO SENDER ID" required>
<small>
{{translate('Please check this URL for')}}
<a href="https://developer.vonage.com/en/messaging/sms/guides/custom-sender-id?source=messaging">Sender Identity</a>
{{translate('before setting the sender ID')}}
</small>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,36 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{ translate('SPARROW Credential') }}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('update_credentials') }}" method="POST">
<input type="hidden" name="otp_method" value="sparrow">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="SPARROW_TOKEN">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('SPARROW_TOKEN') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="SPARROW_TOKEN"
value="{{ env('SPARROW_TOKEN') }}" placeholder="SPARROW_TOKEN" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="MESSGAE_FROM">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('MESSGAE_FROM') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="MESSGAE_FROM"
value="{{ env('MESSGAE_FROM') }}" placeholder="MESSGAE_FROM" required>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,46 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{ translate('SSL Wireless Credential') }}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('update_credentials') }}" method="POST">
<input type="hidden" name="otp_method" value="ssl_wireless">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="SSL_SMS_API_TOKEN">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('SSL SMS API TOKEN') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="SSL_SMS_API_TOKEN"
value="{{ env('SSL_SMS_API_TOKEN') }}" placeholder="SSL SMS API TOKEN" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="SSL_SMS_SID">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('SSL SMS SID') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="SSL_SMS_SID"
value="{{ env('SSL_SMS_SID') }}" placeholder="SSL SMS SID" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="SSL_SMS_URL">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('SSL SMS URL') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="SSL_SMS_URL"
value="{{ env('SSL_SMS_URL') }}" placeholder="SSL SMS URL">
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,60 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{ translate('Twilio Credential') }}</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('update_credentials') }}" method="POST">
<input type="hidden" name="otp_method" value="twillo">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="TWILIO_SID">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('TWILIO SID') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="TWILIO_SID" value="{{ env('TWILIO_SID') }}"
placeholder="TWILIO SID" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="TWILIO_AUTH_TOKEN">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('TWILIO AUTH TOKEN') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="TWILIO_AUTH_TOKEN"
value="{{ env('TWILIO_AUTH_TOKEN') }}" placeholder="TWILIO AUTH TOKEN" required>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="VALID_TWILLO_NUMBER">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('VALID TWILIO NUMBER') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="VALID_TWILLO_NUMBER"
value="{{ env('VALID_TWILLO_NUMBER') }}" placeholder="VALID TWILLO NUMBER">
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="TWILLO_TYPE">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('TWILIO TYPE') }}</label>
</div>
<div class="col-lg-6">
<select class="form-control" name="TWILLO_TYPE">
<option value="1" {{ env('TWILLO_TYPE') < 2 ? 'selected' : false }}>SMS</option>
<option value="2" {{ env('TWILLO_TYPE') > 1 ? 'selected' : false }}>WhatsApp</option>
</select>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,106 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">Zender Credential</h5>
</div>
<div class="card-body">
<form class="form-horizontal" action="{{ route('update_credentials') }}" method="POST">
<input type="hidden" name="otp_method" value="zender">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="ZENDER_SITEURL">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('ZENDER_SITEURL') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="ZENDER_SITEURL"
value="{{ env('ZENDER_SITEURL') }}" placeholder="https://yourzendersite.com"
required>
<small>The site url of your Zender. Do not add ending slash.</small>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="ZENDER_APIKEY">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('ZENDER_APIKEY') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="ZENDER_APIKEY"
value="{{ env('ZENDER_APIKEY') }}" placeholder="ZENDER_APIKEY" required>
<small>Your Zender API key. Please make sure that it is correct and required permissions are
granted: sms_send, wa_send</small>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="ZENDER_SERVICE">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('ZENDER_SERVICE') }}</label>
</div>
<div class="col-lg-6">
<select class="form-control" name="ZENDER_SERVICE">
<option value="1" {{ env('ZENDER_SERVICE') < 2 ? 'selected' : false }}>SMS
</option>
<option value="2" {{ env('ZENDER_SERVICE') > 1 ? 'selected' : false }}>WhatsApp
</option>
</select>
<small>Select the sending service. Please make sure that the API key has the following
permissions: sms_send, wa_send</small>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="ZENDER_WHATSAPP">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('ZENDER_WHATSAPP') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="ZENDER_WHATSAPP"
value="{{ env('ZENDER_WHATSAPP') }}" placeholder="ZENDER_WHATSAPP">
<small>For WhatsApp service only. WhatsApp account ID you want to use for sending.</small>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="ZENDER_DEVICE">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('ZENDER_DEVICE') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="ZENDER_DEVICE"
value="{{ env('ZENDER_DEVICE') }}" placeholder="ZENDER_DEVICE">
<small>For SMS service only. Linked device unique ID. Please only enter this field if you
are sending using one of your devices.</small>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="ZENDER_GATEWAY">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('ZENDER_GATEWAY') }}</label>
</div>
<div class="col-lg-6">
<input type="text" class="form-control" name="ZENDER_GATEWAY"
value="{{ env('ZENDER_GATEWAY') }}" placeholder="ZENDER_GATEWAY">
<small>For SMS service only. Partner device unique ID or gateway ID. Please only enter this
field if you are sending using a partner device or third party gateway.</small>
</div>
</div>
<div class="form-group row">
<input type="hidden" name="types[]" value="ZENDER_SIM">
<div class="col-lg-3">
<label class="col-from-label">{{ translate('ZENDER_SIM') }}</label>
</div>
<div class="col-lg-6">
<select class="form-control" name="ZENDER_SIM">
<option value="1" {{ env('ZENDER_SIM') < 2 ? 'selected' : false }}>SIM 1</option>
<option value="2" {{ env('ZENDER_SIM') > 1 ? 'selected' : false }}>SIM 2</option>
</select>
<small>For SMS service only. Select the sim slot you want to use for sending the messages.
Please only enter this field if you are sending using your device. This is ignored for
partner devices and third party gateways.</small>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -0,0 +1,73 @@
@extends('backend.layouts.app')
@section('content')
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('SMS Templates')}}</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-3">
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
@foreach ($sms_templates as $key => $sms_template)
<a class="nav-link @if($sms_template->id == 1) active @endif" id="v-pills-tab-2" data-toggle="pill" href="#v-pills-{{ $sms_template->id }}" role="tab" aria-controls="v-pills-profile" aria-selected="false">{{ translate(ucwords(str_replace('_', ' ', $sms_template->identifier))) }}</a>
@endforeach
</div>
</div>
<div class="col-9">
<div class="tab-content" id="v-pills-tabContent">
@foreach ($sms_templates as $key => $sms_template)
<div class="tab-pane fade show @if($sms_template->id == 1) active @endif" id="v-pills-{{ $sms_template->id }}" role="tabpanel" aria-labelledby="v-pills-tab-1">
<form action="{{ route('sms-templates.update', $sms_template->id) }}" method="POST">
<input name="_method" type="hidden" value="PATCH">
@csrf
@if($sms_template->identifier != 'phone_number_verification' && $sms_template->identifier != 'password_reset')
<div class="form-group row">
<div class="col-md-2">
<label class="col-from-label">{{translate('Activation')}}</label>
</div>
<div class="col-md-10">
<label class="aiz-switch aiz-switch-success mb-0">
<input value="1" name="status" type="checkbox" @if ($sms_template->status == 1)
checked
@endif>
<span class="slider round"></span>
</label>
</div>
</div>
@endif
<div class="form-group row">
<label class="col-md-2 col-form-label">{{translate('SMS Body')}}</label>
<div class="col-md-10">
<textarea name="body" class="form-control" placeholder="Type.." rows="6" required>{{ $sms_template->sms_body }}</textarea>
<small class="form-text text-danger">{{ ('**N.B : Do Not Change The Variables Like [[ ____ ]].**') }}</small>
@error('body')
<small class="form-text text-danger">{{ $message }}</small>
@enderror
</div>
</div>
<div class="form-group row">
<label class="col-md-2 col-form-label">{{translate('Template ID')}}</label>
<div class="col-md-10">
<input type="text" name="template_id" value="{{ $sms_template->template_id }}" class="form-control" placeholder="{{translate('Template Id')}}">
<small class="form-text text-danger">{{ ('**N.B : Template ID is Required Only for Fast2SMS DLT Manual**') }}</small>
</div>
</div>
<div class="form-group mb-3 text-right">
<button type="submit" class="btn btn-primary">{{translate('Update Settings')}}</button>
</div>
</form>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,99 @@
@extends('frontend.layouts.app')
@section('content')
<section class="py-4">
<div class="container">
<div class="row">
<div class="col-lg-6 col-xl-5 mx-auto">
<div class="card">
<div class="card-body">
<h1 class="h3 fw-600">{{ translate('Reset Password') }}</h1>
<p class="mb-4">{{translate('Enter your phone, code and new password and confirm password.')}} </p>
<form method="POST" action="{{ route('password.update.phone') }}">
@csrf
<div class="form-group">
<input id="phone-code" type="text" class="form-control" name="phone"
placeholder="{{ translate('Phone Number') }}" required>
<span class="invalid-phone-feedback text-danger" role="alert">
</span>
</div>
<input type="hidden" id="country_code" name="country_code" value="">
<div class="form-group">
<input id="email" type="text" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="code" value="{{ $email ?? old('email') }}" placeholder="Code" required autofocus>
@if ($errors->has('email'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
<div class="form-group">
<input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" placeholder="New Password" required>
@if ($errors->has('password'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
<div class="form-group">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" placeholder="Confirm Password" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">
{{ translate('Reset Password') }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
@endsection
@section('script')
<script type="text/javascript">
var isPhoneShown = true,
countryData = window.intlTelInputGlobals.getCountryData(),
input = document.querySelector("#phone-code");
for (var i = 0; i < countryData.length; i++) {
var country = countryData[i];
if(country.iso2 == 'bd'){
country.dialCode = '88';
}
}
var iti = intlTelInput(input, {
separateDialCode: true,
utilsScript: "{{ static_asset('assets/js/intlTelutils.js') }}?1590403638580",
onlyCountries: @php echo json_encode(\App\Models\Country::where('status', 1)->pluck('code')->toArray()) @endphp,
customPlaceholder: function(selectedCountryPlaceholder, selectedCountryData) {
if(selectedCountryData.iso2 == 'bd'){
return "01xxxxxxxxx";
}
return selectedCountryPlaceholder;
}
});
var country = iti.getSelectedCountryData();
$('input[name=country_code]').val(country.dialCode);
input.addEventListener("countrychange", function(e) {
// var currentMask = e.currentTarget.placeholder;
var country = iti.getSelectedCountryData();
$('input[name=country_code]').val(country.dialCode);
});
</script>
@endsection

View File

@@ -0,0 +1,36 @@
@extends('frontend.layouts.app')
@section('content')
<section class="py-4">
<div class="container">
<div class="row">
<div class="col-lg-6 col-xl-5 mx-auto">
<div class="card">
<div class="text-center pt-5">
<h1 class="h2 fw-600">
{{translate('Phone Verification')}}
</h1>
<p>Verification code has been sent. Please wait a few minutes.</p>
<a href="{{ route('verification.phone.resend') }}" class="btn btn-link">{{translate('Resend Code')}}</a>
</div>
<div class="px-5 py-lg-5">
<div class="row align-items-center">
<div class="col-12 col-lg">
<form class="form-default" role="form" action="{{ route('verification.submit') }}" method="POST">
@csrf
<div class="form-group">
<div class="input-group input-group--style-1">
<input type="text" class="form-control" name="verification_code">
</div>
</div>
<button type="submit" class="btn btn-primary btn-block">{{ translate('Verify') }}</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
@endsection

View File

@@ -0,0 +1,48 @@
@extends('backend.layouts.app')
@section('content')
<div class="row">
<div class="col-lg-6 mx-auto">
<div class="card">
<div class="card-header">
<h3 class="fs-18 mb-0">{{translate('Send Bulk SMS')}}</h3>
</div>
<form class="form-horizontal" action="{{ route('sms.send') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="card-body">
<div class="form-group row">
<label class="col-sm-2 control-label" for="name">{{translate('Mobile Users')}}</label>
<div class="col-sm-10">
<select class="form-control aiz-selectpicker" data-live-search="true" name="user_phones[]" multiple>
@foreach($users as $user)
@if ($user->phone != null)
<option value="{{$user->phone}}">{{$user->name}} - {{$user->phone}}</option>
@endif
@endforeach
</select>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label" for="name">{{translate('SMS content')}}</label>
<div class="col-sm-10">
<textarea class="form-control" name="content" required></textarea>
</div>
</div>
<div class="form-group row">
<label class="col-md-2 col-form-label">{{translate('Template ID')}}</label>
<div class="col-md-10">
<input type="text" name="template_id" class="form-control" placeholder="{{translate('Template Id')}}">
<small class="form-text text-danger">{{ ('**N.B : Template ID is Required Only for Fast2SMS DLT Manual **') }}</small>
</div>
</div>
</div>
<div class="card-footer">
<button class="btn btn-primary" type="submit">{{translate('Send')}}</button>
</div>
</form>
</div>
</div>
</div>
@endsection

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View File

@@ -0,0 +1,69 @@
{
"name" : "Offline Payment",
"unique_identifier" : "offline_payment",
"version" : "1.5",
"minimum_item_version" : "7.0.0",
"addon_banner" : "offline_banner.jpg",
"directory" :
[
{
"name" : [
"resources/views/manual_payment_methods",
"resources/views/manual_payment_methods/frontend",
"public/uploads/customer_package_payment_reciept",
"public/uploads/seller_package_payment_reciept"
]
}
],
"sql_file" : "",
"files" :
[
{
"root_directory" : "addons/offline_payment/views/manual_payment_methods/frontend/offline_customer_package_purchase_modal.blade.php",
"update_directory" : "resources/views/manual_payment_methods/frontend/offline_customer_package_purchase_modal.blade.php"
},
{
"root_directory" : "addons/offline_payment/views/manual_payment_methods/frontend/offline_seller_package_purchase_modal.blade.php",
"update_directory" : "resources/views/manual_payment_methods/frontend/offline_seller_package_purchase_modal.blade.php"
},
{
"root_directory" : "addons/offline_payment/views/manual_payment_methods/create.blade.php",
"update_directory" : "resources/views/manual_payment_methods/create.blade.php"
},
{
"root_directory" : "addons/offline_payment/views/manual_payment_methods/customer_package_payment_request.blade.php",
"update_directory" : "resources/views/manual_payment_methods/customer_package_payment_request.blade.php"
},
{
"root_directory" : "addons/offline_payment/views/manual_payment_methods/edit.blade.php",
"update_directory" : "resources/views/manual_payment_methods/edit.blade.php"
},
{
"root_directory" : "addons/offline_payment/views/manual_payment_methods/index.blade.php",
"update_directory" : "resources/views/manual_payment_methods/index.blade.php"
},
{
"root_directory" : "addons/offline_payment/views/manual_payment_methods/seller_package_payment_request.blade.php",
"update_directory" : "resources/views/manual_payment_methods/seller_package_payment_request.blade.php"
},
{
"root_directory" : "addons/offline_payment/views/manual_payment_methods/wallet_request.blade.php",
"update_directory" : "resources/views/manual_payment_methods/wallet_request.blade.php"
},
{
"root_directory" : "addons/offline_payment/controllers/ManualPaymentMethodController.php",
"update_directory" : "app/Http/Controllers/ManualPaymentMethodController.php"
},
{
"root_directory" : "addons/offline_payment/assets/offline_banner.jpg",
"update_directory" : "public/offline_banner.jpg"
}
]
}

View File

@@ -0,0 +1,211 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\ManualPaymentMethod;
use App\Models\Order;
class ManualPaymentMethodController extends Controller
{
public function __construct() {
// Staff Permission Check
$this->middleware(['permission:view_all_manual_payment_methods'])->only('index');
$this->middleware(['permission:add_manual_payment_method'])->only('create');
$this->middleware(['permission:edit_manual_payment_method'])->only('edit');
$this->middleware(['permission:delete_manual_payment_method'])->only('destroy');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$manual_payment_methods = ManualPaymentMethod::all();
return view('manual_payment_methods.index', compact('manual_payment_methods'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('manual_payment_methods.create');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$manual_payment_method = new ManualPaymentMethod;
$manual_payment_method->type = $request->type;
$manual_payment_method->photo = $request->photo;
$manual_payment_method->heading = $request->heading;
$manual_payment_method->description = $request->description;
if($request->type == 'bank_payment')
{
$banks_informations = array();
for ($i=0; $i < count($request->bank_name); $i++) {
$item = array();
$item['bank_name'] = $request->bank_name[$i];
$item['account_name'] = $request->account_name[$i];
$item['account_number'] = $request->account_number[$i];
$item['routing_number'] = $request->routing_number[$i];
array_push($banks_informations, $item);
}
$manual_payment_method->bank_info = json_encode($banks_informations);
}
$manual_payment_method->save();
flash(translate('Method has been inserted successfully'))->success();
return redirect()->route('manual_payment_methods.index');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$manual_payment_method = ManualPaymentMethod::findOrFail(decrypt($id));
return view('manual_payment_methods.edit', compact('manual_payment_method'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$manual_payment_method = ManualPaymentMethod::findOrFail($id);
$manual_payment_method->type = $request->type;
$manual_payment_method->heading = $request->heading;
$manual_payment_method->description = $request->description;
if($request->type == 'bank_payment')
{
$banks_informations = array();
for ($i=0; $i < count($request->bank_name); $i++) {
$item = array();
$item['bank_name'] = $request->bank_name[$i];
$item['account_name'] = $request->account_name[$i];
$item['account_number'] = $request->account_number[$i];
$item['routing_number'] = $request->routing_number[$i];
array_push($banks_informations, $item);
}
$manual_payment_method->bank_info = json_encode($banks_informations);
}
$manual_payment_method->photo = $request->photo;
$manual_payment_method->save();
flash( translate('Method has been updated successfully'))->success();
return redirect()->route('manual_payment_methods.index');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
if(ManualPaymentMethod::destroy($id)){
flash(translate('Method has been deleted successfully'))->success();
}
else{
flash(translate('Something went wrong'))->error();
}
return redirect()->route('manual_payment_methods.index');
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function show_payment_modal(Request $request)
{
$order = Order::find($request->order_id);
if($order != null){
return view('frontend.user.payment_modal', compact('order'));
}
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function submit_offline_payment(Request $request)
{
$order = Order::findOrFail($request->order_id);
if($request->name != null && $request->amount != null && $request->trx_id != null){
$data['name'] = $request->name;
$data['amount'] = $request->amount;
$data['trx_id'] = $request->trx_id;
$data['photo'] = $request->photo;
}
else {
flash(translate('Please fill all the fields'))->warning();
return back();
}
$order->manual_payment_data = json_encode($data);
$order->payment_type = $request->payment_option;
$order->payment_status = 'Submitted';
$order->manual_payment = 1;
$order->save();
flash(translate('Your payment data has been submitted successfully'))->success();
return redirect()->route('home');
}
public function offline_recharge_modal(Request $request)
{
return view('frontend.user.wallet.offline_recharge_modal');
}
public function offline_customer_package_purchase_modal(Request $request)
{
$package_id = $request->package_id;
return view('manual_payment_methods.frontend.offline_customer_package_purchase_modal', compact('package_id'));
}
public function offline_seller_package_purchase_modal(Request $request)
{
$package_id = $request->package_id;
return view('manual_payment_methods.frontend.offline_seller_package_purchase_modal', compact('package_id'));
}
}

View File

@@ -0,0 +1,4 @@
ALTER TABLE `wallets` ADD `approval` INT(1) NOT NULL DEFAULT '0' AFTER `payment_details`, ADD `offline_payment` INT(1) NOT NULL DEFAULT '0' AFTER `approval`;
ALTER TABLE `wallets` ADD `reciept` VARCHAR(150) NULL DEFAULT NULL AFTER `offline_payment`;
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1,74 @@
-- phpMyAdmin SQL Dump
-- version 4.9.0.1
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Apr 07, 2020 at 03:02 PM
-- Server version: 10.3.16-MariaDB
-- PHP Version: 7.3.7
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `shop_new`
--
-- --------------------------------------------------------
--
-- Table structure for table `manual_payment_methods`
--
ALTER TABLE `orders` ADD `manual_payment` INT(1) NOT NULL DEFAULT '0' AFTER `payment_type`, ADD `manual_payment_data` TEXT NULL DEFAULT NULL AFTER `manual_payment`;
CREATE TABLE `manual_payment_methods` (
`id` int(11) NOT NULL,
`type` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`heading` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`description` text COLLATE utf8_unicode_ci DEFAULT NULL,
`bank_info` text COLLATE utf8_unicode_ci DEFAULT NULL,
`photo` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `manual_payment_methods`
--
ALTER TABLE `manual_payment_methods`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `manual_payment_methods`
--
ALTER TABLE `manual_payment_methods`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
ALTER TABLE `wallets` ADD `approval` INT(1) NOT NULL DEFAULT '0' AFTER `payment_details`, ADD `offline_payment` INT(1) NOT NULL DEFAULT '0' AFTER `approval`;
ALTER TABLE `wallets` ADD `reciept` VARCHAR(150) NULL DEFAULT NULL AFTER `offline_payment`;
COMMIT;

View File

@@ -0,0 +1,125 @@
@extends('backend.layouts.app')
@section('content')
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('Manual Payment Information')}}</h5>
</div>
<form action="{{ route('manual_payment_methods.store') }}" method="POST">
@csrf
<div class="card-body">
<div class="form-group row">
<label class="col-sm-2 col-from-label" for="type">{{translate('Type')}}</label>
<div class="col-sm-10">
<select class="form-control aiz-selectpicker" name="type" id="type" required>
<option value="custom_payment">{{translate('Custom Payment')}}</option>
<option value="bank_payment">{{translate('Bank Payment')}}</option>
<option value="check_payment">{{translate('Check Payment')}}</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-from-label" for="name">{{translate('Name')}}</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="heading" value="" placeholder="Name" required>
</div>
</div>
<div class="form-group row">
<label class="col-md-2 col-form-label" for="signinSrEmail">{{translate('Checkout Thumbnail')}} (438x235)px</label>
<div class="col-md-8">
<div class="input-group" data-toggle="aizuploader" data-type="image" data-multiple="false">
<div class="input-group-prepend">
<div class="input-group-text bg-soft-secondary font-weight-medium">{{ translate('Browse')}}</div>
</div>
<div class="form-control file-amount">{{ translate('Choose File') }}</div>
<input type="hidden" name="photo" class="selected-files">
</div>
<div class="file-preview box sm">
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-from-label">{{translate('Payment Instruction')}}</label>
<div class="col-sm-10">
<textarea class="aiz-text-editor" name="description"></textarea>
</div>
</div>
<div id="bank_payment_data">
<div id="bank_payment_informations">
<div class="form-group row">
<div class="row">
<label class="col-sm-2 col-from-label">{{translate('Bank Information')}}</label>
<div class="col-sm-8">
<div class="row">
<div class="col-sm-3"><input type="text" id="bank_name" name="bank_name[]" class="form-control" placeholder="{{ translate('Bank Name') }}"></div>
<div class="col-sm-3"><input type="text" id="account_name" name="account_name[]" class="form-control" placeholder="{{ translate('Account Name') }}"></div>
<div class="col-sm-3"><input type="text" id="account_number" name="account_number[]" class="form-control" placeholder="{{ translate('Account Number') }}"></div>
<div class="col-sm-3"><input type="text" id="routing_number" name="routing_number[]" class="form-control" placeholder="{{ translate('Routing Number') }}"></div>
</div>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-primary" onclick="addBankInfoRow()">{{ translate('Add More') }}</button>
</div>
</div>
</div>
</div>
</div>
<div class="form-group mb-3 text-right">
<button type="submit" class="btn btn-primary">{{translate('Save')}}</button>
</div>
</div>
</form>
<div class="d-none" id="bank_info_row">
<div class="form-group row">
<div class="row">
<label class="col-sm-2 col-from-label">{{translate('Bank Information')}}</label>
<div class="col-sm-8">
<div class="row">
<div class="col-sm-3"><input type="text" name="bank_name[]" class="form-control" placeholder="{{ translate('Bank Name') }}"></div>
<div class="col-sm-3"><input type="text" name="account_name[]" class="form-control" placeholder="{{ translate('Account Name') }}"></div>
<div class="col-sm-3"><input type="text" name="account_number[]" class="form-control" placeholder="{{ translate('Account Number') }}"></div>
<div class="col-sm-3"><input type="text" name="routing_number[]" class="form-control" placeholder="{{ translate('Routing Number') }}"></div>
</div>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger" onclick="removeBankInfoRow(this)">{{translate('Remove')}}</button>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('script')
<script type="text/javascript">
$(document).ready(function(){
$('#bank_payment_data').hide();
$('#type').on('change', function(){
if($('#type').val() == 'bank_payment'){
$('#bank_payment_data').show();
}
else {
$('#bank_payment_data').hide();
}
});
});
function addBankInfoRow(){
$('#bank_payment_informations').append($('#bank_info_row').html());
}
function removeBankInfoRow(el){
$(el).closest('.form-group').remove();
}
</script>
@endsection

View File

@@ -0,0 +1,85 @@
@extends('backend.layouts.app')
@section('content')
<div class="card">
<div class="card-header">
<h3 class="mb-0 h6">{{translate('Offline Customer Package Payment Requests')}}</h3>
</div>
<div class="card-body">
<table class="table aiz-table mb-0">
<thead>
<tr>
<th>#</th>
<th>{{translate('Name')}}</th>
<th>{{translate('Package')}}</th>
<th>{{translate('Method')}}</th>
<th>{{translate('TXN ID')}}</th>
<th>{{translate('Reciept')}}</th>
<th>{{translate('Approval')}}</th>
<th>{{translate('Date')}}</th>
</tr>
</thead>
<tbody>
@foreach($package_payment_requests as $key => $package_payment_request)
@if($package_payment_request->user != null && $package_payment_request->customer_package != null)
<tr>
<td>{{ ($key+1) }}</td>
<td>{{ $package_payment_request->user->name }}</td>
<td>{{ $package_payment_request->customer_package->getTranslation('name') }}</td>
<td>{{ $package_payment_request->payment_method }}</td>
<td>{{ $package_payment_request->payment_details }}</td>
<td>
@if ($package_payment_request->reciept != null)
<a href="{{ uploaded_asset($package_payment_request->reciept) }}" target="_blank">{{translate('Open Reciept')}}</a>
@endif
</td>
<td>
<label class="aiz-switch aiz-switch-success mb-0">
@if($package_payment_request->approval == 1)
<input type="checkbox" checked disabled>
@else
<input
@can('approve_offline_customer_package_payment') onchange="offline_payment_approval(this)" @endcan
id="payment_approval" type="checkbox"
value="{{ $package_payment_request->id }}"
@cannot('approve_offline_customer_package_payment') disabled @endcan
>
@endif
<span class="slider round"></span>
</label>
</td>
<td>{{ $package_payment_request->created_at }}</td>
</tr>
@endif
@endforeach
</tbody>
</table>
<div class="aiz-pagination">
{{ $package_payment_requests->links() }}
</div>
</div>
</div>
@endsection
@section('script')
<script type="text/javascript">
function offline_payment_approval(el){
if(el.checked){
var status = 1;
}
else{
var status = 0;
}
$.post('{{ route('offline_customer_package_payment.approved') }}', {_token:'{{ csrf_token() }}', id:el.value, status:status}, function(data){
if(data == 1){
$( "#payment_approval" ).prop( "disabled", true );
AIZ.plugins.notify('success', '{{ translate('Offline Customer Package Payment approved successfully') }}');
}
else{
AIZ.plugins.notify('danger', '{{ translate('Something went wrong') }}');
}
});
}
</script>
@endsection

View File

@@ -0,0 +1,137 @@
@extends('backend.layouts.app')
@section('content')
<div class="col-lg-12">
<div class="card">
<div class="card-header">
<h3 class="mb-0 h6">{{translate('Manual Payment Information')}}</h3>
</div>
<form action="{{ route('manual_payment_methods.update', $manual_payment_method->id) }}" method="POST">
<input name="_method" type="hidden" value="PATCH">
@csrf
<div class="card-body">
<div class="form-group row">
<label class="col-sm-2 col-from-label" for="type">{{translate('Type')}}</label>
<div class="col-sm-10">
<select class="form-control aiz-selectpicker" name="type" id="type" required>
<option value="custom_payment" @if($manual_payment_method->type == 'custom_payment') selected @endif>{{translate('Custom Payment')}}</option>
<option value="bank_payment" @if($manual_payment_method->type == 'bank_payment') selected @endif>{{translate('Bank Payment')}}</option>
<option value="check_payment" @if($manual_payment_method->type == 'check_payment') selected @endif>{{translate('Check Payment')}}</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-from-label" for="name">{{translate('Heading')}}</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="heading" value="{{ $manual_payment_method->heading }}" placeholder="" required>
</div>
</div>
<div class="form-group row">
<label class="col-md-2 col-form-label" for="signinSrEmail">{{translate('Checkout Thumbnail')}} (438x235)px</label>
<div class="col-md-8">
<div class="input-group" data-toggle="aizuploader" data-type="image" data-multiple="false">
<div class="input-group-prepend">
<div class="input-group-text bg-soft-secondary font-weight-medium">{{ translate('Browse')}}</div>
</div>
<div class="form-control file-amount">{{ translate('Choose File') }}</div>
<input type="hidden" name="photo" value="{{ $manual_payment_method->photo }}" class="selected-files">
</div>
<div class="file-preview box sm">
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-from-label">{{translate('Payment Instruction')}}</label>
<div class="col-sm-10">
<textarea class="aiz-text-editor" name="description">@php echo $manual_payment_method->description @endphp</textarea>
</div>
</div>
<div id="bank_payment_data">
<div id="bank_payment_informations">
@if($manual_payment_method->bank_info != null)
@foreach (json_decode($manual_payment_method->bank_info) as $key => $bank_info)
<div class="form-group row">
<div class="row">
<label class="col-sm-2 col-from-label">{{translate('Bank Information')}}</label>
<div class="col-sm-8">
<div class="row">
<div class="col-sm-3"><input type="text" name="bank_name[]" class="form-control" placeholder="{{ translate('Bank Name') }}" value="{{ $bank_info->bank_name }}"></div>
<div class="col-sm-3"><input type="text" name="account_name[]" class="form-control" placeholder="{{ translate('Account Name') }}" value="{{ $bank_info->account_name }}"></div>
<div class="col-sm-3"><input type="text" name="account_number[]" class="form-control" placeholder="{{ translate('Account Number') }}" value="{{ $bank_info->account_number }}"></div>
<div class="col-sm-3"><input type="text" name="routing_number[]" class="form-control" placeholder="{{ translate('Routing Number') }}" value="{{ $bank_info->routing_number }}"></div>
</div>
</div>
<div class="col-sm-2">
@if ($key == 0)
<button type="button" class="btn btn-primary" onclick="addBankInfoRow()">{{ translate('Add More') }}</button>
@else
<div class="col-sm-1">
<button type="button" class="btn btn-danger" onclick="removeBankInfoRow(this)">{{ translate('Remove') }}</button>
</div>
@endif
</div>
</div>
</div>
@endforeach
@endif
</div>
</div>
</div>
<div class="form-group mb-3 text-right">
<button type="submit" class="btn btn-primary">{{translate('Save')}}</button>
</div>
</form>
<!--===================================================-->
<!--End Horizontal Form-->
<div class="d-none" id="bank_info_row">
<div class="form-group row">
<div class="row">
<label class="col-sm-2 col-from-label">{{translate('Bank Information')}}</label>
<div class="col-sm-8">
<div class="row">
<div class="col-sm-3"><input type="text" name="bank_name[]" class="form-control" placeholder="{{ translate('Bank Name') }}"></div>
<div class="col-sm-3"><input type="text" name="account_name[]" class="form-control" placeholder="{{ translate('Account Name') }}"></div>
<div class="col-sm-3"><input type="text" name="account_number[]" class="form-control" placeholder="{{ translate('Account Number') }}"></div>
<div class="col-sm-3"><input type="text" name="routing_number[]" class="form-control" placeholder="{{ translate('Routing Number') }}"></div>
</div>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger" onclick="removeBankInfoRow(this)">{{translate('Remove')}}</button>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('script')
<script type="text/javascript">
$(document).ready(function(){
$('#type').on('change', function(){
if($('#type').val() == 'bank_payment'){
$('#bank_payment_data').show();
}
else {
$('#bank_payment_data').hide();
}
});
});
function addBankInfoRow(){
$('#bank_payment_informations').append($('#bank_info_row').html());
}
function removeBankInfoRow(el){
$(el).closest('.form-group').remove();
}
</script>
@endsection

View File

@@ -0,0 +1,81 @@
<form class="" action="{{ route('customer_package.make_offline_payment') }}" method="post" enctype="multipart/form-data">
@csrf
<input type="hidden" name="package_id" value="{{$package_id}}">
<div class="modal-body gry-bg px-3 pt-3 mx-auto c-scrollbar-light">
<div class="align-items-center gutters-5 row">
@foreach(\App\Models\ManualPaymentMethod::all() as $method)
<div class="col-6 col-md-4">
<label class="aiz-megabox d-block mb-3">
<input value="{{ $method->heading }}" id="payment_option" type="radio" name="payment_option" onchange="toggleManualPaymentData({{ $method->id }})" data-id="{{ $method->id }}" checked>
<span class="d-block p-3 aiz-megabox-elem">
<img src="{{ uploaded_asset($method->photo) }}" class="img-fluid mb-2">
<span class="d-block text-center">
<span class="d-block fw-600 fs-15">{{ $method->heading }}</span>
</span>
</span>
</label>
</div>
@endforeach
</div>
<div id="manual_payment_data">
<div class="card rounded-0 shadow-none border mb-3 p-3 d-none">
<div id="manual_payment_description">
</div>
</div>
<div class="card rounded-0 shadow-none border mb-3 p-3">
<div class="row">
<div class="col-md-3">
<label>{{ translate('Transaction ID')}} <span class="text-danger">*</span></label>
</div>
<div class="col-md-9">
<input type="text" class="form-control mb-3 rounded-0" name="trx_id" placeholder="{{ translate('Transaction ID') }}" required>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 col-form-label">{{ translate('Photo') }}</label>
<div class="col-md-9">
<div class="input-group" data-toggle="aizuploader" data-type="image">
<div class="input-group-prepend">
<div class="input-group-text bg-soft-secondary font-weight-medium rounded-0">{{ translate('Browse')}}</div>
</div>
<div class="form-control file-amount">{{ translate('Choose image') }}</div>
<input type="hidden" name="photo" class="selected-files">
</div>
<div class="file-preview box sm">
</div>
</div>
</div>
</div>
</div>
<div class="form-group text-right">
<button type="submit" class="btn btn-sm btn-primary rounded-0 w-150px transition-3d-hover">{{translate('Confirm')}}</button>
</div>
</div>
</form>
@foreach(\App\Models\ManualPaymentMethod::all() as $method)
<div id="manual_payment_info_{{ $method->id }}" class="d-none">
<div>@php echo $method->description @endphp</div>
@if ($method->bank_info != null)
<ul>
@foreach (json_decode($method->bank_info) as $key => $info)
<li>{{ translate('Bank Name') }} - {{ $info->bank_name }}, {{ translate('Account Name') }} - {{ $info->account_name }}, {{ translate('Account Number') }} - {{ $info->account_number}}, {{ translate('Routing Number') }} - {{ $info->routing_number }}</li>
@endforeach
</ul>
@endif
</div>
@endforeach
<script type="text/javascript">
$(document).ready(function(){
toggleManualPaymentData($('input[name=payment_option]:checked').data('id'));
});
function toggleManualPaymentData(id){
$('#manual_payment_description').parent().removeClass('d-none');
$('#manual_payment_description').html($('#manual_payment_info_'+id).html());
}
</script>

View File

@@ -0,0 +1,77 @@
<form class="" action="{{ route('seller.make_offline_payment') }}" method="post" enctype="multipart/form-data">
@csrf
<input type="hidden" name="package_id" value="{{$package_id}}">
<div class="modal-body gry-bg px-3 pt-3 mx-auto">
<div class="align-items-center gutters-5 row">
@foreach(\App\Models\ManualPaymentMethod::all() as $method)
<div class="col-6 col-md-4">
<label class="aiz-megabox d-block mb-3">
<input value="{{ $method->heading }}" id="payment_option" type="radio" name="payment_option" onchange="toggleManualPaymentData({{ $method->id }})" checked>
<span class="d-block p-3 aiz-megabox-elem">
<img src="{{ uploaded_asset($method->photo) }}" class="img-fluid mb-2">
<span class="d-block text-center">
<span class="d-block fw-600 fs-15">{{ $method->heading }}</span>
</span>
</span>
</label>
</div>
@endforeach
</div>
<div id="manual_payment_data">
<div class="card mb-3 p-3 d-none">
<div id="manual_payment_description">
</div>
</div>
<div class="card mb-3 p-3">
<div class="row">
<div class="col-md-3">
<label>{{ translate('Transaction ID')}} <span class="text-danger">*</span></label>
</div>
<div class="col-md-9">
<input type="text" class="form-control mb-3" name="trx_id" placeholder="{{ translate('Transaction ID') }}" required>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 col-form-label">{{ translate('Photo') }}</label>
<div class="col-md-9">
<div class="input-group" data-toggle="aizuploader" data-type="image">
<div class="input-group-prepend">
<div class="input-group-text bg-soft-secondary font-weight-medium">{{ translate('Browse')}}</div>
</div>
<div class="form-control file-amount">{{ translate('Choose image') }}</div>
<input type="hidden" name="photo" class="selected-files">
</div>
<div class="file-preview box sm">
</div>
</div>
</div>
</div>
</div>
<div class="form-group text-right">
<button type="submit" class="btn btn-sm btn-primary transition-3d-hover mr-1">{{translate('Confirm')}}</button>
</div>
</div>
</form>
@foreach(\App\Models\ManualPaymentMethod::all() as $method)
<div id="manual_payment_info_{{ $method->id }}" class="d-none">
<div>@php echo $method->description @endphp</div>
@if ($method->bank_info != null)
<ul>
@foreach (json_decode($method->bank_info) as $key => $info)
<li>{{ translate('Bank Name') }} - {{ $info->bank_name }}, {{ translate('Account Name') }} - {{ $info->account_name }}, {{ translate('Account Number') }} - {{ $info->account_number}}, {{ translate('Routing Number') }} - {{ $info->routing_number }}</li>
@endforeach
</ul>
@endif
</div>
@endforeach
<script type="text/javascript">
function toggleManualPaymentData(id){
$('#manual_payment_description').parent().removeClass('d-none');
$('#manual_payment_description').html($('#manual_payment_info_'+id).html());
}
</script>

View File

@@ -0,0 +1,58 @@
@extends('backend.layouts.app')
@section('content')
@can('add_manual_payment_method')
<div class="aiz-titlebar mt-2 mb-3">
<div class="text-md-right">
<a href="{{ route('manual_payment_methods.create') }}" class="btn btn-circle btn-info">
<span>{{translate('Add New Payment Method')}}</span>
</a>
</div>
</div>
@endcan
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('Manual Payment Method')}}</h5>
</div>
<div class="card-body">
<table class="table aiz-table" cellspacing="0" width="100%">
<thead>
<tr>
<th>#</th>
<th>{{translate('Heading')}}</th>
<th>{{translate('Logo')}}</th>
<th width="10%" class="text-right">{{translate('Options')}}</th>
</tr>
</thead>
<tbody>
@foreach($manual_payment_methods as $key => $manual_payment_method)
<tr>
<td>{{ ($key+1) }}</td>
<td>{{ $manual_payment_method->heading }}</td>
<td><img class="w-50px" src="{{ uploaded_asset($manual_payment_method->photo) }}" alt="Logo"></td>
<td class="text-right">
@can('edit_manual_payment_method')
<a class="btn btn-soft-primary btn-icon btn-circle btn-sm" href="{{route('manual_payment_methods.edit', encrypt($manual_payment_method->id))}}" title="{{ translate('Edit') }}">
<i class="las la-edit"></i>
</a>
@endcan
@can('delete_manual_payment_method')
<a href="#" class="btn btn-soft-danger btn-icon btn-circle btn-sm confirm-delete" data-href="{{route('manual_payment_methods.destroy', $manual_payment_method->id)}}" title="{{ translate('Delete') }}">
<i class="las la-trash"></i>
</a>
@endcan
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
@section('modal')
@include('modals.delete_modal')
@endsection

View File

@@ -0,0 +1,85 @@
@extends('backend.layouts.app')
@section('content')
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('Offline Seller Package Payment Requests')}}</h5>
</div>
<div class="card-body">
<table class="table aiz-table mb-0">
<thead>
<tr>
<th>#</th>
<th>{{translate('Name')}}</th>
<th>{{translate('Package')}}</th>
<th>{{translate('Method')}}</th>
<th>{{translate('TXN ID')}}</th>
<th>{{translate('Reciept')}}</th>
<th>{{translate('Approval')}}</th>
<th>{{translate('Date')}}</th>
</tr>
</thead>
<tbody>
@foreach($package_payment_requests as $key => $package_payment_request)
@if ($package_payment_request->user != null)
<tr>
<td>{{ ($key+1) }}</td>
<td>{{ $package_payment_request->user->name}}</td>
<td>{{ $package_payment_request->seller_package->name ?? translate('Package Unavailable') }}</td>
<td>{{ $package_payment_request->payment_method }}</td>
<td>{{ $package_payment_request->payment_details }}</td>
<td>
@if ($package_payment_request->reciept != null)
<a href="{{ uploaded_asset($package_payment_request->reciept) }}" target="_blank">{{translate('Open Reciept')}}</a>
@endif
</td>
<td>
<label class="aiz-switch aiz-switch-success mb-0">
@if($package_payment_request->approval == 1)
<input type="checkbox" checked disabled>
@else
<input
@can('approve_offline_seller_package_payment') onchange="offline_payment_approval(this)" @endcan
id="payment_approval" type="checkbox"
value="{{ $package_payment_request->id }}"
@cannot('approve_offline_seller_package_payment') disabled @endcan
>
@endif
<span class="slider round"></span>
</label>
</td>
<td>{{ $package_payment_request->created_at }}</td>
</tr>
@endif
@endforeach
</tbody>
</table>
<div class="aiz-pagination">
{{ $package_payment_requests->links() }}
</div>
</div>
</div>
@endsection
@section('script')
<script type="text/javascript">
function offline_payment_approval(el){
if(el.checked){
var status = 1;
}
else{
var status = 0;
}
$.post('{{ route('offline_seller_package_payment.approved') }}', {_token:'{{ csrf_token() }}', id:el.value, status:status}, function(data){
if(data == 1){
$( "#payment_approval" ).prop( "disabled", true );
AIZ.plugins.notify('success', '{{ translate('Offline Seller Package Payment approved successfully') }}');
}
else{
AIZ.plugins.notify('danger', '{{ translate('Something went wrong') }}');
}
});
}
</script>
@endsection

View File

@@ -0,0 +1,80 @@
@extends('backend.layouts.app')
@section('content')
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('Offline Wallet Recharge Requests')}}</h5>
</div>
<div class="card-body">
<table class="table aiz-table mb-0">
<thead>
<tr>
<th>#</th>
<th>{{translate('Name')}}</th>
<th>{{translate('Amount')}}</th>
<th>{{translate('Method')}}</th>
<th>{{translate('TXN ID')}}</th>
<th>{{translate('Photo')}}</th>
<th>{{translate('Approval')}}</th>
<th>{{translate('Date')}}</th>
</tr>
</thead>
<tbody>
@foreach($wallets as $key => $wallet)
@if ($wallet->user != null)
<tr>
<td>{{ ($key+1) }}</td>
<td>{{ $wallet->user->name }}</td>
<td>{{ $wallet->amount }}</td>
<td>{{ $wallet->payment_method }}</td>
<td>{{ $wallet->payment_details }}</td>
<td>
@if ($wallet->reciept != null)
<a href="{{ uploaded_asset($wallet->reciept) }}" target="_blank">{{translate('Open Reciept')}}</a>
@endif
</td>
<td>
<label class="aiz-switch aiz-switch-success mb-0">
<input
@can('approve_offline_wallet_recharge') onchange="update_approved(this)" @endcan
value="{{ $wallet->id }}" type="checkbox"
@if($wallet->approval == 1) checked @endif
@cannot('approve_offline_wallet_recharge') disabled @endcan
>
<span class="slider round"></span>
</label>
</td>
<td>{{ $wallet->created_at }}</td>
</tr>
@endif
@endforeach
</tbody>
</table>
<div class="aiz-pagination">
{{ $wallets->links() }}
</div>
</div>
</div>
@endsection
@section('script')
<script type="text/javascript">
function update_approved(el){
if(el.checked){
var status = 1;
}
else{
var status = 0;
}
$.post('{{ route('offline_recharge_request.approved') }}', {_token:'{{ csrf_token() }}', id:el.value, status:status}, function(data){
if(data == 1){
AIZ.plugins.notify('success', '{{ translate('Money has been added successfully') }}');
}
else{
AIZ.plugins.notify('danger', '{{ translate('Something went wrong') }}');
}
});
}
</script>
@endsection

View File

@@ -0,0 +1,73 @@
<?php
namespace App\Utility;
use App\Models\ProductStock;
use App\Models\Address;
use App\Models\Country;
use App\Models\State;
use App\Models\City;
class PosUtility
{
public static function product_search($request_data): object
{
$product_query = ProductStock::query()->join('products', 'product_stocks.product_id', '=', 'products.id');
if (auth()->user()->user_type == 'seller') {
$product_query->where('products.user_id', auth()->user()->id);
} else {
$product_query->where('products.added_by', 'admin');
}
$products = $product_query->where('products.auction_product', 0)
->where('products.wholesale_product', 0)
->where('products.published', 1)
->where('products.approved', 1)
->select('products.*', 'product_stocks.id as stock_id', 'product_stocks.variant', 'product_stocks.price as stock_price', 'product_stocks.qty as stock_qty', 'product_stocks.image as stock_image')
->orderBy('products.created_at', 'desc');
if ($request_data['category'] != null) {
$arr = explode('-', $request_data['category']);
if ($arr[0] == 'category') {
$category_ids = CategoryUtility::children_ids($arr[1]);
$category_ids[] = $arr[1];
$products = $products->whereIn('products.category_id', $category_ids);
}
}
if ($request_data['brand'] != null) {
$products = $products->where('products.brand_id', $request_data['brand']);
}
if ($request_data['keyword'] != null) {
$products = $products->where('products.name', 'like', '%' . $request_data['keyword'] . '%')->orWhere('products.barcode', $request_data['keyword']);
}
return $products->paginate(16);
}
public static function get_shipping_address($request) : array {
if ($request->address_id != null) {
$address = Address::findOrFail($request->address_id);
$data['name'] = $address->user->name;
$data['email'] = $address->user->email;
$data['address'] = $address->address;
$data['country'] = $address->country->name;
$data['state'] = $address->state->name;
$data['city'] = $address->city->name;
$data['postal_code'] = $address->postal_code;
$data['phone'] = $address->phone;
} else {
$data['name'] = $request->name;
$data['email'] = $request->email;
$data['address'] = $request->address;
$data['country'] = Country::find($request->country_id)->name;
$data['state'] = State::find($request->state_id)->name;
$data['city'] = City::find($request->city_id)->name;
$data['postal_code'] = $request->postal_code;
$data['phone'] = $request->phone;
}
return $data;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@@ -0,0 +1,91 @@
{
"name" : "Point of Sale",
"unique_identifier" : "pos_system",
"version" : "2.1",
"minimum_item_version" : "7.5.0",
"addon_banner" : "pos_banner.png",
"directory" :
[
{
"name" : [
"resources/views/backend/pos",
"resources/views/seller/pos"
]
}
],
"sql_file" : "",
"files" :
[
{
"root_directory" : "addons/pos_system/views/backend/pos/cart.blade.php",
"update_directory" : "resources/views/backend/pos/cart.blade.php"
},
{
"root_directory" : "addons/pos_system/views/backend/pos/guest_shipping_address.blade.php",
"update_directory" : "resources/views/backend/pos/guest_shipping_address.blade.php"
},
{
"root_directory" : "addons/pos_system/views/backend/pos/index.blade.php",
"update_directory" : "resources/views/backend/pos/index.blade.php"
},
{
"root_directory" : "addons/pos_system/views/backend/pos/pos_activation.blade.php",
"update_directory" : "resources/views/backend/pos/pos_activation.blade.php"
},
{
"root_directory" : "addons/pos_system/views/backend/pos/shipping_address.blade.php",
"update_directory" : "resources/views/backend/pos/shipping_address.blade.php"
},
{
"root_directory" : "addons/pos_system/views/backend/pos/variants.blade.php",
"update_directory" : "resources/views/backend/pos/variants.blade.php"
},
{
"root_directory" : "addons/pos_system/views/backend/pos/order_summary.blade.php",
"update_directory" : "resources/views/backend/pos/order_summary.blade.php"
},
{
"root_directory" : "addons/pos_system/views/backend/pos/thermal_invoice.blade.php",
"update_directory" : "resources/views/backend/pos/thermal_invoice.blade.php"
},
{
"root_directory" : "addons/pos_system/views/seller/pos/guest_shipping_address.blade.php",
"update_directory" : "resources/views/seller/pos/guest_shipping_address.blade.php"
},
{
"root_directory" : "addons/pos_system/views/seller/pos/index.blade.php",
"update_directory" : "resources/views/seller/pos/index.blade.php"
},
{
"root_directory" : "addons/pos_system/views/seller/pos/pos_activation.blade.php",
"update_directory" : "resources/views/seller/pos/pos_activation.blade.php"
},
{
"root_directory" : "addons/pos_system/views/seller/pos/shipping_address.blade.php",
"update_directory" : "resources/views/seller/pos/shipping_address.blade.php"
},
{
"root_directory" : "addons/pos_system/controllers/PosController.php",
"update_directory" : "app/Http/Controllers/PosController.php"
},
{
"root_directory" : "addons/pos_system/controllers/Seller/PosController.php",
"update_directory" : "app/Http/Controllers/Seller/PosController.php"
},
{
"root_directory" : "addons/pos_system/Utility/PosUtility.php",
"update_directory" : "app/Utility/PosUtility.php"
},
{
"root_directory" : "addons/pos_system/assets/pos_banner.png",
"update_directory" : "public/pos_banner.png"
}
]
}

View File

@@ -0,0 +1,397 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\OrderDetail;
use App\Models\ProductStock;
use App\Models\Product;
use App\Models\Order;
use App\Models\City;
use App\Models\User;
use App\Models\Address;
use App\Models\Addon;
use Session;
use Auth;
use Mail;
use App\Mail\InvoiceEmailManager;
use App\Http\Resources\PosProductCollection;
use App\Models\Country;
use App\Models\State;
use App\Utility\CategoryUtility;
use App\Utility\FontUtility;
use App\Utility\PosUtility;
use Mpdf\Mpdf;
class PosController extends Controller
{
public function __construct()
{
// Staff Permission Check
$this->middleware(['permission:pos_manager'])->only('admin_index');
$this->middleware(['permission:pos_configuration'])->only('pos_activation');
}
public function index()
{
$customers = User::where('user_type', 'customer')->where('email_verified_at', '!=', null)->orderBy('created_at', 'desc')->get();
return view('backend.pos.index', compact('customers'));
}
public function search(Request $request)
{
$products = PosUtility::product_search($request->only('category', 'brand', 'keyword'));
$stocks = new PosProductCollection($products);
$stocks->appends(['keyword' => $request->keyword, 'category' => $request->category, 'brand' => $request->brand]);
return $stocks;
}
public function addToCart(Request $request)
{
$stock = ProductStock::find($request->stock_id);
$product = $stock->product;
$data = array();
$data['stock_id'] = $request->stock_id;
$data['id'] = $product->id;
$data['variant'] = $stock->variant;
$data['quantity'] = $product->min_qty;
if ($stock->qty < $product->min_qty && $product->digital == 0) {
return array('success' => 0, 'message' => translate("This product doesn't have enough stock for minimum purchase quantity ") . $product->min_qty, 'view' => view('backend.pos.cart')->render());
}
$tax = 0;
$price = $stock->price;
// discount calculation
$discount_applicable = false;
if ($product->discount_start_date == null) {
$discount_applicable = true;
} elseif (
strtotime(date('d-m-Y H:i:s')) >= $product->discount_start_date &&
strtotime(date('d-m-Y H:i:s')) <= $product->discount_end_date
) {
$discount_applicable = true;
}
if ($discount_applicable) {
if ($product->discount_type == 'percent') {
$price -= ($price * $product->discount) / 100;
} elseif ($product->discount_type == 'amount') {
$price -= $product->discount;
}
}
//tax calculation
foreach ($product->taxes as $product_tax) {
if ($product_tax->tax_type == 'percent') {
$tax += ($price * $product_tax->tax) / 100;
} elseif ($product_tax->tax_type == 'amount') {
$tax += $product_tax->tax;
}
}
$data['price'] = $price;
$data['tax'] = $tax;
if ($request->session()->has('pos.cart')) {
$foundInCart = false;
$cart = collect();
foreach ($request->session()->get('pos.cart') as $key => $cartItem) {
if ($cartItem['id'] == $product->id && $cartItem['stock_id'] == $stock->id) {
$foundInCart = true;
if ($product->digital == 0) {
$loop_product = Product::find($cartItem['id']);
$product_stock = $loop_product->stocks->where('variant', $cartItem['variant'])->first();
if ($product->digital == 1 || $product_stock->qty >= ($cartItem['quantity'] + 1)) {
$cartItem['quantity'] += 1;
} else {
return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('backend.pos.cart')->render());
}
} else {
return array('success' => 0, 'message' => translate("This product is alreday in the cart"), 'view' => view('backend.pos.cart')->render());
}
}
$cart->push($cartItem);
}
if (!$foundInCart) {
$cart->push($data);
}
$request->session()->put('pos.cart', $cart);
} else {
$cart = collect([$data]);
$request->session()->put('pos.cart', $cart);
}
$request->session()->put('pos.cart', $cart);
return array('success' => 1, 'message' => '', 'view' => view('backend.pos.cart')->render());
}
//updated the quantity for a cart item
public function updateQuantity(Request $request)
{
$cart = $request->session()->get('pos.cart', collect([]));
$cart = $cart->map(function ($object, $key) use ($request) {
if ($key == $request->key) {
$product = Product::find($object['id']);
$product_stock = $product->stocks->where('id', $object['stock_id'])->first();
if ($product_stock->qty >= $request->quantity) {
$object['quantity'] = $request->quantity;
} else {
return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('backend.pos.cart')->render());
}
}
return $object;
});
$request->session()->put('pos.cart', $cart);
return array('success' => 1, 'message' => '', 'view' => view('backend.pos.cart')->render());
}
//removes from Cart
public function removeFromCart(Request $request)
{
if (Session::has('pos.cart')) {
$cart = Session::get('pos.cart', collect([]));
$cart->forget($request->key);
Session::put('pos.cart', $cart);
$request->session()->put('pos.cart', $cart);
}
return view('backend.pos.cart');
}
//Shipping Address for admin
public function getShippingAddress(Request $request)
{
$user_id = $request->id;
if ($user_id == '') {
return view('backend.pos.guest_shipping_address');
} else {
return view('backend.pos.shipping_address', compact('user_id'));
}
}
public function set_shipping_address(Request $request)
{
$data = PosUtility::get_shipping_address($request);
$shipping_info = $data;
$request->session()->put('pos.shipping_info', $shipping_info);
}
//set Discount
public function setDiscount(Request $request)
{
if ($request->discount >= 0) {
Session::put('pos.discount', $request->discount);
}
return view('backend.pos.cart');
}
//set Shipping Cost
public function setShipping(Request $request)
{
if ($request->shipping != null) {
Session::put('pos.shipping', $request->shipping);
}
return view('backend.pos.cart');
}
//order summary
public function get_order_summary(Request $request)
{
return view('backend.pos.order_summary');
}
//order place
public function order_store(Request $request)
{
if (Session::get('pos.shipping_info') == null || Session::get('pos.shipping_info')['name'] == null || Session::get('pos.shipping_info')['phone'] == null || Session::get('pos.shipping_info')['address'] == null) {
return array('success' => 0, 'message' => translate("Please Add Shipping Information."));
}
if (Session::has('pos.cart') && count(Session::get('pos.cart')) > 0) {
$order = new Order;
if ($request->user_id == null) {
$order->guest_id = mt_rand(100000, 999999);
} else {
$order->user_id = $request->user_id;
}
$order->shipping_address = json_encode(Session::get('pos.shipping_info'));
$order->payment_type = $request->payment_type;
$order->delivery_viewed = '0';
$order->payment_status_viewed = '0';
$order->code = date('Ymd-His') . rand(10, 99);
$order->date = strtotime('now');
$order->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
$order->payment_details = $request->payment_type;
$order->order_from = 'pos';
if ($request->payment_type == 'offline_payment') {
if ($request->offline_trx_id == null) {
return array('success' => 0, 'message' => translate("Transaction ID can not be null."));
}
$data['name'] = $request->offline_payment_method;
$data['amount'] = $request->offline_payment_amount;
$data['trx_id'] = $request->offline_trx_id;
$data['photo'] = $request->offline_payment_proof;
$order->manual_payment_data = json_encode($data);
$order->manual_payment = 1;
}
if ($order->save()) {
$subtotal = 0;
$tax = 0;
foreach (Session::get('pos.cart') as $key => $cartItem) {
$product_stock = ProductStock::find($cartItem['stock_id']);
$product = $product_stock->product;
$product_variation = $product_stock->variant;
$subtotal += $cartItem['price'] * $cartItem['quantity'];
$tax += $cartItem['tax'] * $cartItem['quantity'];
if ($product->digital == 0) {
if ($cartItem['quantity'] > $product_stock->qty) {
$order->delete();
return array('success' => 0, 'message' => $product->name . ' (' . $product_variation . ') ' . translate(" just stock outs."));
} else {
$product_stock->qty -= $cartItem['quantity'];
$product_stock->save();
}
}
$order_detail = new OrderDetail;
$order_detail->order_id = $order->id;
$order_detail->seller_id = $product->user_id;
$order_detail->product_id = $product->id;
$order_detail->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
$order_detail->variation = $product_variation;
$order_detail->price = $cartItem['price'] * $cartItem['quantity'];
$order_detail->tax = $cartItem['tax'] * $cartItem['quantity'];
$order_detail->quantity = $cartItem['quantity'];
$order_detail->shipping_type = null;
if (Session::get('pos.shipping', 0) >= 0) {
$order_detail->shipping_cost = Session::get('pos.shipping', 0) / count(Session::get('pos.cart'));
} else {
$order_detail->shipping_cost = 0;
}
$order_detail->save();
$product->num_of_sale++;
$product->save();
}
$order->grand_total = $subtotal + $tax + Session::get('pos.shipping', 0);
if (Session::has('pos.discount')) {
$order->grand_total -= Session::get('pos.discount');
$order->coupon_discount = Session::get('pos.discount');
}
$order->seller_id = $product->user_id;
$order->save();
$array['view'] = 'emails.invoice';
$array['subject'] = 'Your order has been placed - ' . $order->code;
$array['from'] = env('MAIL_USERNAME');
$array['order'] = $order;
$admin_products = array();
$seller_products = array();
foreach ($order->orderDetails as $key => $orderDetail) {
if ($orderDetail->product->added_by == 'admin') {
array_push($admin_products, $orderDetail->product->id);
} else {
$product_ids = array();
if (array_key_exists($orderDetail->product->user_id, $seller_products)) {
$product_ids = $seller_products[$orderDetail->product->user_id];
}
array_push($product_ids, $orderDetail->product->id);
$seller_products[$orderDetail->product->user_id] = $product_ids;
}
}
foreach ($seller_products as $key => $seller_product) {
try {
Mail::to(User::find($key)->email)->queue(new InvoiceEmailManager($array));
} catch (\Exception $e) {
}
}
//sends email to customer with the invoice pdf attached
if (env('MAIL_USERNAME') != null) {
try {
Mail::to($request->session()->get('pos.shipping_info')['email'])->queue(new InvoiceEmailManager($array));
Mail::to(User::where('user_type', 'admin')->first()->email)->queue(new InvoiceEmailManager($array));
} catch (\Exception $e) {
}
}
if ($request->user_id != NULL && $order->payment_status == 'paid') {
calculateCommissionAffilationClubPoint($order);
}
Session::forget('pos.shipping_info');
Session::forget('pos.shipping');
Session::forget('pos.discount');
Session::forget('pos.cart');
return array('success' => 1, 'message' => translate('Order Completed Successfully.'));
} else {
return array('success' => 0, 'message' => translate('Please input customer information.'));
}
}
return array('success' => 0, 'message' => translate("Please select a product."));
}
public function configuration()
{
return view('backend.pos.pos_activation');
}
public function invoice($id)
{
$order = Order::findOrFail($id);
$print_width = get_setting('print_width');
if ($print_width == null) {
flash(translate('Thermal printer size is not given in POS configuration'))->warning();
return back();
}
$pdf_style_data = FontUtility::get_font_family();
$html = view('backend.pos.thermal_invoice', compact('order', 'pdf_style_data'));
$mpdf = new Mpdf(['mode' => 'utf-8', 'format' => [$print_width, 1000]]);
$mpdf->WriteHTML($html);
// $mpdf->WriteHTML('<h1>Hello world!</h1>');
$mpdf->page = 0;
$mpdf->state = 0;
unset($mpdf->pages[0]);
// The $p needs to be passed by reference
$p = 'P';
// dd($mpdf->y);
$mpdf->_setPageSize(array($print_width, $mpdf->y), $p);
$mpdf->addPage();
$mpdf->WriteHTML($html);
$mpdf->Output('order-' . $order->code . '.pdf', 'I');
}
}

View File

@@ -0,0 +1,403 @@
<?php
namespace App\Http\Controllers\Seller;
use Illuminate\Http\Request;
use App\Models\OrderDetail;
use App\Models\ProductStock;
use App\Models\Product;
use App\Models\Order;
use App\Models\City;
use App\Models\User;
use App\Models\Address;
use App\Models\Addon;
use Session;
use Auth;
use Mail;
use App\Mail\InvoiceEmailManager;
use App\Http\Resources\PosProductCollection;
use App\Models\Country;
use App\Models\State;
use App\Utility\CategoryUtility;
use App\Utility\FontUtility;
use App\Utility\PosUtility;
use Mpdf\Mpdf;
class PosController extends Controller
{
public function index()
{
$customers = User::where('user_type', 'customer')->where('email_verified_at', '!=', null)->orderBy('created_at', 'desc')->get();
if (get_setting('pos_activation_for_seller') == 1) {
return view('seller.pos.index', compact('customers'));
}
else {
flash(translate('POS is disable for Sellers!!!'))->error();
return back();
}
}
public function search(Request $request)
{
$products = PosUtility::product_search($request->only('category', 'brand', 'keyword'));
$stocks = new PosProductCollection($products);
$stocks->appends(['keyword' => $request->keyword, 'category' => $request->category, 'brand' => $request->brand]);
return $stocks;
}
public function addToCart(Request $request)
{
$stock = ProductStock::find($request->stock_id);
$product = $stock->product;
$data = array();
$data['stock_id'] = $request->stock_id;
$data['id'] = $product->id;
$data['variant'] = $stock->variant;
$data['quantity'] = $product->min_qty;
if($stock->qty < $product->min_qty && $product->digital == 0){
return array('success' => 0, 'message' => translate("This product doesn't have enough stock for minimum purchase quantity ").$product->min_qty, 'view' => view('backend.pos.cart')->render());
}
$tax = 0;
$price = $stock->price;
// discount calculation
$discount_applicable = false;
if ($product->discount_start_date == null) {
$discount_applicable = true;
}
elseif (strtotime(date('d-m-Y H:i:s')) >= $product->discount_start_date &&
strtotime(date('d-m-Y H:i:s')) <= $product->discount_end_date) {
$discount_applicable = true;
}
if ($discount_applicable) {
if($product->discount_type == 'percent'){
$price -= ($price*$product->discount)/100;
}
elseif($product->discount_type == 'amount'){
$price -= $product->discount;
}
}
//tax calculation
foreach ($product->taxes as $product_tax) {
if($product_tax->tax_type == 'percent'){
$tax += ($price * $product_tax->tax) / 100;
}
elseif($product_tax->tax_type == 'amount'){
$tax += $product_tax->tax;
}
}
$data['price'] = $price;
$data['tax'] = $tax;
if($request->session()->has('pos.cart')){
$foundInCart = false;
$cart = collect();
foreach ($request->session()->get('pos.cart') as $key => $cartItem){
if($cartItem['id'] == $product->id && $cartItem['stock_id'] == $stock->id){
$foundInCart = true;
if($product->digital == 0){
$loop_product = Product::find($cartItem['id']);
$product_stock = $loop_product->stocks->where('variant', $cartItem['variant'])->first();
if($product->digital == 1 || $product_stock->qty >= ($cartItem['quantity'] + 1)){
$cartItem['quantity'] += 1;
}else{
return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('backend.pos.cart')->render());
}
}
else{
return array('success' => 0, 'message' => translate("This product is alreday in the cart"), 'view' => view('backend.pos.cart')->render());
}
}
$cart->push($cartItem);
}
if (!$foundInCart) {
$cart->push($data);
}
$request->session()->put('pos.cart', $cart);
}
else{
$cart = collect([$data]);
$request->session()->put('pos.cart', $cart);
}
$request->session()->put('pos.cart', $cart);
return array('success' => 1, 'message' => '', 'view' => view('backend.pos.cart')->render());
}
//updated the quantity for a cart item
public function updateQuantity(Request $request)
{
$cart = $request->session()->get('pos.cart', collect([]));
$cart = $cart->map(function ($object, $key) use ($request) {
if($key == $request->key){
$product = Product::find($object['id']);
$product_stock = $product->stocks->where('id', $object['stock_id'])->first();
if($product_stock->qty >= $request->quantity){
$object['quantity'] = $request->quantity;
}else{
return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('backend.pos.cart')->render());
}
}
return $object;
});
$request->session()->put('pos.cart', $cart);
return array('success' => 1, 'message' => '', 'view' => view('backend.pos.cart')->render());
}
//removes from Cart
public function removeFromCart(Request $request)
{
if(Session::has('pos.cart')){
$cart = Session::get('pos.cart', collect([]));
$cart->forget($request->key);
Session::put('pos.cart', $cart);
$request->session()->put('pos.cart', $cart);
}
return view('backend.pos.cart');
}
//Shipping Address for seller
public function getShippingAddressForSeller(Request $request)
{
$user_id = $request->id;
return ($user_id == '') ?
view('seller.pos.guest_shipping_address') :
view('seller.pos.shipping_address', compact('user_id'));
}
public function set_shipping_address(Request $request)
{
$data = PosUtility::get_shipping_address($request);
$shipping_info = $data;
$request->session()->put('pos.shipping_info', $shipping_info);
}
//set Discount
public function setDiscount(Request $request){
if($request->discount >= 0){
Session::put('pos.discount', $request->discount);
}
return view('backend.pos.cart');
}
//set Shipping Cost
public function setShipping(Request $request){
if($request->shipping != null){
Session::put('pos.shipping', $request->shipping);
}
return view('backend.pos.cart');
}
//order summary
public function get_order_summary(Request $request){
return view('backend.pos.order_summary');
}
//order place
public function order_store(Request $request){
if(Session::get('pos.shipping_info') == null || Session::get('pos.shipping_info')['name'] == null || Session::get('pos.shipping_info')['phone'] == null || Session::get('pos.shipping_info')['address'] == null){
return array('success' => 0, 'message' => translate("Please Add Shipping Information."));
}
if(Session::has('pos.cart') && count(Session::get('pos.cart')) > 0){
$order = new Order;
if ($request->user_id == null) {
$order->guest_id = mt_rand(100000, 999999);
}
else {
$order->user_id = $request->user_id;
}
$order->shipping_address = json_encode(Session::get('pos.shipping_info'));
$order->payment_type = $request->payment_type;
$order->delivery_viewed = '0';
$order->payment_status_viewed = '0';
$order->code = date('Ymd-His').rand(10,99);
$order->date = strtotime('now');
$order->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
$order->payment_details = $request->payment_type;
$order->order_from = 'pos';
if($request->payment_type == 'offline_payment'){
if($request->offline_trx_id == null){
return array('success' => 0, 'message' => translate("Transaction ID can not be null."));
}
$data['name'] = $request->offline_payment_method;
$data['amount'] = $request->offline_payment_amount;
$data['trx_id'] = $request->offline_trx_id;
$data['photo'] = $request->offline_payment_proof;
$order->manual_payment_data = json_encode($data);
$order->manual_payment = 1;
}
if($order->save()){
$subtotal = 0;
$tax = 0;
foreach (Session::get('pos.cart') as $key => $cartItem){
$product_stock = ProductStock::find($cartItem['stock_id']);
$product = $product_stock->product;
$product_variation = $product_stock->variant;
$subtotal += $cartItem['price']*$cartItem['quantity'];
$tax += $cartItem['tax']*$cartItem['quantity'];
if($product->digital == 0){
if($cartItem['quantity'] > $product_stock->qty){
$order->delete();
return array('success' => 0, 'message' => $product->name.' ('.$product_variation.') '.translate(" just stock outs."));
}
else {
$product_stock->qty -= $cartItem['quantity'];
$product_stock->save();
}
}
$order_detail = new OrderDetail;
$order_detail->order_id =$order->id;
$order_detail->seller_id = $product->user_id;
$order_detail->product_id = $product->id;
$order_detail->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
$order_detail->variation = $product_variation;
$order_detail->price = $cartItem['price'] * $cartItem['quantity'];
$order_detail->tax = $cartItem['tax'] * $cartItem['quantity'];
$order_detail->quantity = $cartItem['quantity'];
$order_detail->shipping_type = null;
if (Session::get('pos.shipping', 0) >= 0){
$order_detail->shipping_cost = Session::get('pos.shipping', 0)/count(Session::get('pos.cart'));
}
else {
$order_detail->shipping_cost = 0;
}
$order_detail->save();
$product->num_of_sale++;
$product->save();
}
$order->grand_total = $subtotal + $tax + Session::get('pos.shipping', 0);
if(Session::has('pos.discount')){
$order->grand_total -= Session::get('pos.discount');
$order->coupon_discount = Session::get('pos.discount');
}
$order->seller_id = $product->user_id;
$order->save();
$array['view'] = 'emails.invoice';
$array['subject'] = 'Your order has been placed - '.$order->code;
$array['from'] = env('MAIL_USERNAME');
$array['order'] = $order;
$admin_products = array();
$seller_products = array();
foreach ($order->orderDetails as $key => $orderDetail){
if($orderDetail->product->added_by == 'admin'){
array_push($admin_products, $orderDetail->product->id);
}
else{
$product_ids = array();
if(array_key_exists($orderDetail->product->user_id, $seller_products)){
$product_ids = $seller_products[$orderDetail->product->user_id];
}
array_push($product_ids, $orderDetail->product->id);
$seller_products[$orderDetail->product->user_id] = $product_ids;
}
}
foreach($seller_products as $key => $seller_product){
try {
Mail::to(User::find($key)->email)->queue(new InvoiceEmailManager($array));
} catch (\Exception $e) {
}
}
//sends email to customer with the invoice pdf attached
if(env('MAIL_USERNAME') != null){
try {
Mail::to($request->session()->get('pos.shipping_info')['email'])->queue(new InvoiceEmailManager($array));
Mail::to(User::where('user_type', 'admin')->first()->email)->queue(new InvoiceEmailManager($array));
} catch (\Exception $e) {
}
}
if($request->user_id != NULL && $order->payment_status == 'paid') {
calculateCommissionAffilationClubPoint($order);
}
Session::forget('pos.shipping_info');
Session::forget('pos.shipping');
Session::forget('pos.discount');
Session::forget('pos.cart');
return array('success' => 1, 'message' => translate('Order Completed Successfully.'));
}
else {
return array('success' => 0, 'message' => translate('Please input customer information.'));
}
}
return array('success' => 0, 'message' => translate("Please select a product."));
}
public function configuration()
{
return view('seller.pos.pos_activation');
}
public function invoice($id)
{
$order = Order::findOrFail($id);
if(auth()->user()->id != $order->seller_id) {
return back();
}
$print_width = get_setting('print_width_seller_pos');
if ($print_width == null) {
flash(translate('Print Size does not set for thermal printer from POS configuration'))->warning();
return back();
}
$pdf_style_data = FontUtility::get_font_family();
$html = view('backend.pos.thermal_invoice', compact('order', 'pdf_style_data'));
$mpdf = new Mpdf(['mode' => 'utf-8', 'format' => [$print_width, 1000]]);
$mpdf->WriteHTML($html);
// $mpdf->WriteHTML('<h1>Hello world!</h1>');
$mpdf->page = 0;
$mpdf->state = 0;
unset($mpdf->pages[0]);
// The $p needs to be passed by reference
$p = 'P';
// dd($mpdf->y);
$mpdf->_setPageSize(array($print_width, $mpdf->y), $p);
$mpdf->addPage();
$mpdf->WriteHTML($html);
$mpdf->Output('order-' . $order->code . '.pdf', 'I');
}
}

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1 @@
COMMIT;

View File

@@ -0,0 +1,79 @@
<div class="aiz-pos-cart-list mb-4 mt-3 c-scrollbar-light">
@php
$subtotal = 0;
$tax = 0;
@endphp
@if (Session::has('pos.cart'))
<ul class="list-group list-group-flush">
@forelse (Session::get('pos.cart') as $key => $cartItem)
@php
$subtotal += $cartItem['price']*$cartItem['quantity'];
$tax += $cartItem['tax']*$cartItem['quantity'];
$stock = \App\Models\ProductStock::find($cartItem['stock_id']);
@endphp
<li class="list-group-item py-0 pl-2">
<div class="row gutters-5 align-items-center">
<div class="col-auto w-60px">
<div class="row no-gutters align-items-center flex-column aiz-plus-minus">
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="plus" data-field="qty-{{ $key }}">
<i class="las la-plus"></i>
</button>
<input type="text" name="qty-{{ $key }}" id="qty-{{ $key }}" class="col border-0 text-center flex-grow-1 fs-16 input-number" placeholder="1" value="{{ $cartItem['quantity'] }}" min="{{ $stock->product->min_qty }}" max="{{ $stock->qty }}" onchange="updateQuantity({{ $key }})">
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="minus" data-field="qty-{{ $key }}">
<i class="las la-minus"></i>
</button>
</div>
</div>
<div class="col">
<div class="text-truncate-2">{{ $stock->product->name }}</div>
<span class="span badge badge-inline fs-12 badge-soft-secondary">{{ $cartItem['variant'] }}</span>
</div>
<div class="col-auto">
<div class="fs-12 opacity-60">{{ single_price($cartItem['price']) }} x {{ $cartItem['quantity'] }}</div>
<div class="fs-15 fw-600">{{ single_price($cartItem['price']*$cartItem['quantity']) }}</div>
</div>
<div class="col-auto">
<button type="button" class="btn btn-circle btn-icon btn-sm btn-soft-danger ml-2 mr-0" onclick="removeFromCart({{ $key }})">
<i class="las la-trash-alt"></i>
</button>
</div>
</div>
</li>
@empty
<li class="list-group-item">
<div class="text-center">
<i class="las la-frown la-3x opacity-50"></i>
<p>{{ translate('No Product Added') }}</p>
</div>
</li>
@endforelse
</ul>
@else
<div class="text-center">
<i class="las la-frown la-3x opacity-50"></i>
<p>{{ translate('No Product Added') }}</p>
</div>
@endif
</div>
<div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Sub Total')}}</span>
<span>{{ single_price($subtotal) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Tax')}}</span>
<span>{{ single_price($tax) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Shipping')}}</span>
<span>{{ single_price(Session::get('pos.shipping', 0)) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Discount')}}</span>
<span>{{ single_price(Session::get('pos.discount', 0)) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 fs-18 border-top pt-2">
<span>{{translate('Total')}}</span>
<span>{{ single_price($subtotal+$tax+Session::get('pos.shipping', 0) - Session::get('pos.discount', 0)) }}</span>
</div>
</div>

View File

@@ -0,0 +1,77 @@
<div class="form-group">
<div class="row">
<label class="col-sm-2 control-label" for="name">{{translate('Name')}}</label>
<div class="col-sm-10">
<input type="text" placeholder="{{translate('Name')}}" id="name" name="name" class="form-control" required>
</div>
</div>
</div>
<div class="form-group">
<div class=" row">
<label class="col-sm-2 control-label" for="email">{{translate('Email')}}</label>
<div class="col-sm-10">
<input type="email" placeholder="{{translate('Email')}}" id="email" name="email" class="form-control" required>
</div>
</div>
</div>
<div class="form-group">
<div class=" row">
<label class="col-sm-2 control-label" for="address">{{translate('Address')}}</label>
<div class="col-sm-10">
<textarea placeholder="{{translate('Address')}}" id="address" name="address" class="form-control" required></textarea>
</div>
</div>
</div>
<div class="form-group">
<div class=" row">
<label class="col-sm-2 control-label">{{translate('Country')}}</label>
<div class="col-sm-10">
<select class="form-control aiz-selectpicker" data-live-search="true" data-placeholder="{{ translate('Select your country') }}" name="country_id" required>
<option value="">{{ translate('Select your country') }}</option>
@foreach (\App\Models\Country::where('status', 1)->get() as $key => $country)
<option value="{{ $country->id }}">{{ $country->name }}</option>
@endforeach
</select>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-sm-2 control-label"">
<label>{{ translate('State')}}</label>
</div>
<div class="col-sm-10">
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="state_id" required>
</select>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-sm-2">
<label>{{ translate('City')}}</label>
</div>
<div class="col-sm-10">
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="city_id" required>
</select>
</div>
</div>
</div>
<div class="form-group">
<div class=" row">
<label class="col-sm-2 control-label" for="postal_code">{{translate('Postal code')}}</label>
<div class="col-sm-10">
<input type="number" min="0" placeholder="{{translate('Postal code')}}" id="postal_code" name="postal_code" class="form-control" required>
</div>
</div>
</div>
<div class="form-group">
<div class=" row">
<label class="col-sm-2 control-label" for="phone">{{translate('Phone')}}</label>
<div class="col-sm-10">
<input type="number" min="0" placeholder="{{translate('Phone')}}" id="phone" name="phone" class="form-control" required>
</div>
</div>
</div>

View File

@@ -0,0 +1,637 @@
@extends('backend.layouts.app')
@section('content')
<section class="">
<form class="" action="" method="POST" enctype="multipart/form-data">
@csrf
<div class="row gutters-5">
<div class="col-md">
<div class="row gutters-5 mb-3">
<div class="col-md-6 mb-2 mb-md-0">
<div class="form-group mb-0">
<input class="form-control form-control-lg" type="text" name="keyword" placeholder="{{ translate('Search by Product Name/Barcode') }}" onkeyup="filterProducts()">
</div>
</div>
<div class="col-md-3 col-6">
<select name="poscategory" class="form-control form-control-lg aiz-selectpicker" data-live-search="true" onchange="filterProducts()">
<option value="">{{ translate('All Categories') }}</option>
@foreach (\App\Models\Category::all() as $key => $category)
<option value="category-{{ $category->id }}">{{ $category->getTranslation('name') }}</option>
@endforeach
</select>
</div>
<div class="col-md-3 col-6">
<select name="brand" class="form-control form-control-lg aiz-selectpicker" data-live-search="true" onchange="filterProducts()">
<option value="">{{ translate('All Brands') }}</option>
@foreach (\App\Models\Brand::all() as $key => $brand)
<option value="{{ $brand->id }}">{{ $brand->getTranslation('name') }}</option>
@endforeach
</select>
</div>
</div>
<div class="aiz-pos-product-list c-scrollbar-light">
<div class="d-flex flex-wrap justify-content-center" id="product-list">
</div>
<div id="load-more" class="text-center">
<div class="fs-14 d-inline-block fw-600 btn btn-soft-primary c-pointer" onclick="loadMoreProduct()">{{ translate('Loading..') }}</div>
</div>
</div>
</div>
<div class="col-md-auto w-md-350px w-lg-400px w-xl-500px">
<div class="card mb-3">
<div class="card-body">
<div class="d-flex border-bottom pb-3">
<div class="flex-grow-1">
<select name="user_id" class="form-control aiz-selectpicker pos-customer" data-live-search="true" onchange="getShippingAddress()">
<option value="">{{translate('Walk In Customer')}}</option>
@foreach ($customers as $key => $customer)
<option value="{{ $customer->id }}" data-contact="{{ $customer->email }}">
{{ $customer->name }}
</option>
@endforeach
</select>
</div>
<button type="button" class="btn btn-icon btn-soft-dark ml-3 mr-0" data-target="#new-customer" data-toggle="modal">
<i class="las la-truck"></i>
</button>
</div>
<div class="" id="cart-details">
<div class="aiz-pos-cart-list mb-4 mt-3 c-scrollbar-light">
@php
$subtotal = 0;
$tax = 0;
@endphp
@if (Session::has('pos.cart'))
<ul class="list-group list-group-flush">
@forelse (Session::get('pos.cart') as $key => $cartItem)
@php
$subtotal += $cartItem['price']*$cartItem['quantity'];
$tax += $cartItem['tax']*$cartItem['quantity'];
$stock = \App\Models\ProductStock::find($cartItem['stock_id']);
@endphp
<li class="list-group-item py-0 pl-2">
<div class="row gutters-5 align-items-center">
<div class="col-auto w-60px">
<div class="row no-gutters align-items-center flex-column aiz-plus-minus">
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="plus" data-field="qty-{{ $key }}" @if($stock->product->digital == 1) disabled @endif>
<i class="las la-plus"></i>
</button>
<input type="text" name="qty-{{ $key }}" id="qty-{{ $key }}" class="col border-0 text-center flex-grow-1 fs-16 input-number" placeholder="1" value="{{ $cartItem['quantity'] }}" min="{{ $stock->product->min_qty }}" max="{{ $stock->qty }}" onchange="updateQuantity({{ $key }})">
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="minus" data-field="qty-{{ $key }}" @if($stock->product->digital == 1) disabled @endif>
<i class="las la-minus"></i>
</button>
</div>
</div>
<div class="col">
<div class="text-truncate-2">{{ $stock->product->name }}</div>
<span class="span badge badge-inline fs-12 badge-soft-secondary">{{ $cartItem['variant'] }}</span>
</div>
<div class="col-auto">
<div class="fs-12 opacity-60">{{ single_price($cartItem['price']) }} x {{ $cartItem['quantity'] }}</div>
<div class="fs-15 fw-600">{{ single_price($cartItem['price']*$cartItem['quantity']) }}</div>
</div>
<div class="col-auto">
<button type="button" class="btn btn-circle btn-icon btn-sm btn-soft-danger ml-2 mr-0" onclick="removeFromCart({{ $key }})">
<i class="las la-trash-alt"></i>
</button>
</div>
</div>
</li>
@empty
<li class="list-group-item">
<div class="text-center">
<i class="las la-frown la-3x opacity-50"></i>
<p>{{ translate('No Product Added') }}</p>
</div>
</li>
@endforelse
</ul>
@else
<div class="text-center">
<i class="las la-frown la-3x opacity-50"></i>
<p>{{ translate('No Product Added') }}</p>
</div>
@endif
</div>
<div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Sub Total')}}</span>
<span>{{ single_price($subtotal) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Tax')}}</span>
<span>{{ single_price($tax) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Shipping')}}</span>
<span>{{ single_price(Session::get('pos.shipping', 0)) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Discount')}}</span>
<span>{{ single_price(Session::get('pos.discount', 0)) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 fs-18 border-top pt-2">
<span>{{translate('Total')}}</span>
<span>{{ single_price($subtotal+$tax+Session::get('pos.shipping', 0) - Session::get('pos.discount', 0)) }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="pos-footer mar-btm">
<div class="d-flex flex-column flex-md-row justify-content-between">
<div class="d-flex">
<div class="dropdown mr-3 ml-0 dropup">
<button class="btn btn-outline-dark btn-styled dropdown-toggle" type="button" data-toggle="dropdown">
{{translate('Shipping')}}
</button>
<div class="dropdown-menu p-3 dropdown-menu-lg">
<div class="input-group">
<input type="number" min="0" placeholder="Amount" name="shipping" class="form-control" value="{{ Session::get('pos.shipping', 0) }}" required onchange="setShipping()">
<div class="input-group-append">
<span class="input-group-text">{{ translate('Flat') }}</span>
</div>
</div>
</div>
</div>
<div class="dropdown dropup">
<button class="btn btn-outline-dark btn-styled dropdown-toggle" type="button" data-toggle="dropdown">
{{translate('Discount')}}
</button>
<div class="dropdown-menu p-3 dropdown-menu-lg">
<div class="input-group">
<input type="number" min="0" placeholder="Amount" name="discount" class="form-control" value="{{ Session::get('pos.discount', 0) }}" required onchange="setDiscount()">
<div class="input-group-append">
<span class="input-group-text">{{ translate('Flat') }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="my-2 my-md-0">
<button type="button" class="btn btn-primary btn-block" onclick="orderConfirmation()">{{ translate('Place Order') }}</button>
</div>
</div>
</div>
</div>
</div>
</form>
</section>
@endsection
@section('modal')
<!-- Address Modal -->
<div id="new-customer" class="modal fade" role="dialog">
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom" role="document">
<div class="modal-content">
<div class="modal-header bord-btm">
<h4 class="modal-title h6">{{translate('Shipping Address')}}</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<form id="shipping_form">
<div class="modal-body" id="shipping_address">
</div>
</form>
<div class="modal-footer">
<button type="button" class="btn btn-styled btn-base-3" data-dismiss="modal" id="close-button">{{translate('Close')}}</button>
<button type="button" class="btn btn-primary btn-styled btn-base-1" id="confirm-address" data-dismiss="modal">{{translate('Confirm')}}</button>
</div>
</div>
</div>
</div>
<!-- new address modal -->
<div id="new-address-modal" class="modal fade" role="dialog">
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom" role="document">
<div class="modal-content">
<div class="modal-header bord-btm">
<h4 class="modal-title h6">{{translate('Shipping Address')}}</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<form class="form-horizontal" action="{{ route('addresses.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="modal-body">
<input type="hidden" name="customer_id" id="set_customer_id" value="">
<div class="form-group">
<div class=" row">
<label class="col-sm-2 control-label" for="address">{{translate('Address')}}</label>
<div class="col-sm-10">
<textarea placeholder="{{translate('Address')}}" id="address" name="address" class="form-control" required></textarea>
</div>
</div>
</div>
<div class="form-group">
<div class=" row">
<label class="col-sm-2 control-label">{{translate('Country')}}</label>
<div class="col-sm-10">
<select class="form-control aiz-selectpicker" data-live-search="true" data-placeholder="{{ translate('Select your country') }}" name="country_id" required>
<option value="">{{ translate('Select your country') }}</option>
@foreach (\App\Models\Country::where('status', 1)->get() as $key => $country)
<option value="{{ $country->id }}">{{ $country->name }}</option>
@endforeach
</select>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-sm-2 control-label"">
<label>{{ translate('State')}}</label>
</div>
<div class="col-sm-10">
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="state_id" required>
</select>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-sm-2">
<label>{{ translate('City')}}</label>
</div>
<div class="col-sm-10">
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="city_id" required>
</select>
</div>
</div>
</div>
<div class="form-group">
<div class=" row">
<label class="col-sm-2 control-label" for="postal_code">{{translate('Postal code')}}</label>
<div class="col-sm-10">
<input type="number" min="0" placeholder="{{translate('Postal code')}}" id="postal_code" name="postal_code" class="form-control" required>
</div>
</div>
</div>
<div class="form-group">
<div class=" row">
<label class="col-sm-2 control-label" for="phone">{{translate('Phone')}}</label>
<div class="col-sm-10">
<input type="number" min="0" placeholder="{{translate('Phone')}}" id="phone" name="phone" class="form-control" required>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-styled btn-base-3" data-dismiss="modal">{{translate('Close')}}</button>
<button type="submit" class="btn btn-primary btn-styled btn-base-1">{{translate('Save')}}</button>
</div>
</form>
</div>
</div>
</div>
<div id="order-confirm" class="modal fade">
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom modal-xl">
<div class="modal-content" id="variants">
<div class="modal-header bord-btm">
<h4 class="modal-title h6">{{translate('Order Summary')}}</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body" id="order-confirmation">
<div class="p-4 text-center">
<i class="las la-spinner la-spin la-3x"></i>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary btn-base-3" data-dismiss="modal">{{translate('Close')}}</button>
<button type="button" onclick="oflinePayment()" class="btn btn-base-1 btn-warning">{{translate('Offline Payment')}}</button>
<button type="button" onclick="submitOrder('cash_on_delivery')" class="btn btn-base-1 btn-info">{{translate('Confirm with COD')}}</button>
<button type="button" onclick="submitOrder('cash')" class="btn btn-base-1 btn-success">{{translate('Confirm with Cash')}}</button>
</div>
</div>
</div>
</div>
{{-- Offline Payment Modal --}}
<div id="offlin_payment" class="modal fade" role="dialog">
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom" role="document">
<div class="modal-content">
<div class="modal-header bord-btm">
<h4 class="modal-title h6">{{translate('Offline Payment Info')}}</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div class="form-group">
<div class=" row">
<label class="col-sm-3 control-label" for="offline_payment_method">{{translate('Payment Method')}}</label>
<div class="col-sm-9">
<input placeholder="{{translate('Name')}}" id="offline_payment_method" name="offline_payment_method" class="form-control" required>
</div>
</div>
</div>
<div class="form-group">
<div class=" row">
<label class="col-sm-3 control-label" for="offline_payment_amount">{{translate('Amount')}}</label>
<div class="col-sm-9">
<input placeholder="{{translate('Amount')}}" id="offline_payment_amount" name="offline_payment_amount" class="form-control" required>
</div>
</div>
</div>
<div class="row">
<label class="col-sm-3 control-label" for="trx_id">{{translate('Transaction ID')}}</label>
<div class="col-md-9">
<input type="text" class="form-control mb-3" id="trx_id" name="trx_id" placeholder="{{ translate('Transaction ID') }}" required>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 col-form-label">{{ translate('Payment Proof') }}</label>
<div class="col-md-9">
<div class="input-group" data-toggle="aizuploader" data-type="image">
<div class="input-group-prepend">
<div class="input-group-text bg-soft-secondary font-weight-medium">{{ translate('Browse')}}</div>
</div>
<div class="form-control file-amount">{{ translate('Choose image') }}</div>
<input type="hidden" name="payment_proof" class="selected-files">
</div>
<div class="file-preview box sm">
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary btn-base-3" data-dismiss="modal">{{translate('Close')}}</button>
<button type="button" onclick="submitOrder('offline_payment')" class="btn btn-styled btn-base-1 btn-success">{{translate('Confirm')}}</button>
</div>
</div>
</div>
</div>
@endsection
@section('script')
<script type="text/javascript">
var products = null;
$(document).ready(function(){
$('body').addClass('side-menu-closed');
$('#product-list').on('click','.add-plus:not(.c-not-allowed)',function(){
var stock_id = $(this).data('stock-id');
$.post('{{ route('pos.addToCart') }}',{_token:AIZ.data.csrf, stock_id:stock_id}, function(data){
if(data.success == 1){
updateCart(data.view);
}else{
AIZ.plugins.notify('danger', data.message);
}
});
});
filterProducts();
getShippingAddress();
});
$("#confirm-address").click(function (){
var data = new FormData($('#shipping_form')[0]);
$.ajax({
headers: {
'X-CSRF-TOKEN': AIZ.data.csrf
},
method: "POST",
url: "{{route('pos.set-shipping-address')}}",
data: data,
cache: false,
contentType: false,
processData: false,
success: function (data, textStatus, jqXHR) {
}
})
});
function updateCart(data){
$('#cart-details').html(data);
AIZ.extra.plusMinus();
}
function filterProducts(){
var keyword = $('input[name=keyword]').val();
var category = $('select[name=poscategory]').val();
var brand = $('select[name=brand]').val();
$.get('{{ route('pos.search_product') }}',{keyword:keyword, category:category, brand:brand}, function(data){
products = data;
$('#product-list').html(null);
setProductList(data);
});
}
function loadMoreProduct(){
if(products != null && products.links.next != null){
$('#load-more').find('.btn').html('{{ translate('Loading..') }}');
$.get(products.links.next,{}, function(data){
products = data;
setProductList(data);
});
}
}
function setProductList(data){
for (var i = 0; i < data.data.length; i++) {
$('#product-list').append(
`<div class="w-140px w-xl-180px w-xxl-210px mx-2">
<div class="card bg-white c-pointer product-card hov-container">
<div class="position-relative">
${data.data[i].digital == 0
?
`<span class="absolute-top-left mt-1 ml-1 mr-0">
${data.data[i].qty > 0
? `<span class="badge badge-inline badge-success fs-13">{{ translate('In stock') }}`
: `<span class="badge badge-inline badge-danger fs-13">{{ translate('Out of stock') }}` }
: ${data.data[i].qty}</span>
</span>`
: ''
}
${data.data[i].variant != null
? `<span class="badge badge-inline badge-warning absolute-bottom-left mb-1 ml-1 mr-0 fs-13 text-truncate">${data.data[i].variant}</span>`
: '' }
<img src="${data.data[i].thumbnail_image }" class="card-img-top img-fit h-120px h-xl-180px h-xxl-210px mw-100 mx-auto" >
</div>
<div class="card-body p-2 p-xl-3">
<div class="text-truncate fw-600 fs-14 mb-2">${data.data[i].name}</div>
<div class="">
${data.data[i].price != data.data[i].base_price
? `<del class="mr-2 ml-0">${data.data[i].base_price}</del><span>${data.data[i].price}</span>`
: `<span>${data.data[i].base_price}</span>`
}
</div>
</div>
<div class="add-plus absolute-full rounded overflow-hidden hov-box ${(data.data[i].digital == 0 && data.data[i].qty <= 0) ? 'c-not-allowed' : '' }" data-stock-id="${data.data[i].stock_id}">
<div class="absolute-full bg-dark opacity-50">
</div>
<i class="las la-plus absolute-center la-6x text-white"></i>
</div>
</div>
</div>`
);
}
if (data.links.next != null) {
$('#load-more').find('.btn').html('{{ translate('Load More.') }}');
}
else {
$('#load-more').find('.btn').html('{{ translate('Nothing more found.') }}');
}
}
function removeFromCart(key){
$.post('{{ route('pos.removeFromCart') }}', {_token:AIZ.data.csrf, key:key}, function(data){
updateCart(data);
});
}
function addToCart(product_id, variant, quantity){
$.post('{{ route('pos.addToCart') }}',{_token:AIZ.data.csrf, product_id:product_id, variant:variant, quantity, quantity}, function(data){
$('#cart-details').html(data);
$('#product-variation').modal('hide');
});
}
function updateQuantity(key){
$.post('{{ route('pos.updateQuantity') }}',{_token:AIZ.data.csrf, key:key, quantity: $('#qty-'+key).val()}, function(data){
if(data.success == 1){
updateCart(data.view);
}else{
AIZ.plugins.notify('danger', data.message);
}
});
}
function setDiscount(){
var discount = $('input[name=discount]').val();
$.post('{{ route('pos.setDiscount') }}',{_token:AIZ.data.csrf, discount:discount}, function(data){
updateCart(data);
});
}
function setShipping(){
var shipping = $('input[name=shipping]').val();
$.post('{{ route('pos.setShipping') }}',{_token:AIZ.data.csrf, shipping:shipping}, function(data){
updateCart(data);
});
}
function getShippingAddress(){
$.post('{{ route('pos.getShippingAddress') }}',{_token:AIZ.data.csrf, id:$('select[name=user_id]').val()}, function(data){
$('#shipping_address').html(data);
});
}
function add_new_address(){
var customer_id = $('#customer_id').val();
$('#set_customer_id').val(customer_id);
$('#new-address-modal').modal('show');
$("#close-button").click();
}
function orderConfirmation(){
$('#order-confirmation').html(`<div class="p-4 text-center"><i class="las la-spinner la-spin la-3x"></i></div>`);
$('#order-confirm').modal('show');
$.post('{{ route('pos.getOrderSummary') }}',{_token:AIZ.data.csrf}, function(data){
$('#order-confirmation').html(data);
});
}
function oflinePayment(){
$('#offlin_payment').modal('show');
}
function submitOrder(payment_type){
var user_id = $('select[name=user_id]').val();
var shipping = $('input[name=shipping]:checked').val();
var discount = $('input[name=discount]').val();
var shipping_address = $('input[name=address_id]:checked').val();
var offline_payment_method = $('input[name=offline_payment_method]').val();
var offline_payment_amount = $('input[name=offline_payment_amount]').val();
var offline_trx_id = $('input[name=trx_id]').val();
var offline_payment_proof = $('input[name=payment_proof]').val();
$.post('{{ route('pos.order_place') }}',{
_token : AIZ.data.csrf,
user_id : user_id,
shipping_address : shipping_address,
payment_type : payment_type,
shipping : shipping,
discount : discount,
offline_payment_method : offline_payment_method,
offline_payment_amount : offline_payment_amount,
offline_trx_id : offline_trx_id,
offline_payment_proof : offline_payment_proof
}, function(data){
if(data.success == 1){
AIZ.plugins.notify('success', data.message );
location.reload();
}
else{
AIZ.plugins.notify('danger', data.message );
}
});
}
//address
$(document).on('change', '[name=country_id]', function() {
var country_id = $(this).val();
get_states(country_id);
});
$(document).on('change', '[name=state_id]', function() {
var state_id = $(this).val();
get_city(state_id);
});
function get_states(country_id) {
$('[name="state"]').html("");
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "{{route('get-state')}}",
type: 'POST',
data: {
country_id : country_id
},
success: function (response) {
var obj = JSON.parse(response);
if(obj != '') {
$('[name="state_id"]').html(obj);
AIZ.plugins.bootstrapSelect('refresh');
}
}
});
}
function get_city(state_id) {
$('[name="city"]').html("");
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "{{route('get-city')}}",
type: 'POST',
data: {
state_id: state_id
},
success: function (response) {
var obj = JSON.parse(response);
if(obj != '') {
$('[name="city_id"]').html(obj);
AIZ.plugins.bootstrapSelect('refresh');
}
}
});
}
</script>
@endsection

View File

@@ -0,0 +1,116 @@
<div class="row">
<div class="col-xl-6">
@php
$subtotal = 0;
$tax = 0;
@endphp
@if (Session::has('pos.cart'))
<ul class="list-group list-group-flush">
@forelse (Session::get('pos.cart') as $key => $cartItem)
@php
$subtotal += $cartItem['price']*$cartItem['quantity'];
$tax += $cartItem['tax']*$cartItem['quantity'];
$stock = \App\Models\ProductStock::find($cartItem['stock_id']);
@endphp
<li class="list-group-item px-0">
<div class="row gutters-10 align-items-center">
<div class="col">
<div class="d-flex">
@if($stock->image == null)
<img src="{{ uploaded_asset($stock->product->thumbnail_img) }}" class="img-fit size-60px">
@else
<img src="{{ uploaded_asset($stock->image) }}" class="img-fit size-60px">
@endif
<span class="flex-grow-1 ml-3 mr-0">
<div class="text-truncate-2">{{ $stock->product->name }}</div>
<span class="span badge badge-inline fs-12 badge-soft-secondary">{{ $cartItem['variant'] }}</span>
</span>
</div>
</div>
<div class="col-xl-3">
<div class="fs-14 fw-600 text-right">{{ single_price($cartItem['price']) }}</div>
<div class="fs-14 text-right">{{ translate('QTY') }}: {{ $cartItem['quantity'] }}</div>
</div>
</div>
</li>
@empty
<li class="list-group-item">
<div class="text-center">
<i class="las la-frown la-3x opacity-50"></i>
<p>{{ translate('No Product Added') }}</p>
</div>
</li>
@endforelse
</ul>
@else
<div class="text-center">
<i class="las la-frown la-3x opacity-50"></i>
<p>{{ translate('No Product Added') }}</p>
</div>
@endif
</div>
<div class="col-xl-6">
<div class="pl-xl-4">
<div class="card mb-4">
<div class="card-header"><span class="fs-16">{{ translate('Customer Info') }}</span></div>
<div class="card-body">
@if(Session::has('pos.shipping_info') && Session::get('pos.shipping_info')['name'] != null)
<div class="d-flex justify-content-between mb-2">
<span class="">{{translate('Name')}}:</span>
<span class="fw-600">{{ Session::get('pos.shipping_info')['name'] }}</span>
</div>
<div class="d-flex justify-content-between mb-2">
<span class="">{{translate('Email')}}:</span>
<span class="fw-600">{{ Session::get('pos.shipping_info')['email'] }}</span>
</div>
<div class="d-flex justify-content-between mb-2">
<span class="">{{translate('Phone')}}:</span>
<span class="fw-600">{{ Session::get('pos.shipping_info')['phone'] }}</span>
</div>
<div class="d-flex justify-content-between mb-2">
<span class="">{{translate('Address')}}:</span>
<span class="fw-600">{{ Session::get('pos.shipping_info')['address'] }}</span>
</div>
<div class="d-flex justify-content-between mb-2">
<span class="">{{translate('Country')}}:</span>
<span class="fw-600">{{ Session::get('pos.shipping_info')['country'] }}</span>
</div>
<div class="d-flex justify-content-between mb-2">
<span class="">{{translate('City')}}:</span>
<span class="fw-600">{{ Session::get('pos.shipping_info')['city'] }}</span>
</div>
<div class="d-flex justify-content-between mb-2">
<span class="">{{translate('Postal Code')}}:</span>
<span class="fw-600">{{ Session::get('pos.shipping_info')['postal_code'] }}</span>
</div>
@else
<div class="text-center p-4">
{{ translate('No customer information selected.') }}
</div>
@endif
</div>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Total')}}</span>
<span>{{ single_price($subtotal) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Tax')}}</span>
<span>{{ single_price($tax) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Shipping')}}</span>
<span>{{ single_price(Session::get('pos.shipping', 0)) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
<span>{{translate('Discount')}}</span>
<span>{{ single_price(Session::get('pos.discount', 0)) }}</span>
</div>
<div class="d-flex justify-content-between fw-600 fs-18 border-top pt-2">
<span>{{translate('Total')}}</span>
<span>{{ single_price($subtotal+$tax+Session::get('pos.shipping', 0) - Session::get('pos.discount', 0)) }}</span>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,68 @@
@extends('backend.layouts.app')
@section('content')
<h4 class="text-center text-muted">{{translate('POS Activation for Seller')}}</h4>
<div class="row">
<div class="col-lg-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{translate('POS Activation for Seller')}}</h5>
</div>
<div class="card-body text-center">
<label class="aiz-switch aiz-switch-success mb-0">
<input type="checkbox" onchange="updateSettings(this, 'pos_activation_for_seller')" @if(get_setting('pos_activation_for_seller') == 1) checked @endif>
<span class="slider round"></span>
</label>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0 h6">{{ translate('Thermal Printer Size') }}</h5>
</div>
<div class="card-body text-center">
<form class="form-horizontal" action="{{ route('business_settings.update') }}" method="POST">
@csrf
<div class="form-group row">
<input type="hidden" name="types[]" value="print_width">
<div class="input-group mb-3">
<input type="text" class="form-control" name="print_width" placeholder="{{ translate('Print width in mm') }}"
value="{{ get_setting('print_width') }}">
<div class="input-group-append">
<span class="input-group-text" id="basic-addon2">{{ translate('mm') }}</span>
</div>
</div>
</div>
<div class="form-group mb-0 text-right">
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection
@section('script')
<script type="text/javascript">
function updateSettings(el, type){
if($(el).is(':checked')){
var value = 1;
}
else{
var value = 0;
}
$.post('{{ route('business_settings.update.activation') }}', {_token:'{{ csrf_token() }}', type:type, value:value}, function(data){
if(data == '1'){
AIZ.plugins.notify('success', '{{ translate('Settings updated successfully') }}');
}
else{
AIZ.plugins.notify('danger', '{{ translate('Something went wrong') }}');
}
});
}
</script>
@endsection

View File

@@ -0,0 +1,43 @@
<div class="">
@foreach (\App\Models\Address::where('user_id',$user_id)->get() as $key => $address)
<label class="aiz-megabox d-block bg-white" style="display:block">
<input type="radio" name="address_id" value="{{ $address->id }}" @if ($address->set_default) checked @endif required>
<span class="d-flex p-3 pad-all aiz-megabox-elem">
<span class="aiz-rounded-check flex-shrink-0 mt-1"></span>
<span class="flex-grow-1 pl-3 pad-lft">
<div>
<span class="alpha-6">{{ translate('Address') }}:</span>
<span class="strong-600 ml-2">{{ $address->address }}</span>
</div>
<div>
<span class="alpha-6">{{ translate('Postal Code') }}:</span>
<span class="strong-600 ml-2">{{ $address->postal_code }}</span>
</div>
<div>
<span class="alpha-6">{{ translate('City') }}:</span>
<span class="strong-600 ml-2">{{ $address->city->name }}</span>
</div>
<div>
<span class="alpha-6">{{ translate('State') }}:</span>
<span class="strong-600 ml-2">{{ $address->state->name }}</span>
</div>
<div>
<span class="alpha-6">{{ translate('Country') }}:</span>
<span class="strong-600 ml-2">{{ $address->country->name }}</span>
</div>
<div>
<span class="alpha-6">{{ translate('Phone') }}:</span>
<span class="strong-600 ml-2">{{ $address->phone }}</span>
</div>
</span>
</span>
</label>
@endforeach
<input type="hidden" id="customer_id" value="{{$user_id}}" >
<div class="" onclick="add_new_address()">
<div class="border p-3 rounded mb-3 bord-all pad-all c-pointer text-center bg-white">
<i class="fa fa-plus fa-2x"></i>
<div class="alpha-7">{{ translate('Add New Address') }}</div>
</div>
</div>
</div>

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