mirror of
https://git.meshkee.com/cssd/cssd-back.git
synced 2026-10-12 00:11:06 +03:30
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
faabc08aa9 | ||
|
|
b0c619d3c0 | ||
|
|
d7db25937f | ||
|
|
7fd27c4693 | ||
|
|
7a6c81600f | ||
|
|
eeb90fe49e | ||
|
|
6f12cd4e69 | ||
|
|
b8b6e46cf2 | ||
|
|
122c7cdbda | ||
|
|
0977346b6e | ||
|
|
8f0b87c333 | ||
|
|
a467b06ea7 | ||
|
|
316c5507ba | ||
|
|
fa7df1e500 | ||
|
|
9040310170 | ||
|
|
156c3fbeb6 | ||
|
|
a7a46a1fd3 | ||
|
|
4a3b8fe5c0 | ||
|
|
2e59726bce | ||
|
|
4c48b13646 | ||
|
|
7ce5e0262b | ||
|
|
b7694a92a4 | ||
|
|
0bd017360c | ||
|
|
bcba3b7a8d | ||
|
|
dd85f7f5e2 | ||
|
|
263ef246fd | ||
|
|
38ca9b3b84 | ||
|
|
bea98bdd02 | ||
|
|
7a7ad062c6 | ||
|
|
27cd2292fe | ||
|
|
fee688c183 | ||
|
|
4eb2fa5107 | ||
|
|
edb9e9fc8a | ||
|
|
8b30242419 | ||
|
|
97f63d1435 | ||
|
|
44be70f3ff | ||
|
|
baeaed7c70 | ||
|
|
b573d1bbed | ||
|
|
6d108e43c9 | ||
|
|
2b8ad33cb2 | ||
|
|
354992fe48 | ||
|
|
b3f733cdd0 | ||
|
|
c03c1196ec | ||
|
|
be86f52ae7 | ||
|
|
200888482f | ||
|
|
838ad7ca12 | ||
|
|
3ec315bc09 | ||
|
|
d84a9a18c0 | ||
|
|
6b18d07b73 | ||
|
|
66812c5ed4 | ||
|
|
ea46db84a0 | ||
|
|
fd70c015f3 |
@@ -0,0 +1,86 @@
|
|||||||
|
name: CSSD-backend-publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*' # run on any tag push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Run Publish Job
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
actions: read
|
||||||
|
packages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: https://git.meshkee.com/actions/checkout@main
|
||||||
|
|
||||||
|
- name: Setup Docker buildx
|
||||||
|
uses: https://git.meshkee.com/actions/setup-buildx-action@master
|
||||||
|
|
||||||
|
- name: Log into registry git.meshkee.com
|
||||||
|
uses: https://git.meshkee.com/actions/login-action@master
|
||||||
|
with:
|
||||||
|
registry: git.meshkee.com
|
||||||
|
username: ${{ vars.DOCKER_USERNAME }}
|
||||||
|
password: ${{ vars.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
id: build-and-push
|
||||||
|
uses: https://git.meshkee.com/actions/build-push-action@master
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
git.meshkee.com/${{ gitea.repository }}:${{ gitea.ref_name }}
|
||||||
|
git.meshkee.com/${{ gitea.repository }}:latest
|
||||||
|
cache-from: type=registry,ref=git.meshkee.com/${{ gitea.repository }}:buildcache
|
||||||
|
cache-to: type=registry,ref=git.meshkee.com/${{ gitea.repository }}:buildcache,mode=max
|
||||||
|
# cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
# cache-to: type=local,dest=/tmp/.buildx-cache
|
||||||
|
secrets: |
|
||||||
|
gitea_token=${{ secrets.TOKEN }}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# deploy:
|
||||||
|
# name: Deploy Job
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
# permissions:
|
||||||
|
# contents: read
|
||||||
|
# security-events: write
|
||||||
|
# actions: read
|
||||||
|
# id-token: write
|
||||||
|
|
||||||
|
# steps:
|
||||||
|
# - name: Deploy to server
|
||||||
|
# uses: appleboy/ssh-action@v1.0.0
|
||||||
|
# with:
|
||||||
|
# host: ${{ secrets.SSH_HOST }}
|
||||||
|
# username: ${{ secrets.SSH_USER }}
|
||||||
|
# key: ${{ secrets.SSH_KEY }}
|
||||||
|
# port: 22
|
||||||
|
# script: |
|
||||||
|
# cd /apps/balout-backend
|
||||||
|
# docker pull git.meshkee.com/${{ gitea.repository }}:${{ gitea.ref_name }}
|
||||||
|
# IMAGE=git.meshkee.com/${{ gitea.repository }}:${{ gitea.ref_name }} docker compose run --rm balout-backend php artisan migrate --pretend --force
|
||||||
|
# # docker run --rm git.meshkee.com/${{ gitea.repository }}:${{ gitea.ref_name }} php artisan migrate --pretend --force
|
||||||
|
# if [ $? -eq 0 ]; then
|
||||||
|
# echo "Migration check passed. Deploying..."
|
||||||
|
# IMAGE=git.meshkee.com/${{ gitea.repository }}:${{ gitea.ref_name }} docker compose up -d
|
||||||
|
|
||||||
|
# # اجرای واقعی migration داخل کانتینر در حال اجرا
|
||||||
|
# docker exec balout-backend php artisan migrate --force
|
||||||
|
# else
|
||||||
|
# echo "Migration test failed, aborting deploy"
|
||||||
|
# exit 1
|
||||||
|
# fi
|
||||||
|
|
||||||
|
|
||||||
+9
-3
@@ -1,4 +1,4 @@
|
|||||||
FROM docker.meshkee.com/repository/docker-hosted/standard-laravel:8.2-fpm
|
FROM git.meshkee.com/packages/standard-laravel:8.2-fpm
|
||||||
|
|
||||||
WORKDIR /var/www/html
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
@@ -11,9 +11,15 @@ COPY database /var/www/html/database
|
|||||||
|
|
||||||
COPY composer.* /var/www/html/
|
COPY composer.* /var/www/html/
|
||||||
|
|
||||||
RUN composer config --global http-basic.repo.meshkee.com $REGISTRY_USER_NAME $REGISTRY_PASSWORD
|
# RUN composer config --global http-basic.repo.meshkee.com $REGISTRY_USER_NAME $REGISTRY_PASSWORD
|
||||||
|
|
||||||
RUN composer install --no-scripts
|
# RUN composer install --no-scripts
|
||||||
|
|
||||||
|
RUN --mount=type=secret,id=gitea_token \
|
||||||
|
pw=$(cat /run/secrets/gitea_token) && \
|
||||||
|
echo "{\"http-basic\":{\"git.meshkee.com\":{\"username\":\"zahra.mousavi\",\"password\":\"$pw\"}}}" > /tmp/composer_auth.json && \
|
||||||
|
export COMPOSER_AUTH="$(cat /tmp/composer_auth.json)" && \
|
||||||
|
composer install --optimize-autoloader --no-dev --no-scripts
|
||||||
|
|
||||||
COPY . /var/www/html
|
COPY . /var/www/html
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ COPY . .
|
|||||||
RUN composer install --no-interaction --prefer-dist --optimize-autoloader
|
RUN composer install --no-interaction --prefer-dist --optimize-autoloader
|
||||||
|
|
||||||
# Set permissions for the Laravel project
|
# Set permissions for the Laravel project
|
||||||
RUN chown -R www-data:www-data /var/www/html \
|
RUN chown -R 1000:1000 /var/www/html \
|
||||||
&& chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache
|
&& chmod -R 777 /var/www/html/storage /var/www/html/bootstrap/cache
|
||||||
|
|
||||||
# Expose port 9000 for PHP-FPM
|
# Expose port 9000 for PHP-FPM
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
FROM node:14-alpine AS builder
|
FROM docker.meshkee.com/repository/docker-hosted/node:14-alpine AS builder
|
||||||
|
|
||||||
WORKDIR /var/www/html
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exceptions;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class FieldNotExistsException extends Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
if (!function_exists('pluckValues')) {
|
if (!function_exists('pluckValues')) {
|
||||||
/**
|
/**
|
||||||
* Extracts the values of a given key from an array of associative arrays.
|
* Extracts the values of a given key from an array of associative arrays.
|
||||||
@@ -15,3 +17,12 @@ if (!function_exists('pluckValues')) {
|
|||||||
}, $array);
|
}, $array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!function_exists('getNamespaceMap')) {
|
||||||
|
|
||||||
|
function getNamespaceMap(Model $model): string
|
||||||
|
{
|
||||||
|
return $model->getMorphClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,13 +3,36 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Cycle;
|
use App\Models\Cycle;
|
||||||
|
use App\Models\FakeModel;
|
||||||
use App\Models\Item;
|
use App\Models\Item;
|
||||||
use App\Models\Package;
|
use App\Models\Package;
|
||||||
use App\Services\ExportCollection;
|
use App\Services\ExportCollection;
|
||||||
|
use App\Services\Responser;
|
||||||
use Maatwebsite\Excel\Facades\Excel;
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class ExportController extends Controller
|
class ExportController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private function sendToS3($export){
|
||||||
|
$fakeModel = FakeModel::firstOrCreate(['batch_id' => Str::random(6)]);
|
||||||
|
|
||||||
|
$tempFileName = 'excel_' . Str::random(10) . '.xlsx';
|
||||||
|
$tempDir = 'temp';
|
||||||
|
Storage::makeDirectory($tempDir);
|
||||||
|
$tempFilePath = $tempDir . '/' . $tempFileName;
|
||||||
|
|
||||||
|
Excel::store($export, $tempFilePath, 'local', \Maatwebsite\Excel\Excel::XLSX);
|
||||||
|
|
||||||
|
$media = $fakeModel->addMedia(storage_path('app/' . $tempFilePath))->toMediaCollection('temp_medias');
|
||||||
|
|
||||||
|
// اگه مشکلی پیش نمیاد بعد از این مرحله بالایی فیک مدل رو هم حذف کن که دیتابیس شلوغ نشه
|
||||||
|
|
||||||
|
Storage::delete($tempFilePath);
|
||||||
|
return $media;
|
||||||
|
}
|
||||||
|
|
||||||
public function items()
|
public function items()
|
||||||
{
|
{
|
||||||
$Items = Item::with( [ 'user' => function ( $query ) {
|
$Items = Item::with( [ 'user' => function ( $query ) {
|
||||||
@@ -67,8 +90,17 @@ class ExportController extends Controller
|
|||||||
'نام بیمارستان',
|
'نام بیمارستان',
|
||||||
'اخرین انتقال'
|
'اخرین انتقال'
|
||||||
] );
|
] );
|
||||||
|
|
||||||
$export = new ExportCollection( $Items );
|
$export = new ExportCollection( $Items );
|
||||||
return Excel::download( $export , 'items.xlsx' , null , [ \Maatwebsite\Excel\Excel::XLSX ] );
|
$media = $this->sendToS3($export);
|
||||||
|
|
||||||
|
return response()->json(
|
||||||
|
Responser::success(
|
||||||
|
'خروجی اکسل',
|
||||||
|
null,
|
||||||
|
['id' => $media->id, 'url' => $media->getUrl()]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function packages()
|
public function packages()
|
||||||
@@ -122,7 +154,14 @@ class ExportController extends Controller
|
|||||||
'اخرین انتقال'
|
'اخرین انتقال'
|
||||||
] );
|
] );
|
||||||
$export = new ExportCollection( $Packages );
|
$export = new ExportCollection( $Packages );
|
||||||
return Excel::download( $export , 'packages.xlsx' , null , [ \Maatwebsite\Excel\Excel::XLSX ] );
|
$media = $this->sendToS3($export);
|
||||||
|
return response()->json(
|
||||||
|
Responser::success(
|
||||||
|
'خروجی اکسل',
|
||||||
|
null,
|
||||||
|
['id' => $media->id, 'url' => $media->getUrl()]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function cycles()
|
public function cycles()
|
||||||
@@ -170,6 +209,16 @@ class ExportController extends Controller
|
|||||||
'نام بیمارستان',
|
'نام بیمارستان',
|
||||||
]);
|
]);
|
||||||
$export = new ExportCollection($cycles);
|
$export = new ExportCollection($cycles);
|
||||||
return Excel::download($export, 'cycles.xlsx', null, [\Maatwebsite\Excel\Excel::XLSX]);
|
|
||||||
|
$media = $this->sendToS3($export);
|
||||||
|
|
||||||
|
return response()->json(
|
||||||
|
Responser::success(
|
||||||
|
'خروجی اکسل',
|
||||||
|
null,
|
||||||
|
['id' => $media->id, 'url' => $media->getUrl()]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,20 @@ class ItemController extends Controller
|
|||||||
{
|
{
|
||||||
public function index( Request $request )
|
public function index( Request $request )
|
||||||
{
|
{
|
||||||
$Items = Item::when( $request->has( 'name' ) && $request->name != '' , function ( $query ) use ( $request ) {
|
$Items = Item::with( [
|
||||||
|
'user' ,
|
||||||
|
'package' ,
|
||||||
|
'user.medical_center' => function ( $query ) {
|
||||||
|
$query->select( 'id' , 'name' , 'address' , 'phone_number' );
|
||||||
|
} ,
|
||||||
|
] )->when( $request->has( 'name' ) && $request->name != '' , function ( $query ) use ( $request ) {
|
||||||
$query->where( 'name' , 'LIKE' , '%' . $request->name . '%' );
|
$query->where( 'name' , 'LIKE' , '%' . $request->name . '%' );
|
||||||
} )
|
} )
|
||||||
|
->when($request->filled('user_name'), function ($query) use ($request) {
|
||||||
|
$query->whereHas('user', function ($q) use ($request) {
|
||||||
|
$q->where('users.name', 'LIKE', '%' . $request->user_name . '%');
|
||||||
|
});
|
||||||
|
})
|
||||||
->when( $request->has( 'udi' ) && $request->udi != '' , function ( $query ) use ( $request ) {
|
->when( $request->has( 'udi' ) && $request->udi != '' , function ( $query ) use ( $request ) {
|
||||||
$query->where( 'udi' , 'LIKE' , '%' . $request->udi . '%' );
|
$query->where( 'udi' , 'LIKE' , '%' . $request->udi . '%' );
|
||||||
} )
|
} )
|
||||||
@@ -35,14 +46,7 @@ class ItemController extends Controller
|
|||||||
$query->whereHas( 'user' , function ( $query ) use ( $request ) {
|
$query->whereHas( 'user' , function ( $query ) use ( $request ) {
|
||||||
$query->where( 'medical_center_id' , $request->medical_center_id );
|
$query->where( 'medical_center_id' , $request->medical_center_id );
|
||||||
} );
|
} );
|
||||||
} )
|
} );
|
||||||
->with( [
|
|
||||||
'user' ,
|
|
||||||
'package' ,
|
|
||||||
'user.medical_center' => function ( $query ) {
|
|
||||||
$query->select( 'id' , 'name' , 'address' , 'phone_number' );
|
|
||||||
} ,
|
|
||||||
] );
|
|
||||||
|
|
||||||
$user = auth( 'api' )->user();
|
$user = auth( 'api' )->user();
|
||||||
if ( $user->hasRole( 'User' ) or $user->hasRole( 'Supervisor' ) ) {
|
if ( $user->hasRole( 'User' ) or $user->hasRole( 'Supervisor' ) ) {
|
||||||
@@ -92,12 +96,8 @@ class ItemController extends Controller
|
|||||||
] );
|
] );
|
||||||
|
|
||||||
$user = auth( 'api' )->user();
|
$user = auth( 'api' )->user();
|
||||||
if ( $user->hasRole( 'User' ) ) {
|
if ( $user->hasRole( 'User' ) or $user->hasRole('Supervisor') ) {
|
||||||
$Items = $Items->where( "user_id" , $user->id );
|
$Items = $Items->where( "user_id" , $user->id );
|
||||||
} elseif ( $user->hasRole( 'Supervisor' ) ) {
|
|
||||||
$Items = $Items->whereHas( 'user' , function ( $query ) use ( $user ) {
|
|
||||||
$query->where( 'medical_center_id' , $user->medical_center_id );
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$Items = $Items->orderByDesc( 'id' )->paginate( 10 );
|
$Items = $Items->orderByDesc( 'id' )->paginate( 10 );
|
||||||
@@ -148,6 +148,35 @@ class ItemController extends Controller
|
|||||||
return ItemResource::make( $Item );
|
return ItemResource::make( $Item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function showUdi( $udi )
|
||||||
|
{
|
||||||
|
$Item = Item::where('udi',$udi)->first();
|
||||||
|
$Item->load( [
|
||||||
|
'user' ,
|
||||||
|
'creator' ,
|
||||||
|
'package' ,
|
||||||
|
'user.medical_center' => function ( $query ) {
|
||||||
|
$query->select( 'id' , 'name' , 'address' , 'phone_number' );
|
||||||
|
} ,
|
||||||
|
"transfers" => function ( $query ) {
|
||||||
|
$query->with( [
|
||||||
|
'user' => function ( $query ) {
|
||||||
|
$query->select( 'id' , 'name' , 'cell_number' );
|
||||||
|
} ,
|
||||||
|
'user.medical_center' => function ( $query ) {
|
||||||
|
$query->select( 'id' , 'name' , 'address' , 'phone_number' );
|
||||||
|
},
|
||||||
|
'userTransfer' => function ($query) {
|
||||||
|
$query->select('id','name','cell_number');
|
||||||
|
}
|
||||||
|
] );
|
||||||
|
},
|
||||||
|
'media'
|
||||||
|
] );
|
||||||
|
|
||||||
|
return ItemResource::make( $Item );
|
||||||
|
}
|
||||||
|
|
||||||
public function store( StoreItemRequest $request )
|
public function store( StoreItemRequest $request )
|
||||||
{
|
{
|
||||||
$Item = Item::create( [
|
$Item = Item::create( [
|
||||||
@@ -167,7 +196,7 @@ class ItemController extends Controller
|
|||||||
|
|
||||||
public function edit( Item $Item )
|
public function edit( Item $Item )
|
||||||
{
|
{
|
||||||
return ItemResource::make( $Item );
|
return ItemResource::make( $Item->load(['media']) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update( StoreItemRequest $request , Item $Item )
|
public function update( StoreItemRequest $request , Item $Item )
|
||||||
|
|||||||
@@ -13,50 +13,45 @@ class MessageController extends Controller
|
|||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$User = auth('api')->user();
|
$User = auth('api')->user();
|
||||||
$role = null;
|
|
||||||
$medical_center_id = null;
|
$medical_center_id = null;
|
||||||
|
|
||||||
$User = auth('api')->user();
|
|
||||||
if ($User->hasRole('Supervisor') || $User->hasRole('User')) {
|
if ($User->hasRole('Supervisor') || $User->hasRole('User')) {
|
||||||
$medical_center_id = $User->medical_center_id;
|
$medical_center_id = $User->medical_center_id;
|
||||||
$role = 'Admin';
|
|
||||||
}
|
}
|
||||||
$remove = $User->id;
|
|
||||||
$Users = User::whereHas('messagesSent', function ($q) use ($User) {
|
$Users = User::where(function ($query) use ($User) {
|
||||||
|
$query->whereHas('messagesSent', function ($q) use ($User) {
|
||||||
$q->where('recipient_user_id', $User->id);
|
$q->where('recipient_user_id', $User->id);
|
||||||
})
|
})
|
||||||
->orWhereHas('messagesReceived', function ($q) use ($User) {
|
->orWhereHas('messagesReceived', function ($q) use ($User) {
|
||||||
$q->where('sender_user_id', $User->id);
|
$q->where('sender_user_id', $User->id);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
->when($medical_center_id, function ($query) use ($medical_center_id) {
|
->when($medical_center_id, function ($query) use ($medical_center_id) {
|
||||||
$query->where('medical_center_id', $medical_center_id);
|
$query->where('medical_center_id', $medical_center_id);
|
||||||
})
|
})
|
||||||
->when($role, function ($query) use ($role) {
|
|
||||||
$query->role($role);
|
|
||||||
})
|
|
||||||
->paginate(10);
|
->paginate(10);
|
||||||
|
|
||||||
foreach ($Users as $user) {
|
foreach ($Users as $user) {
|
||||||
$UnReadReceivedMessages = Message::where('sender_user_id', $user->id)->where('recipient_user_id', $User->id)->where('status', 'UnRead')->get()->count();
|
$user->unread_messages_count = Message::where('sender_user_id', $user->id)
|
||||||
$user->unread_messages_count = $UnReadReceivedMessages;
|
->where('recipient_user_id', $User->id)
|
||||||
|
->where('status', 'UnRead')
|
||||||
|
->count();
|
||||||
|
|
||||||
$MessagesCount = Message::where(function ($query) use ($user, $User) {
|
$user->messages_count = Message::where(function ($query) use ($user, $User) {
|
||||||
$query->where('sender_user_id', $user->id)->where('recipient_user_id', $User->id);
|
$query->where('sender_user_id', $user->id)
|
||||||
|
->where('recipient_user_id', $User->id);
|
||||||
})->orWhere(function ($query) use ($user, $User) {
|
})->orWhere(function ($query) use ($user, $User) {
|
||||||
$query->where('sender_user_id', $User->id)->where('recipient_user_id', $user->id);
|
$query->where('sender_user_id', $User->id)
|
||||||
})->get()->count();
|
->where('recipient_user_id', $user->id);
|
||||||
|
})->count();
|
||||||
$user->messages_count = $MessagesCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// $Users = $Users->filter(function ($value, $key) use($remove){
|
|
||||||
// return $value['id'] != $remove;
|
|
||||||
// });
|
|
||||||
|
|
||||||
return MessageResponse::data($Users);
|
return MessageResponse::data($Users);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class PackageController extends Controller
|
|||||||
})
|
})
|
||||||
->with([
|
->with([
|
||||||
'user',
|
'user',
|
||||||
|
'items',
|
||||||
'user.medical_center' => function ($query) {
|
'user.medical_center' => function ($query) {
|
||||||
$query->select('id', 'name', 'address', 'phone_number');
|
$query->select('id', 'name', 'address', 'phone_number');
|
||||||
},
|
},
|
||||||
@@ -61,12 +62,8 @@ class PackageController extends Controller
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$user = auth('api')->user();
|
$user = auth('api')->user();
|
||||||
if ($user->hasRole('User')) {
|
if ($user->hasRole('User') or $user->hasRole('Supervisor')) {
|
||||||
$Packages = $Packages->where("user_id", $user->id);
|
$Packages = $Packages->where("user_id", $user->id);
|
||||||
} elseif ($user->hasRole('Supervisor')) {
|
|
||||||
$Packages = $Packages->whereHas('user', function ($query) use ($user) {
|
|
||||||
$query->where('medical_center_id', $user->medical_center_id);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$Packages = $Packages->orderByDesc('id')->paginate(10);
|
$Packages = $Packages->orderByDesc('id')->paginate(10);
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ class TestResultController extends Controller
|
|||||||
->when($request->has('testType_id') && $request->testType_id, function ($query) use ($request) {
|
->when($request->has('testType_id') && $request->testType_id, function ($query) use ($request) {
|
||||||
$query->where('test_type_id', $request->testType_id);
|
$query->where('test_type_id', $request->testType_id);
|
||||||
})
|
})
|
||||||
|
->when($request->has('test_type_name') && $request->test_type_name, function ($q) use ($request) {
|
||||||
|
$q->whereHas('test_type', function ($query) use ($request) {
|
||||||
|
$query->where('name', 'like', "%{$request->test_type_name}%");
|
||||||
|
});
|
||||||
|
})
|
||||||
->when(($request->has('device_id') && $request->device_id) && ($request->has('device_label') && $request->device_label && $request->device_label != "undefined"), function ($query) use ($request) {
|
->when(($request->has('device_id') && $request->device_id) && ($request->has('device_label') && $request->device_label && $request->device_label != "undefined"), function ($query) use ($request) {
|
||||||
if ($request->device_label != 'undefined') {
|
if ($request->device_label != 'undefined') {
|
||||||
$query->whereHas('input_values', function ($query) use ($request) {
|
$query->whereHas('input_values', function ($query) use ($request) {
|
||||||
@@ -218,6 +223,7 @@ class TestResultController extends Controller
|
|||||||
|
|
||||||
public function edit(TestResult $TestResult)
|
public function edit(TestResult $TestResult)
|
||||||
{
|
{
|
||||||
|
$TestResult->load('media');
|
||||||
foreach ($TestResult->input_values as $key => $value) {
|
foreach ($TestResult->input_values as $key => $value) {
|
||||||
$input = $value->input;
|
$input = $value->input;
|
||||||
if ($input->type == 'Checkbox' || $input->type == 'Select' || $input['type'] == 'Radiobutton') {
|
if ($input->type == 'Checkbox' || $input->type == 'Select' || $input['type'] == 'Radiobutton') {
|
||||||
@@ -391,7 +397,7 @@ class TestResultController extends Controller
|
|||||||
|
|
||||||
public function showTestResult($id)
|
public function showTestResult($id)
|
||||||
{
|
{
|
||||||
$TestResult = TestResult::with('input_values', 'user.medical_center', 'test_type')->select('result', 'verified', 'device_id', 'user_id', 'id', 'test_type_id', 'created_at')->findOrFail($id);
|
$TestResult = TestResult::with('input_values', 'user.medical_center', 'test_type','media')->select('result', 'verified', 'device_id', 'user_id', 'id', 'test_type_id', 'created_at')->findOrFail($id);
|
||||||
$options = [];
|
$options = [];
|
||||||
foreach ($TestResult->input_values as $value) {
|
foreach ($TestResult->input_values as $value) {
|
||||||
$input = $value->input;
|
$input = $value->input;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Models\Input;
|
|||||||
use App\Models\Option;
|
use App\Models\Option;
|
||||||
use App\Models\TestResult;
|
use App\Models\TestResult;
|
||||||
use App\Models\TestType;
|
use App\Models\TestType;
|
||||||
|
use Exception;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Milon\Barcode\Facades\DNS1DFacade;
|
use Milon\Barcode\Facades\DNS1DFacade;
|
||||||
@@ -380,21 +381,20 @@ class TestTypeController extends Controller
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public function getInputs(Request $request)
|
public function getInputs($idOrCode)
|
||||||
{
|
{
|
||||||
if (auth('api')->user()->can('getInputs')) {
|
if (auth('api')->user()->can('getInputs')) {
|
||||||
return MessageResponse::error(trans('messages.failed'));
|
return MessageResponse::error(trans('messages.failed'));
|
||||||
}
|
}
|
||||||
if ($request->test_result_id !== '') {
|
try {
|
||||||
$testTypeId = TestResult::find($request->test_result_id);
|
$by = request()->query('by', 'id');
|
||||||
}
|
|
||||||
if (isset($testTypeId) && $testTypeId) {
|
|
||||||
$testType = TestType::select('id', 'name', 'unique_code', 'device_label')->find($testTypeId->test_type_id);
|
|
||||||
} else {
|
|
||||||
$testType = TestType::where('name', $request->name)->orWhere('unique_code', $request->unique_code)->select('id', 'name', 'unique_code', 'device_label')->first();
|
|
||||||
}
|
|
||||||
if (isset($testType) && $testType) {
|
|
||||||
|
|
||||||
|
$testType = TestType::select('id', 'name', 'unique_code', 'device_label');
|
||||||
|
if ($by === 'code') {
|
||||||
|
$testType = $testType->where('unique_code', $idOrCode)->firstOrFail();
|
||||||
|
} else {
|
||||||
|
$testType = $testType->findOrFail($idOrCode);
|
||||||
|
}
|
||||||
$inputs = Input::select('id', 'name', 'type', 'size', 'parent_id', 'require_scanner')->with(
|
$inputs = Input::select('id', 'name', 'type', 'size', 'parent_id', 'require_scanner')->with(
|
||||||
['options' => function ($query) {
|
['options' => function ($query) {
|
||||||
$query->select('id', 'title', 'input_id');
|
$query->select('id', 'title', 'input_id');
|
||||||
@@ -408,13 +408,14 @@ class TestTypeController extends Controller
|
|||||||
)->whereNull('parent_id')->where('test_type_id', $testType->id)->get();
|
)->whereNull('parent_id')->where('test_type_id', $testType->id)->get();
|
||||||
|
|
||||||
return MessageResponse::data(['testType' => $testType, 'inputs' => $inputs]);
|
return MessageResponse::data(['testType' => $testType, 'inputs' => $inputs]);
|
||||||
}
|
} catch(Exception $e) {
|
||||||
return MessageResponse::error();
|
return MessageResponse::error();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function listNames()
|
public function list()
|
||||||
{
|
{
|
||||||
$testType = TestType::pluck('name');
|
$testType = TestType::select('id','name')->get();
|
||||||
return MessageResponse::data($testType);
|
return MessageResponse::data($testType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,20 @@ use App\Http\Requests\StoreTransferRequest;
|
|||||||
use App\Http\Resources\TransferResource;
|
use App\Http\Resources\TransferResource;
|
||||||
use App\Models\Item;
|
use App\Models\Item;
|
||||||
use App\Models\Transfer;
|
use App\Models\Transfer;
|
||||||
|
use App\Policies\TransferPolicy;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Packages\Messaging\src\Facades\MessageResponse;
|
use Packages\Messaging\src\Facades\MessageResponse;
|
||||||
|
|
||||||
class TransferItemController extends Controller
|
class TransferItemController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private $policy;
|
||||||
|
|
||||||
|
public function __construct(TransferPolicy $policy)
|
||||||
|
{
|
||||||
|
$this->policy = $policy;
|
||||||
|
}
|
||||||
|
|
||||||
public function getSuspendedTransfer()
|
public function getSuspendedTransfer()
|
||||||
{
|
{
|
||||||
$data = Transfer::query()
|
$data = Transfer::query()
|
||||||
@@ -58,9 +67,10 @@ class TransferItemController extends Controller
|
|||||||
|
|
||||||
public function transfer( StoreTransferRequest $request , Item $Item )
|
public function transfer( StoreTransferRequest $request , Item $Item )
|
||||||
{
|
{
|
||||||
if ( auth( 'api' )->user()->cant( 'transferItem' , [ auth()->user() , $Item ] ) ) {
|
if (!$this->policy->transferItem(auth('api')->user(), $Item)) {
|
||||||
return MessageResponse::error( trans( 'messages.access_denied' ) );
|
return MessageResponse::error( trans( 'messages.access_denied' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $Item->user_id != $request->user_id ) {
|
if ( $Item->user_id != $request->user_id ) {
|
||||||
$Item->transfers()->create( [
|
$Item->transfers()->create( [
|
||||||
"user_transfer_id" => auth()->user()->id,
|
"user_transfer_id" => auth()->user()->id,
|
||||||
|
|||||||
@@ -227,6 +227,7 @@ class UserController extends Controller
|
|||||||
return MessageResponse::error( trans( 'messages.access_denied' ) );
|
return MessageResponse::error( trans( 'messages.access_denied' ) );
|
||||||
}
|
}
|
||||||
$User->syncRoles( $request->roles );
|
$User->syncRoles( $request->roles );
|
||||||
|
$User->load('roles');
|
||||||
return MessageResponse::data( $User );
|
return MessageResponse::data( $User );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,25 +254,26 @@ class UserController extends Controller
|
|||||||
|
|
||||||
public function searchUser(Request $request)
|
public function searchUser(Request $request)
|
||||||
{
|
{
|
||||||
$role = null;
|
|
||||||
$medical_center_id = null;
|
|
||||||
|
|
||||||
$User = auth('api')->user();
|
$User = auth('api')->user();
|
||||||
|
|
||||||
|
$query = User::query()
|
||||||
|
->with('roles')
|
||||||
|
->where('id', '<>', $User->id)
|
||||||
|
->select('id', 'name')
|
||||||
|
->where('name', 'LIKE', '%' . $request->name . '%');
|
||||||
|
|
||||||
if ($User->hasRole('Supervisor') || $User->hasRole('User')) {
|
if ($User->hasRole('Supervisor') || $User->hasRole('User')) {
|
||||||
$medical_center_id = $User->medical_center_id;
|
$query->where(function ($q) use ($User) {
|
||||||
if ( $User->hasRole( 'Supervisor' ) ) {
|
$q->where('medical_center_id', $User->medical_center_id)
|
||||||
$role = 'Admin';
|
->orWhereHas('roles', function ($roleQuery) {
|
||||||
}
|
$roleQuery->where('name', 'Admin');
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$users = User::where( 'id' , '<>' , $User->id )->select( 'id' , 'name' )->where( 'name' , 'LIKE' , '%' . $request->name . '%' )
|
$users = $query->get();
|
||||||
->when( $medical_center_id , function ( $query ) use ( $medical_center_id ) {
|
|
||||||
$query->where( 'medical_center_id' , $medical_center_id );
|
|
||||||
} )
|
|
||||||
->when( $role , function ( $query ) use ( $role ) {
|
|
||||||
$query->role( $role );
|
|
||||||
} )
|
|
||||||
->get();
|
|
||||||
return MessageResponse::data($users);
|
return MessageResponse::data($users);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Exceptions\FieldNotExistsException;
|
||||||
|
// use App\Scopes\OrderByIdScope;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
trait BasicModel
|
||||||
|
{
|
||||||
|
private int $pageSizeLimit = 48;
|
||||||
|
|
||||||
|
protected static function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
// if (! app()->runningInConsole()) {
|
||||||
|
// static::addGlobalScope( new OrderByIdScope );
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPerPage()
|
||||||
|
{
|
||||||
|
$pageSize = (int) request( 'per_page' , $this->perPage );
|
||||||
|
return min( $pageSize , $this->pageSizeLimit );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attributeExists( $attr ): bool
|
||||||
|
{
|
||||||
|
|
||||||
|
return array_key_exists( $attr , $this->attributes );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getField( $name )
|
||||||
|
{
|
||||||
|
$columnName = static::getColumn( $name );
|
||||||
|
return $this->$columnName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setField( $name , $value ): void
|
||||||
|
{
|
||||||
|
$columnName = static::getColumn( $name );
|
||||||
|
$this->$columnName = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getColumnTable( $name ): string
|
||||||
|
{
|
||||||
|
return static::getTableName() . '.' . static::getColumn( $name );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getColumn( $name )
|
||||||
|
{
|
||||||
|
$fieldName = Arr::get( static::$maps , $name );
|
||||||
|
|
||||||
|
if ( is_null( $fieldName ) ) {
|
||||||
|
throw new FieldNotExistsException( "field $name not exists" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTable()
|
||||||
|
{
|
||||||
|
return static::getTableName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fieldValue( $name )
|
||||||
|
{
|
||||||
|
return $this->$name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAttributes()
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isLoaded( $relationName ): bool
|
||||||
|
{
|
||||||
|
return isset( $this->relations[ $relationName ] ) and $this->$relationName != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public static function getTableName();
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
|
|
||||||
|
class Sms extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
use BasicModel;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'client_id' , 'status_code' , 'status' , 'message' , 'rel_id' , 'rel_type' , 'cell_number' , 'segment_count' ,
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $hidden = [];
|
||||||
|
|
||||||
|
public static function getTableName(): string
|
||||||
|
{
|
||||||
|
return "sms";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function receiver(): MorphTo
|
||||||
|
{
|
||||||
|
return $this->morphTo( null , 'rel_type' , 'rel_id' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function smsBatch(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo( SmsBatch::class );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class SmsBatch extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
use SoftDeletes , BasicModel;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'category' , 'operator' , 'code' , 'fee' , 'type' , 'business_id' , 'is_admin' , 'is_systematic' , 'pattern' , 'from'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $hidden = [];
|
||||||
|
|
||||||
|
public static function getTableName(): string
|
||||||
|
{
|
||||||
|
return "sms_batch";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function smsList(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany( Sms::class );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeSingle( $query )
|
||||||
|
{
|
||||||
|
return $query->whereCategory( 'single' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeBatch( $query )
|
||||||
|
{
|
||||||
|
return $query->whereCategory( 'batch' );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -27,6 +27,10 @@ class User extends Authenticatable
|
|||||||
'email_verified_at' => 'datetime',
|
'email_verified_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public array $messageFields = [
|
||||||
|
'name', 'cell_number'
|
||||||
|
];
|
||||||
|
|
||||||
protected function getDefaultGuardName(): string { return 'api'; }
|
protected function getDefaultGuardName(): string { return 'api'; }
|
||||||
|
|
||||||
public function medical_center(): BelongsTo
|
public function medical_center(): BelongsTo
|
||||||
@@ -34,6 +38,11 @@ class User extends Authenticatable
|
|||||||
return $this->belongsTo(MedicalCenter::class);
|
return $this->belongsTo(MedicalCenter::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPhone()
|
||||||
|
{
|
||||||
|
return $this->cell_number;
|
||||||
|
}
|
||||||
|
|
||||||
public function test_results(): HasMany
|
public function test_results(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(TestResult::class);
|
return $this->hasMany(TestResult::class);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class ItemPolicy
|
|||||||
{
|
{
|
||||||
if ($user->hasRole('Admin')) {
|
if ($user->hasRole('Admin')) {
|
||||||
return true;
|
return true;
|
||||||
} elseif ($user->hasRole('Supervisor') && $Item->user()->medical_center_id == $user->medical_center_id) {
|
} elseif ($user->hasRole('Supervisor') && $Item->user->medical_center_id == $user->medical_center_id) {
|
||||||
return true;
|
return true;
|
||||||
} elseif ($user->hasRole('User') && $Item->user_id == $user->id && $Item->status != StatusTypeEnum::APPROVED) {
|
} elseif ($user->hasRole('User') && $Item->user_id == $user->id && $Item->status != StatusTypeEnum::APPROVED) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ class LabelRepository implements LabelRepositoryInterface
|
|||||||
{
|
{
|
||||||
return Label::when($request->has('sterilizer_id') && $request->sterilizer_id != '', function ($query) use ($request) {
|
return Label::when($request->has('sterilizer_id') && $request->sterilizer_id != '', function ($query) use ($request) {
|
||||||
$query->where('sterilizer_id', $request->sterilizer_id);
|
$query->where('sterilizer_id', $request->sterilizer_id);
|
||||||
|
})
|
||||||
|
->when($request->has('package_name') && $request->package_name != '', function ($query) use ($request) {
|
||||||
|
$this->applyPackageNameFilter($query,$request);
|
||||||
})
|
})
|
||||||
->when($request->has('cycle_number') && $request->cycle_number != '', function ($query) use ($request) {
|
->when($request->has('cycle_number') && $request->cycle_number != '', function ($query) use ($request) {
|
||||||
$query->where('cycle_number', $request->cycle_number);
|
$query->where('cycle_number', $request->cycle_number);
|
||||||
@@ -48,6 +51,9 @@ class LabelRepository implements LabelRepositoryInterface
|
|||||||
{
|
{
|
||||||
return Label::when($request->has('sterilizer_id') && $request->sterilizer_id != '', function ($query) use ($request) {
|
return Label::when($request->has('sterilizer_id') && $request->sterilizer_id != '', function ($query) use ($request) {
|
||||||
$query->where('sterilizer_id', $request->sterilizer_id);
|
$query->where('sterilizer_id', $request->sterilizer_id);
|
||||||
|
})
|
||||||
|
->when($request->has('package_name') && $request->package_name != '', function ($query) use ($request) {
|
||||||
|
$this->applyPackageNameFilter($query,$request);
|
||||||
})
|
})
|
||||||
->when($request->has('cycle_number') && $request->cycle_number != '', function ($query) use ($request) {
|
->when($request->has('cycle_number') && $request->cycle_number != '', function ($query) use ($request) {
|
||||||
$query->where('cycle_number', $request->cycle_number);
|
$query->where('cycle_number', $request->cycle_number);
|
||||||
@@ -85,6 +91,9 @@ class LabelRepository implements LabelRepositoryInterface
|
|||||||
{
|
{
|
||||||
return Label::when($request->has('sterilizer_id') && $request->sterilizer_id != '', function ($query) use ($request) {
|
return Label::when($request->has('sterilizer_id') && $request->sterilizer_id != '', function ($query) use ($request) {
|
||||||
$query->where('sterilizer_id', $request->sterilizer_id);
|
$query->where('sterilizer_id', $request->sterilizer_id);
|
||||||
|
})
|
||||||
|
->when($request->has('package_name') && $request->package_name != '', function ($query) use ($request) {
|
||||||
|
$this->applyPackageNameFilter($query,$request);
|
||||||
})
|
})
|
||||||
->when($request->has('cycle_number') && $request->cycle_number != '', function ($query) use ($request) {
|
->when($request->has('cycle_number') && $request->cycle_number != '', function ($query) use ($request) {
|
||||||
$query->where('cycle_number', $request->cycle_number);
|
$query->where('cycle_number', $request->cycle_number);
|
||||||
@@ -114,4 +123,11 @@ class LabelRepository implements LabelRepositoryInterface
|
|||||||
->orderByDesc('id')
|
->orderByDesc('id')
|
||||||
->paginate(10);
|
->paginate(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function applyPackageNameFilter($q,$request)
|
||||||
|
{
|
||||||
|
return $q->whereHas('package', function ($query) use ($request) {
|
||||||
|
$query->where('packages.name', 'like', "%{$request->package_name}%");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,17 @@ class PackageRepository implements PackageRepositoryInterface
|
|||||||
{
|
{
|
||||||
public function indexForUser($request, $user)
|
public function indexForUser($request, $user)
|
||||||
{
|
{
|
||||||
return Package::when($request->has('name') && $request->name != '', function ($query) use ($request) {
|
return Package::with([
|
||||||
|
'user',
|
||||||
|
'user.medical_center' => function ($query) {
|
||||||
|
$query->select('id', 'name', 'address', 'phone_number');
|
||||||
|
},
|
||||||
|
'items'
|
||||||
|
])
|
||||||
|
->tap(function ($query) use ($request) {
|
||||||
|
$this->applyUserNameFilter($query, $request);
|
||||||
|
})
|
||||||
|
->when($request->has('name') && $request->name != '', function ($query) use ($request) {
|
||||||
$query->where('name', 'LIKE', '%'.$request->name.'%');
|
$query->where('name', 'LIKE', '%'.$request->name.'%');
|
||||||
})
|
})
|
||||||
->when($request->has('package_id') && $request->package_id != '', function ($query) use ($request) {
|
->when($request->has('package_id') && $request->package_id != '', function ($query) use ($request) {
|
||||||
@@ -21,12 +31,6 @@ class PackageRepository implements PackageRepositoryInterface
|
|||||||
$query->where('medical_center_id', $request->medical_center_id);
|
$query->where('medical_center_id', $request->medical_center_id);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
->with([
|
|
||||||
'user',
|
|
||||||
'user.medical_center' => function ($query) {
|
|
||||||
$query->select('id', 'name', 'address', 'phone_number');
|
|
||||||
},
|
|
||||||
])
|
|
||||||
->whereHas('user', function ($query) use ($user) {
|
->whereHas('user', function ($query) use ($user) {
|
||||||
$query->where('users.medical_center_id', $user->medical_center_id);
|
$query->where('users.medical_center_id', $user->medical_center_id);
|
||||||
})
|
})
|
||||||
@@ -37,7 +41,17 @@ class PackageRepository implements PackageRepositoryInterface
|
|||||||
|
|
||||||
public function indexForSupervisor($request, $user)
|
public function indexForSupervisor($request, $user)
|
||||||
{
|
{
|
||||||
return Package::when($request->has('name') && $request->name != '', function ($query) use ($request) {
|
return Package::with([
|
||||||
|
'user',
|
||||||
|
'user.medical_center' => function ($query) {
|
||||||
|
$query->select('id', 'name', 'address', 'phone_number');
|
||||||
|
},
|
||||||
|
'items'
|
||||||
|
])
|
||||||
|
->tap(function ($query) use ($request) {
|
||||||
|
$this->applyUserNameFilter($query, $request);
|
||||||
|
})
|
||||||
|
->when($request->has('name') && $request->name != '', function ($query) use ($request) {
|
||||||
$query->where('name', 'LIKE', '%'.$request->name.'%');
|
$query->where('name', 'LIKE', '%'.$request->name.'%');
|
||||||
})
|
})
|
||||||
->when($request->has('package_id') && $request->package_id != '', function ($query) use ($request) {
|
->when($request->has('package_id') && $request->package_id != '', function ($query) use ($request) {
|
||||||
@@ -48,12 +62,7 @@ class PackageRepository implements PackageRepositoryInterface
|
|||||||
$query->where('medical_center_id', $request->medical_center_id);
|
$query->where('medical_center_id', $request->medical_center_id);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
->with([
|
->whereHas('user', function ($query) use ($user) {
|
||||||
'user',
|
|
||||||
'user.medical_center' => function ($query) {
|
|
||||||
$query->select('id', 'name', 'address', 'phone_number');
|
|
||||||
},
|
|
||||||
])->whereHas('user', function ($query) use ($user) {
|
|
||||||
$query->where('users.medical_center_id', $user->medical_center_id);
|
$query->where('users.medical_center_id', $user->medical_center_id);
|
||||||
})
|
})
|
||||||
->orderByDesc('id')
|
->orderByDesc('id')
|
||||||
@@ -62,7 +71,17 @@ class PackageRepository implements PackageRepositoryInterface
|
|||||||
|
|
||||||
public function indexForAdmin($request, $user)
|
public function indexForAdmin($request, $user)
|
||||||
{
|
{
|
||||||
return Package::when($request->has('name') && $request->name != '', function ($query) use ($request) {
|
return Package::with([
|
||||||
|
'user',
|
||||||
|
'user.medical_center' => function ($query) {
|
||||||
|
$query->select('id', 'name', 'address', 'phone_number');
|
||||||
|
},
|
||||||
|
'items'
|
||||||
|
])
|
||||||
|
->tap(function ($query) use ($request) {
|
||||||
|
$this->applyUserNameFilter($query, $request);
|
||||||
|
})
|
||||||
|
->when($request->has('name') && $request->name != '', function ($query) use ($request) {
|
||||||
$query->where('name', 'LIKE', '%'.$request->name.'%');
|
$query->where('name', 'LIKE', '%'.$request->name.'%');
|
||||||
})
|
})
|
||||||
->when($request->has('package_id') && $request->package_id != '', function ($query) use ($request) {
|
->when($request->has('package_id') && $request->package_id != '', function ($query) use ($request) {
|
||||||
@@ -73,13 +92,15 @@ class PackageRepository implements PackageRepositoryInterface
|
|||||||
$query->where('medical_center_id', $request->medical_center_id);
|
$query->where('medical_center_id', $request->medical_center_id);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
->with([
|
|
||||||
'user',
|
|
||||||
'user.medical_center' => function ($query) {
|
|
||||||
$query->select('id', 'name', 'address', 'phone_number');
|
|
||||||
},
|
|
||||||
])
|
|
||||||
->orderByDesc('id')
|
->orderByDesc('id')
|
||||||
->paginate(10);
|
->paginate(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function applyUserNameFilter($queryBuilder,$request){
|
||||||
|
return $queryBuilder->when($request->filled('user_name'), function ($query) use ($request) {
|
||||||
|
$query->whereHas('user', function ($q) use ($request) {
|
||||||
|
$q->where('users.name', 'LIKE', '%' . $request->user_name . '%');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Scopes;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Scope;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
|
class OrderByIdScope implements Scope
|
||||||
|
{
|
||||||
|
public function apply(Builder $builder, Model $model)
|
||||||
|
{
|
||||||
|
$builder->orderBy($model->getTable().'.id', 'desc');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Notification\Batch;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
class BatchTransmitter
|
||||||
|
{
|
||||||
|
|
||||||
|
protected Collection $collection;
|
||||||
|
protected mixed $config;
|
||||||
|
protected $message;
|
||||||
|
|
||||||
|
public function __construct( Collection $collection )
|
||||||
|
{
|
||||||
|
$this->collection = $collection;
|
||||||
|
$this->config = config( 'notification.drivers.rahyab_advertise' );
|
||||||
|
$this->client = new \SoapClient( $this->config[ 'url' ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send( string $message )
|
||||||
|
{
|
||||||
|
$this->message = $message;
|
||||||
|
if ( $this->collection->count() <= config( 'notification.max_phone_size.do_send_sms' ) ) {
|
||||||
|
return $result = $this->client->doSendSMS( $this->payload() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPhones()
|
||||||
|
{
|
||||||
|
$phones = [];
|
||||||
|
foreach ( $this->collection as $key => $item ) {
|
||||||
|
$phones[] = $item->getPhone();
|
||||||
|
}
|
||||||
|
return array_unique( $phones );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function payload()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'uUsername' => $this->config[ 'username' ] ,
|
||||||
|
'uPassword' => $this->config[ 'password' ] ,
|
||||||
|
'uNumber' => $this->config[ 'from' ] ,
|
||||||
|
'uCellphones' => implode( ';' , $this->getPhones() ) ,
|
||||||
|
'uMessage' => $this->message ,
|
||||||
|
'uFarsi' => true ,
|
||||||
|
'uTopic' => false ,
|
||||||
|
'uFlash' => false ,
|
||||||
|
'uUDH' => ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Notification\Batch;
|
||||||
|
|
||||||
|
use App\Models\SmsBatch;
|
||||||
|
use App\Services\Notification\Events\SmsSent;
|
||||||
|
use App\Services\Notification\Events\SmsSentAgain;
|
||||||
|
use App\Services\Notification\MessagePattern\Pattern;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use SoapClient;
|
||||||
|
|
||||||
|
class PeerToPeer
|
||||||
|
{
|
||||||
|
protected Collection $collection;
|
||||||
|
protected array $config;
|
||||||
|
protected Pattern $messagePatternClass;
|
||||||
|
protected string $messagePattern;
|
||||||
|
protected string $operator;
|
||||||
|
protected bool $isAdmin = false;
|
||||||
|
protected bool $isSystematic = false;
|
||||||
|
protected int $price = -80;
|
||||||
|
|
||||||
|
public function __construct(string $message, Collection $collection, string $category, $uniqueCode, $operator = 'advertise')
|
||||||
|
{
|
||||||
|
if ($this->isValidCost() || $operator == 'service') {
|
||||||
|
$this->operator = ($operator == 'advertise') ? 'rahyab_advertise' : 'rahyab_service';
|
||||||
|
$this->collection = $collection;
|
||||||
|
$this->messagePatternClass = new Pattern($message);
|
||||||
|
$this->messagePattern = $this->messagePatternClass->getPattern();
|
||||||
|
$this->config = array_merge($this->createExtra($category, $uniqueCode), config('notification.drivers.' . $this->operator));
|
||||||
|
|
||||||
|
if (isset($this->config['operator'])) {
|
||||||
|
if (str_contains($this->config['operator'], 'advertise')) {
|
||||||
|
$this->config['type'] = 'advertise';
|
||||||
|
} else {
|
||||||
|
$this->config['type'] = 'service';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->client = new SoapClient( $this->config[ 'url' ] );
|
||||||
|
} catch ( \SoapFault $e ) {
|
||||||
|
dd($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isValidCost(): bool
|
||||||
|
{
|
||||||
|
if ( $this->price > -50000.00) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSystematic($isSystematic = 0): static
|
||||||
|
{
|
||||||
|
$this->isSystematic = $isSystematic;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAdmin($isAdmin = 0): static
|
||||||
|
{
|
||||||
|
$this->isAdmin = $isAdmin;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send($userData): void
|
||||||
|
{
|
||||||
|
if ($this->collection->count() <= config('notification.max_phone_size.do_send_sms_array_c')) {
|
||||||
|
$this->setIsAdminAndIsSystematicInConfig();
|
||||||
|
$payload = $this->payload($userData);
|
||||||
|
$response = $this->client->doSendSMSArrayC($payload)->doSendSMSArrayCResult->DataSendOut;
|
||||||
|
$this->serializeToDatabase($payload['uDataSendIn'], $response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendAgain($userData, SmsBatch $smsBatch): void
|
||||||
|
{
|
||||||
|
if ($this->collection->count() <= config('notification.max_phone_size.do_send_sms_array_c')) {
|
||||||
|
$payload = $this->payload($userData);
|
||||||
|
$response = $this->client->doSendSMSArrayC($payload)->doSendSMSArrayCResult->DataSendOut;
|
||||||
|
$this->updateToDatabase($payload['uDataSendIn'], $response, $smsBatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function payload($userData): array
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
foreach ($this->collection as $key => $item) {
|
||||||
|
$data[$key] = $this->prepareData($item, $userData);
|
||||||
|
}
|
||||||
|
return array(
|
||||||
|
'uUsername' => $this->config['username'],
|
||||||
|
'uPassword' => $this->config['password'],
|
||||||
|
'uDataSendIn' => $data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function prepareData(Model $model, $userData): array
|
||||||
|
{
|
||||||
|
$fillable = is_null($userData) ? $model : $userData;
|
||||||
|
return [
|
||||||
|
'ClientID' => rand(1, 1000000000000000),
|
||||||
|
'ShortCode' => $this->findFrom(),
|
||||||
|
'Cellphone' => $model->getPhone(),
|
||||||
|
'Message' => $this->messagePatternClass->fill($fillable),
|
||||||
|
'Farsi' => true,
|
||||||
|
'Flash' => false,
|
||||||
|
'UDH' => '',
|
||||||
|
'ServiceID' => ''
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function findFrom()
|
||||||
|
{
|
||||||
|
$smsOperatorConfig = collect(config('notification.config_system'));
|
||||||
|
|
||||||
|
if (is_null($smsOperatorConfig) or $smsOperatorConfig->isEmpty()) {
|
||||||
|
return $this->config['from'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$customConfig = $smsOperatorConfig->getConfig($this->operator);
|
||||||
|
|
||||||
|
if (is_null($customConfig)) {
|
||||||
|
return $this->config['from'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $customConfig['from'];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function serializeToDatabase($payload, $response): void
|
||||||
|
{
|
||||||
|
$this->collection->count() > 1 ?: $response = [$response];
|
||||||
|
event(new SmsSent($this->collection, json_decode(json_encode($response), true), $payload, $this->config));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function updateToDatabase($payload, $response, $smsBatch): void
|
||||||
|
{
|
||||||
|
$this->collection->count() > 1 ?: $response = [$response];
|
||||||
|
event(new SmsSentAgain($this->collection, json_decode(json_encode($response), true), $payload, $this->config, $smsBatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createExtra($category, $uniqueCode): array
|
||||||
|
{
|
||||||
|
$extra ['is_admin'] = $this->isAdmin;
|
||||||
|
$extra ['is_systematic'] = $this->isSystematic;
|
||||||
|
$extra ['category'] = $category;
|
||||||
|
$extra ['operator'] = 'rahyab_advertise';
|
||||||
|
$extra ['code'] = $uniqueCode;
|
||||||
|
$extra ['messagePattern'] = $this->messagePattern;
|
||||||
|
$extra['className'] = $this->collection->isEmpty() ? null : getNamespaceMap($this->collection->first());
|
||||||
|
return $extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setIsAdminAndIsSystematicInConfig(): void
|
||||||
|
{
|
||||||
|
$this->config['is_admin'] = $this->isAdmin;
|
||||||
|
$this->config['is_systematic'] = $this->isSystematic;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Notification\Batch;
|
||||||
|
|
||||||
|
use App\Models\SmsBatch;
|
||||||
|
use App\Services\Notification\Events\SmsSent;
|
||||||
|
use App\Services\Notification\Events\SmsSentAgain;
|
||||||
|
use App\Services\Notification\MessagePattern\Pattern;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class SimCard
|
||||||
|
{
|
||||||
|
|
||||||
|
protected Collection $collection;
|
||||||
|
protected array $config;
|
||||||
|
protected Pattern $messagePatternClass;
|
||||||
|
protected string $messagePattern;
|
||||||
|
protected array $payload;
|
||||||
|
protected bool $isAdmin = false;
|
||||||
|
protected bool $isSystematic = false;
|
||||||
|
|
||||||
|
public function __construct( $message , Collection $collection , string $category , $uniqueCode )
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->collection = $collection;
|
||||||
|
$this->messagePatternClass = new Pattern( $message );
|
||||||
|
$this->messagePattern = $this->messagePatternClass->getPattern();
|
||||||
|
$this->config = array_merge( $this->createExtra( $category , $uniqueCode ) , config( 'notification.drivers.simcard' ) );
|
||||||
|
|
||||||
|
if ( isset( $this->config[ 'operator' ] ) ) {
|
||||||
|
$this->config[ 'type' ] = 'simcard';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->client = new \SoapClient( $this->config[ 'url' ] , array( 'trace' => 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSystematic( $isSystematic = 0 ): static
|
||||||
|
{
|
||||||
|
$this->isSystematic = $isSystematic;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAdmin( $isAdmin = 0 ): static
|
||||||
|
{
|
||||||
|
$this->isAdmin = $isAdmin;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send( $userData ): void
|
||||||
|
{
|
||||||
|
if ( $this->collection->count() <= config( 'notification.max_phone_size.do_send_sms_array_c' ) ) {
|
||||||
|
$this->setIsAdminAndIsSystematicInConfig();
|
||||||
|
$payload = $this->payload( $userData );
|
||||||
|
$response = $this->client->SendSMS( $payload[ 'from' ] , $payload[ 'numbers' ] , $payload[ 'messages' ] , $payload[ 'username' ] , $payload[ 'password' ] , $payload[ 'time' ] , $payload[ 'op' ] );
|
||||||
|
$response = json_decode( $response );
|
||||||
|
$this->serializeToDatabase( json_decode( $response[ count( $response ) - 1 ] )[ 1 ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendAgain( $userData , SmsBatch $smsBatch ): void
|
||||||
|
{
|
||||||
|
if ( $this->collection->count() <= config( 'notification.max_phone_size.do_send_sms_array_c' ) ) {
|
||||||
|
$payload = $this->payload( $userData );
|
||||||
|
$response = $this->client->SendSMS( $payload[ 'from' ] , $payload[ 'numbers' ] , $payload[ 'messages' ] , $payload[ 'username' ] , $payload[ 'password' ] , $payload[ 'time' ] , $payload[ 'op' ] );
|
||||||
|
$response = json_decode( $response );
|
||||||
|
$this->updateToDatabase( $response , $smsBatch );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function payload( $userData ): array
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'username' => $this->config[ 'username' ] ,
|
||||||
|
'password' => $this->config[ 'password' ] ,
|
||||||
|
'from' => $this->config[ 'from' ] ,
|
||||||
|
'op' => "pointtopoint" ,
|
||||||
|
'time' => '' ,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ( $this->collection as $key => $item ) {
|
||||||
|
$modelData = $this->prepareData( $item , $userData );
|
||||||
|
$this->payload[] = $modelData;
|
||||||
|
$data[ 'numbers' ][] = $modelData[ 'Cellphone' ];
|
||||||
|
$data[ 'messages' ][] = $modelData[ 'Message' ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function prepareData( Model $model , $userData ): array
|
||||||
|
{
|
||||||
|
$fillable = is_null( $userData ) ? $model : $userData;
|
||||||
|
return [
|
||||||
|
'Cellphone' => $model->getPhone() ,
|
||||||
|
'Message' => $this->messagePatternClass->fill( $fillable ) ,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function serializeToDatabase( $response ): void
|
||||||
|
{
|
||||||
|
$response = $this->prepareResponse( $response );
|
||||||
|
event( new SmsSent( $this->collection , json_decode( json_encode( $response ) , true ) , $this->payload , $this->config ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function updateToDatabase( $response , $smsBatch ): void
|
||||||
|
{
|
||||||
|
$response = $this->prepareResponse( $response );
|
||||||
|
event( new SmsSentAgain( $this->collection , json_decode( json_encode( $response ) , true ) , $this->payload , $this->config , $smsBatch ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function prepareResponse( $response ): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach ( $response as $value ) {
|
||||||
|
$result[] = [
|
||||||
|
'ClientID' => null ,
|
||||||
|
'ServerID' => is_numeric( $value ) ? $value : -1 ,
|
||||||
|
'Status' => is_numeric( $value ) ? 'Send OK.' : $value ,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createExtra( $category , $uniqueCode ): array
|
||||||
|
{
|
||||||
|
$extra [ 'is_admin' ] = $this->isAdmin;
|
||||||
|
$extra [ 'is_systematic' ] = $this->isSystematic;
|
||||||
|
$extra [ 'category' ] = $category;
|
||||||
|
$extra [ 'operator' ] = 'simcard';
|
||||||
|
$extra [ 'code' ] = $uniqueCode;
|
||||||
|
$extra [ 'messagePattern' ] = $this->messagePattern;
|
||||||
|
$extra [ 'className' ] = $this->collection->isEmpty() ? null : getNamespaceMap( $this->collection->first() );
|
||||||
|
return $extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setIsAdminAndIsSystematicInConfig(): void
|
||||||
|
{
|
||||||
|
$this->config[ 'is_admin' ] = $this->isAdmin;
|
||||||
|
$this->config[ 'is_systematic' ] = $this->isSystematic;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Notification\Events;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class SmsSent
|
||||||
|
{
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
public Collection $collection;
|
||||||
|
public array $response;
|
||||||
|
public array $payload;
|
||||||
|
public array $extra;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new event instance.
|
||||||
|
*
|
||||||
|
* @param Collection $collection
|
||||||
|
* @param array $response
|
||||||
|
* @param array $payload
|
||||||
|
* @param array $extra
|
||||||
|
*/
|
||||||
|
public function __construct( Collection $collection , array $response , array $payload , array $extra )
|
||||||
|
{
|
||||||
|
$this->collection = $collection;
|
||||||
|
$this->response = $response;
|
||||||
|
$this->payload = $payload;
|
||||||
|
$this->extra = $extra;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Notification\Events;
|
||||||
|
|
||||||
|
use App\Models\SmsBatch;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class SmsSentAgain
|
||||||
|
{
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
public Collection $collection;
|
||||||
|
public array $response;
|
||||||
|
public array $payload;
|
||||||
|
public array $extra;
|
||||||
|
public SmsBatch $smsBatch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new event instance.
|
||||||
|
*
|
||||||
|
* @param Collection $collection
|
||||||
|
* @param array $response
|
||||||
|
* @param array $payload
|
||||||
|
* @param array $extra
|
||||||
|
* @param SmsBatch $smsBatch
|
||||||
|
*/
|
||||||
|
public function __construct( Collection $collection , array $response , array $payload , array $extra , SmsBatch $smsBatch )
|
||||||
|
{
|
||||||
|
$this->collection = $collection;
|
||||||
|
$this->response = $response;
|
||||||
|
$this->payload = $payload;
|
||||||
|
$this->extra = $extra;
|
||||||
|
$this->smsBatch = $smsBatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Notification\Listeners;
|
||||||
|
|
||||||
|
use App\Models\Sms;
|
||||||
|
use App\Models\SmsBatch;
|
||||||
|
use App\Services\Notification\Events\SmsSent;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class StoreSmsInDatabase
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public function handle( SmsSent $event ): void
|
||||||
|
{
|
||||||
|
$chars_in_every_sms_part = config( "sms.sms_length_calculator.chars_in_every_sms_part" ) > 0 ? : 60;
|
||||||
|
$smsList = [];
|
||||||
|
|
||||||
|
foreach ( $event->collection as $key => $value ) {
|
||||||
|
$smsList[ $key ] = new Sms( [
|
||||||
|
'client_id' => $event->response[ $key ][ 'ClientID' ] ,
|
||||||
|
'status' => $event->response[ $key ][ 'Status' ] ,
|
||||||
|
'message' => $event->payload[ $key ][ 'Message' ] ,
|
||||||
|
'rel_id' => $value->id ,
|
||||||
|
'segment_count' => ceil( strlen( $event->extra[ 'messagePattern' ] ) / $chars_in_every_sms_part ) ,
|
||||||
|
'cell_number' => $event->payload[ $key ][ 'Cellphone' ] ,
|
||||||
|
'rel_type' => $event->extra[ 'className' ] ,
|
||||||
|
'fee' => $event->extra[ 'fee' ] ,
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::alert( 'store SmsBatch' , [ 'hasSms' => SmsBatch::where( 'code' , $event->extra[ 'code' ] )->first() ] );
|
||||||
|
|
||||||
|
$smsBatch = SmsBatch::firstOrCreate(
|
||||||
|
[
|
||||||
|
'code' => $event->extra[ 'code' ]
|
||||||
|
] ,
|
||||||
|
[
|
||||||
|
'category' => $event->extra[ 'category' ] ,
|
||||||
|
'operator' => $event->extra[ 'operator' ] ,
|
||||||
|
'type' => $event->extra[ 'type' ] ,
|
||||||
|
'pattern' => $event->extra[ 'messagePattern' ] ,
|
||||||
|
'is_admin' => $event->extra[ 'is_admin' ] ,
|
||||||
|
'is_systematic' => $event->extra[ 'is_systematic' ] ,
|
||||||
|
'from' => $event->extra[ 'from' ] ,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$smsBatch->smsList()->saveMany( $smsList );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Notification\MessagePattern;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Pattern
|
||||||
|
{
|
||||||
|
|
||||||
|
protected string $pattern;
|
||||||
|
|
||||||
|
public function __construct( $pattern )
|
||||||
|
{
|
||||||
|
$this->pattern = $pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fill( $model ): string
|
||||||
|
{
|
||||||
|
$replacements = $this->findReplacements( $model );
|
||||||
|
return strtr( $this->pattern , $replacements );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function findReplacements( $model , $prefix = '{' , $postfix = '}' ): array
|
||||||
|
{
|
||||||
|
$replacements = [];
|
||||||
|
foreach ( $model->messageFields as $field ) {
|
||||||
|
list( $nickName , $value ) = $this->getFieldValue( $model , $field );
|
||||||
|
$replacements[ $prefix . $nickName . $postfix ] = $value;
|
||||||
|
}
|
||||||
|
if ( config( 'notification.fields' ) ) {
|
||||||
|
foreach ( config( 'notification.fields' ) as $name => $field ) {
|
||||||
|
$replacements[ $prefix . $name . $postfix ] = $field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $replacements;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFieldValue( Model $model , string $messageField ): array
|
||||||
|
{
|
||||||
|
$parts = explode( ' as ' , $messageField );
|
||||||
|
if ( count( $parts ) == 2 and $this->isRelation( $parts[ 0 ] ) ) {
|
||||||
|
list( $relation , $field ) = $this->splitRelationField( $parts[ 0 ] );
|
||||||
|
$model->loadMissing( $relation );
|
||||||
|
$key = $parts[ 1 ];
|
||||||
|
$value = $model->$relation ? $model->$relation->$field : '';
|
||||||
|
} else {
|
||||||
|
$key = $messageField;
|
||||||
|
$value = $model->$messageField;
|
||||||
|
}
|
||||||
|
return [ $key , $value ];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isRelation( $field ): bool
|
||||||
|
{
|
||||||
|
return str_contains( $field , ':' );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function splitRelationField( $field ): array
|
||||||
|
{
|
||||||
|
$parts = explode( ':' , $field );
|
||||||
|
$partsCount = count( $parts );
|
||||||
|
return [ implode( '.' , array_slice( $parts , 0 , $partsCount - 1 ) ) , $parts[ $partsCount - 1 ] ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPattern(): string
|
||||||
|
{
|
||||||
|
return $this->pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Notification;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
class SendSmsToAdmins
|
||||||
|
{
|
||||||
|
protected array $mobiles;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->mobiles = [
|
||||||
|
"09101526570",
|
||||||
|
"09128529050"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendRequestNotification($device_title, $smsUser)
|
||||||
|
{
|
||||||
|
$adminCollection = User::query()
|
||||||
|
->orWhere('role', 'admin');
|
||||||
|
|
||||||
|
$adminText = "کاربر %s
|
||||||
|
با شماره ی همراه %s
|
||||||
|
درخواستی زیر را ثبت کرد\n
|
||||||
|
%s\n";
|
||||||
|
$adminText = sprintf($adminText, $smsUser->full_name, $smsUser->cell_number, $device_title);
|
||||||
|
SmsNotification::to($adminCollection)->isSystematic()->send(
|
||||||
|
$adminText,
|
||||||
|
'service'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
$userText = "%s عزیز\n
|
||||||
|
درخواست شما را دریافت کردیم\n
|
||||||
|
به زودی همکاران ما با شما تماس خواهند گرفت\n
|
||||||
|
از اعتماد شما سپاسگزاریم\n";
|
||||||
|
$userText = sprintf($userText, $smsUser->full_name);
|
||||||
|
$userCollection = User::query()->where('id', $smsUser->id);
|
||||||
|
$res = SmsNotification::to($userCollection)->isSystematic()->send(
|
||||||
|
$userText,
|
||||||
|
'service'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Notification;
|
||||||
|
|
||||||
|
use App\Models\SmsBatch;
|
||||||
|
use App\Services\Notification\Batch\PeerToPeer;
|
||||||
|
use App\Services\Notification\Batch\SimCard;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class SmsNotification
|
||||||
|
{
|
||||||
|
protected $builder;
|
||||||
|
protected string $category;
|
||||||
|
protected $userData;
|
||||||
|
protected bool $isSystematic = false;
|
||||||
|
protected bool $isAdmin = false;
|
||||||
|
|
||||||
|
protected static $self = null;
|
||||||
|
|
||||||
|
private function __construct($builder, $userData)
|
||||||
|
{
|
||||||
|
$this->builder = $builder;
|
||||||
|
$this->userData = $userData;
|
||||||
|
$this->category = $this->builder->limit(2)->count() > 1 ? 'batch' : 'single';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBuilder($builder): static
|
||||||
|
{
|
||||||
|
$this->builder = $builder;
|
||||||
|
$this->category = $this->builder->limit(2)->count() > 1 ? 'batch' : 'single';
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUserData($userData): static
|
||||||
|
{
|
||||||
|
$this->userData = $userData;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function to($builder, $userData = null)
|
||||||
|
{
|
||||||
|
if (static::$self === null) {
|
||||||
|
static::$self = new static($builder, $userData);
|
||||||
|
}
|
||||||
|
return static::$self;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSystematic(): static
|
||||||
|
{
|
||||||
|
$this->isSystematic = true;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAdmin(): static
|
||||||
|
{
|
||||||
|
$this->isAdmin = true;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendAgain(SmsBatch $smsBatch): void
|
||||||
|
{
|
||||||
|
$uniqueCode = Str::random(40);
|
||||||
|
foreach ($this->chuncks() as $notification) {
|
||||||
|
switch ($smsBatch->type) {
|
||||||
|
case 'advertise':
|
||||||
|
(new PeerToPeer($smsBatch->pattern, $notification, $this->category, $uniqueCode))->isAdmin($this->isAdmin)->isSystematic($this->isSystematic)->sendAgain($this->userData,
|
||||||
|
$smsBatch);
|
||||||
|
break;
|
||||||
|
case 'simcard' :
|
||||||
|
(new SimCard($smsBatch->pattern, $notification, $this->category, $uniqueCode))->isAdmin($this->isAdmin)->isSystematic($this->isSystematic)->sendAgain($this->userData, $smsBatch);
|
||||||
|
break;
|
||||||
|
case 'service':
|
||||||
|
(new PeerToPeer($smsBatch->pattern, $notification, $this->category, $uniqueCode, 'service'))->isAdmin($this->isAdmin)->isSystematic($this->isSystematic)->sendAgain($this->userData,
|
||||||
|
$smsBatch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function send($message, $method = 'advertise'): void
|
||||||
|
{
|
||||||
|
$uniqueCode = Str::random(40);
|
||||||
|
foreach ($this->chuncks() as $notification) {
|
||||||
|
switch ($method) {
|
||||||
|
case 'advertise':
|
||||||
|
(new PeerToPeer($message, $notification, $this->category, $uniqueCode))->isAdmin($this->isAdmin)->isSystematic($this->isSystematic)->send($this->userData);
|
||||||
|
break;
|
||||||
|
case 'simcard' :
|
||||||
|
(new SimCard($message, $notification, $this->category, $uniqueCode))->isAdmin($this->isAdmin)->isSystematic($this->isSystematic)->send($this->userData);
|
||||||
|
break;
|
||||||
|
case 'service':
|
||||||
|
(new PeerToPeer($message, $notification, $this->category, $uniqueCode, 'service'))->isAdmin($this->isAdmin)->isSystematic($this->isSystematic)->send($this->userData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendWithTemplate($template): void
|
||||||
|
{
|
||||||
|
if ( ! is_null($template)) {
|
||||||
|
$this->send($template->template, $template->operator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function chuncks(): \Generator
|
||||||
|
{
|
||||||
|
$limit = config('notification.max_phone_size.do_send_sms_array_c');
|
||||||
|
$iteration = 0;
|
||||||
|
while (true) {
|
||||||
|
$offset = $iteration * $limit;
|
||||||
|
$chunk = $this->builder->offset($offset)->limit($limit)->get();
|
||||||
|
if ($chunk->isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$iteration++;
|
||||||
|
yield $chunk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Sms;
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
'db_name' => 'willaengine',
|
||||||
|
|
||||||
|
'morph_models' => [],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Driver
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value determines which of drivers should be used.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'default' => 'advertise',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Notification Configs
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| These are the list of configs to use for sending sms.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'drivers' => [
|
||||||
|
'advertise' => [
|
||||||
|
'url' => 'http://188.0.240.110/class/sms/wsdlservice/server.php?wsdl',
|
||||||
|
'username' => env('SMS_USERNAME'),
|
||||||
|
'password' => env('SMS_PASSWORD'),
|
||||||
|
'from' => env('SMS_NUMBER_ADVERTISE'),
|
||||||
|
],
|
||||||
|
'service' => [
|
||||||
|
'url' => 'http://188.0.240.110/class/sms/wsdlservice/server.php?wsdl',
|
||||||
|
'username' => env('SMS_USERNAME'),
|
||||||
|
'password' => env('SMS_PASSWORD'),
|
||||||
|
'from' => env('SMS_NUMBER_SERVICE'),
|
||||||
|
],
|
||||||
|
'simcard' => [
|
||||||
|
'url' => 'http://188.0.240.110/class/sms/wsdlservice/server.php?wsdl',
|
||||||
|
'username' => env('SMS_USERNAME'),
|
||||||
|
'password' => env('SMS_PASSWORD'),
|
||||||
|
'from' => env('SMS_NUMBER_SIM_CARD'),
|
||||||
|
'fee' => 150
|
||||||
|
],
|
||||||
|
'pattern' => [
|
||||||
|
'url' => 'http://188.0.240.110/class/sms/wsdlservice/server.php?wsdl',
|
||||||
|
'username' => env('SMS_USERNAME'),
|
||||||
|
'password' => env('SMS_PASSWORD'),
|
||||||
|
'from' => env('SMS_NUMBER_SERVICE'),
|
||||||
|
],
|
||||||
|
'rahyab_advertise' => [
|
||||||
|
'url' => 'https://sms.igama.ir/webservice/sms.asmx?wsdl',
|
||||||
|
'username' => env('RAHYAB_SMS_USERNAME'),
|
||||||
|
'password' => env('RAHYAB_SMS_PASSWORD'),
|
||||||
|
'from' => env('RAHYAB_SMS_NUMBER_ADVERTISE'),
|
||||||
|
'fee' => 100
|
||||||
|
],
|
||||||
|
'rahyab_service' => [
|
||||||
|
'url' => 'https://sms.igama.ir/webservice/sms.asmx?wsdl',
|
||||||
|
'username' => env('RAHYAB_SMS_USERNAME'),
|
||||||
|
'password' => env('RAHYAB_SMS_PASSWORD'),
|
||||||
|
'from' => env('RAHYAB_SMS_NUMBER_SERVICE'),
|
||||||
|
'fee' => 80
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Class Maps
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This is the array of Classes that maps to Drivers above.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'map' => [
|
||||||
|
'advertise' => Sms::class,
|
||||||
|
'service' => Sms::class,
|
||||||
|
'simcard' => Sms::class,
|
||||||
|
'pattern' => SmsPattern::class,
|
||||||
|
'rahyab_advertise' => HelloWorld::class,
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Fields Pattern
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This is the array of fields that used in sms patterns.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'fields' => [
|
||||||
|
'time' => now('Asia/Tehran')->format('H:i:s'),
|
||||||
|
'date' => now('Asia/Tehran')->format('Y/m/d')
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| MAXIMUM NUMBER OF PHONE NUMBERS IN ONE BATCH
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| CAUTION!! DONT TOUCH THESE NUMBERS
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'max_phone_size' => [
|
||||||
|
'do_send_sms' => 83,
|
||||||
|
'do_send_sms_array_c' => 100,
|
||||||
|
],
|
||||||
|
'max_update_devlivery_status_bulk_items' => 100,
|
||||||
|
'sms_length_calculator' => [
|
||||||
|
'encoding' => '8', //bit
|
||||||
|
'chars_in_every_sms_part' => 63
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
'config_system' => [],
|
||||||
|
|
||||||
|
];
|
||||||
@@ -27,7 +27,7 @@ class ItemFactory extends Factory
|
|||||||
'udi' => $this->faker->uuid,
|
'udi' => $this->faker->uuid,
|
||||||
'repair' => $this->faker->boolean,
|
'repair' => $this->faker->boolean,
|
||||||
'creator_id' => \App\Models\User::factory(),
|
'creator_id' => \App\Models\User::factory(),
|
||||||
'status' => $this->faker->randomElement(['approved', 'rejected', 'suspended']),
|
'status' => $this->faker->randomElement(['approved', 'rejected', 'pending']),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class PackageFactory extends Factory
|
|||||||
'bar_code' => $this->faker->optional()->word,
|
'bar_code' => $this->faker->optional()->word,
|
||||||
'qr_code' => $this->faker->optional()->word,
|
'qr_code' => $this->faker->optional()->word,
|
||||||
'creator_id' => User::factory(), // ایجاد کاربر دیگر به عنوان creator
|
'creator_id' => User::factory(), // ایجاد کاربر دیگر به عنوان creator
|
||||||
'status' => $this->faker->randomElement(['approved', 'rejected', 'suspended']),
|
'status' => $this->faker->randomElement(['approved', 'rejected', 'pending']),
|
||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
'updated_at' => now(),
|
'updated_at' => now(),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('sms', function (Blueprint $table) {
|
||||||
|
$table->increments( 'id' );
|
||||||
|
$table->unsignedBigInteger( 'client_id' )->nullable();
|
||||||
|
$table->string( 'status' );
|
||||||
|
$table->string( 'message' , 100 );
|
||||||
|
$table->unsignedInteger( 'rel_id' );
|
||||||
|
$table->string( 'rel_type' , 50 );
|
||||||
|
$table->string( 'cell_number' , 20 );
|
||||||
|
$table->unsignedInteger( 'fee' )->default( 0 );
|
||||||
|
$table->unsignedInteger( 'sms_batch_id' );
|
||||||
|
$table->index( 'sms_batch_id' );
|
||||||
|
$table->integer( 'segment_count' )->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('sms');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('sms_batch', function (Blueprint $table) {
|
||||||
|
$table->increments( 'id' );
|
||||||
|
$table->string( 'category' );
|
||||||
|
$table->string( 'operator' , 100 );
|
||||||
|
$table->enum( 'type' , [ 'service' , 'simcard' , 'advertise' ] );
|
||||||
|
$table->string( 'code' , 40 );
|
||||||
|
$table->string( 'pattern' )->nullable();
|
||||||
|
$table->boolean( 'is_admin' )->default( 0 );
|
||||||
|
$table->boolean( 'is_systematic' )->default( 0 );
|
||||||
|
$table->string( 'from' )->nullable();
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('sms_batch');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
use Spatie\Permission\Models\Role;
|
||||||
|
|
||||||
|
class TempSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Seed the application's database.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$roles = [
|
||||||
|
['name' => 'Admin','guard_name'=>'api'],
|
||||||
|
['name' => 'Supervisor','guard_name'=>'api'],
|
||||||
|
['name' => 'User','guard_name'=>'api']
|
||||||
|
];
|
||||||
|
Role::insert($roles);
|
||||||
|
|
||||||
|
$user = User::create([
|
||||||
|
'name' => 'user',
|
||||||
|
'email' => 'user@user',
|
||||||
|
'country_code' => '0098',
|
||||||
|
'cell_number' => '09392349878',
|
||||||
|
'gender' => 'Male',
|
||||||
|
'verified' => 'Verified',
|
||||||
|
'status' => 'Active',
|
||||||
|
'medical_center_id' => 1, // ایجاد مرکز پزشکی به طور خودکار
|
||||||
|
'password' => bcrypt('password'), // رمز عبور پیشفرض
|
||||||
|
'address' => 'yyop.st 45 5.No',
|
||||||
|
'remember_token' => '1234567891',
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
$admin = User::create([
|
||||||
|
'name' => 'admin',
|
||||||
|
'email' => 'admin@admin',
|
||||||
|
'country_code' => '0098',
|
||||||
|
'cell_number' => '09121231234',
|
||||||
|
'gender' => 'Male',
|
||||||
|
'verified' => 'Verified',
|
||||||
|
'status' => 'Active',
|
||||||
|
'medical_center_id' => 1, // ایجاد مرکز پزشکی به طور خودکار
|
||||||
|
'password' => bcrypt('password'), // رمز عبور پیشفرض
|
||||||
|
'address' => 'rgdforp.st 49 8.No',
|
||||||
|
'remember_token' => '5432123459',
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
$supervisor=User::create([
|
||||||
|
'name' => 'supervisor',
|
||||||
|
'email' => 'supervisor@supervisor',
|
||||||
|
'country_code' => '0098',
|
||||||
|
'cell_number' => '09101231232',
|
||||||
|
'gender' => 'Male',
|
||||||
|
'verified' => 'Verified',
|
||||||
|
'status' => 'Active',
|
||||||
|
'medical_center_id' => 1, // ایجاد مرکز پزشکی به طور خودکار
|
||||||
|
'password' => bcrypt('password'), // رمز عبور پیشفرض
|
||||||
|
'address' => 'yyhdfghop.st 43 6.No',
|
||||||
|
'remember_token' => '1234543212',
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$user->assignRole('User');
|
||||||
|
$admin->assignRole('Admin');
|
||||||
|
$supervisor->assignRole('Supervisor');
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -31,10 +31,10 @@ services:
|
|||||||
mysql:
|
mysql:
|
||||||
image: 'docker-proxy.meshkee.com/mysql/mysql-server:8.0'
|
image: 'docker-proxy.meshkee.com/mysql/mysql-server:8.0'
|
||||||
container_name: cssd_mysql
|
container_name: cssd_mysql
|
||||||
restart: always
|
|
||||||
ports:
|
ports:
|
||||||
- "3312:3306"
|
- "3312:3306"
|
||||||
environment:
|
environment:
|
||||||
|
MYSQL_ROOT_HOST: '%'
|
||||||
MYSQL_DATABASE: "${DB_DATABASE:-cssd}"
|
MYSQL_DATABASE: "${DB_DATABASE:-cssd}"
|
||||||
MYSQL_PORT: "${DB_PORT:-3306}"
|
MYSQL_PORT: "${DB_PORT:-3306}"
|
||||||
MYSQL_USERNAME: "${DB_USERNAME:-root}"
|
MYSQL_USERNAME: "${DB_USERNAME:-root}"
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ namespace Packages\Auth;
|
|||||||
|
|
||||||
use App\Http\Controllers\Api\Auth\LoginController;
|
use App\Http\Controllers\Api\Auth\LoginController;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Services\Notification\SmsNotification;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Packages\Messaging\src\Facades\MessageResponse;
|
use Packages\Messaging\src\Facades\MessageResponse;
|
||||||
use Packages\SMSSender\SMSSender;
|
// use Packages\SMSSender\SMSSender;
|
||||||
|
|
||||||
trait SendsPasswordResetEmails
|
trait SendsPasswordResetEmails
|
||||||
{
|
{
|
||||||
@@ -37,16 +39,14 @@ trait SendsPasswordResetEmails
|
|||||||
*/
|
*/
|
||||||
public function checkDisposablePassword(Request $request)
|
public function checkDisposablePassword(Request $request)
|
||||||
{
|
{
|
||||||
if ( \Cache::has($request->code) ) {
|
|
||||||
$userid = \Cache::pull($request->code);
|
$userid = \Cache::pull($request->code);
|
||||||
$user = User::where('id', $userid)->first();
|
if ( !is_null($userid) ) {
|
||||||
|
$user = User::findOrFail($userid);
|
||||||
if($user) {
|
if($user) {
|
||||||
|
$user->password = \Hash::make($request->code);
|
||||||
$password = rand(10000000, 999999999);
|
|
||||||
$user->password = \Hash::make($password);
|
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
$request->merge([ 'cell_number' => $user->cell_number, 'password' => $password ]);
|
$request->merge([ 'cell_number' => $user->cell_number, 'password' => $request->code ]);
|
||||||
return (new LoginController())->login($request);
|
return (new LoginController())->login($request);
|
||||||
}
|
}
|
||||||
return MessageResponse::error('User Not Found');
|
return MessageResponse::error('User Not Found');
|
||||||
@@ -57,11 +57,18 @@ trait SendsPasswordResetEmails
|
|||||||
|
|
||||||
protected function generateAndSendCode($request)
|
protected function generateAndSendCode($request)
|
||||||
{
|
{
|
||||||
$user = User::where('cell_number', $request->cell_number)->where('status', 'Active')->first();
|
$userModel = User::where('cell_number', $request->cell_number)->where('status', 'Active');
|
||||||
|
$user = $userModel->first();
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$code = rand(100000, 999999);
|
$code = rand(100000, 999999);
|
||||||
\Cache::put($code, $user->id, Carbon::now()->addMinutes(30));
|
\Cache::put($code, $user->id, Carbon::now()->addMinutes(30));
|
||||||
SMSSender::instance()->patternSend($request->cell_number, 'jqomyn42wo', ["verification-code" => $code]);
|
SmsNotification::to( $userModel )->isSystematic()->send(
|
||||||
|
trans( 'sms.reset_password' , [
|
||||||
|
'activation_code' => $code
|
||||||
|
] ) ,
|
||||||
|
'service'
|
||||||
|
);
|
||||||
|
// SMSSender::instance()->patternSend($request->cell_number, 'jqomyn42wo', ["verification-code" => $code]);
|
||||||
return MessageResponse::success('Send Disposable Password');
|
return MessageResponse::success('Send Disposable Password');
|
||||||
}
|
}
|
||||||
return MessageResponse::error('User Not Found');
|
return MessageResponse::error('User Not Found');
|
||||||
|
|||||||
Vendored
+3
-2
@@ -5,7 +5,9 @@ const urls = {
|
|||||||
showItem: function(id) {
|
showItem: function(id) {
|
||||||
// return `/ShowItem/${id}`;
|
// return `/ShowItem/${id}`;
|
||||||
return `/api/show-item/${id}`;
|
return `/api/show-item/${id}`;
|
||||||
|
},
|
||||||
|
showItemByUdi: function(udi) {
|
||||||
|
return `/api/show-item/udi/${udi}`;
|
||||||
},
|
},
|
||||||
showPackage: function(id) {
|
showPackage: function(id) {
|
||||||
return `/api/show-package/${id}`;
|
return `/api/show-package/${id}`;
|
||||||
@@ -17,7 +19,6 @@ const urls = {
|
|||||||
return `/ShowCycle/${id}`;
|
return `/ShowCycle/${id}`;
|
||||||
},
|
},
|
||||||
Barcode: function(code, type) {
|
Barcode: function(code, type) {
|
||||||
console.log(code, type,'aaa');
|
|
||||||
return `/BarCode/${code}/${type}`;
|
return `/BarCode/${code}/${type}`;
|
||||||
},
|
},
|
||||||
packageBarcode: function(code) {
|
packageBarcode: function(code) {
|
||||||
|
|||||||
Vendored
-1
@@ -30,7 +30,6 @@ function route (options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vue.use(Router)
|
Vue.use(Router)
|
||||||
console.log(paths);
|
|
||||||
// Create a new router
|
// Create a new router
|
||||||
const router = new Router({
|
const router = new Router({
|
||||||
mode: 'history',
|
mode: 'history',
|
||||||
|
|||||||
Vendored
+6
@@ -19,6 +19,12 @@ export default [
|
|||||||
view: 'Item/ShowItem',
|
view: 'Item/ShowItem',
|
||||||
meta: {public: true}
|
meta: {public: true}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/Show/UDI/:udi',
|
||||||
|
name: 'ShowItem',
|
||||||
|
view: 'Item/ShowItem',
|
||||||
|
meta: {public: true}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/Show/Package/:package',
|
path: '/Show/Package/:package',
|
||||||
name: 'ShowPackage',
|
name: 'ShowPackage',
|
||||||
|
|||||||
@@ -1,105 +1,158 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container grid-list-xs>
|
<v-container grid-list-xs>
|
||||||
<material-card color="black" title="Show Cycle">
|
<material-card color="black" title="Show Cycle">
|
||||||
<v-layout id="printMe" align-left justify-left wrap class="px-5 my-3">
|
<v-layout align-left justify-left wrap id="printMe" class="px-3 my-3">
|
||||||
<h3 class="ml-3">Cycle - {{ MedicalCenter }}</h3>
|
<h3 class="mt-0">
|
||||||
|
Cycle - {{ (data.user && data.user.medical_center) ? data.user.medical_center.name : "" }}
|
||||||
|
</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light">
|
<hr class="v-divider theme--light">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-flex xs12>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-layout row wrap class="">
|
||||||
<div class="WM-d-flex">
|
<v-flex xs12 sm6 md4>
|
||||||
|
<div>
|
||||||
<span class="title">Cycle ID :</span>
|
<span class="title">Cycle ID :</span>
|
||||||
<span class="headline ml-1" style="letter-spacing:0 !important">{{ data.id }}</span>
|
<span class="headline ml-1" style="letter-spacing:0 !important">{{ data.id }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-flex xs12 sm6 md4>
|
||||||
<div>
|
<div>
|
||||||
<span class="title">Sterilizer ID :</span>
|
<span class="title">Sterilizer ID :</span>
|
||||||
<span class="headline ml-1" style="letter-spacing:0 !important">{{ data.sterilizer_id }}</span>
|
<span class="headline ml-1"
|
||||||
|
style="letter-spacing:0 !important">{{ data.sterilizer_id }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-flex xs12 sm6 md4>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-user"></v-icon>
|
<v-icon class="WMi-user"/>
|
||||||
<span class="headline ml-2" style="letter-spacing:0 !important">{{ data.user ? data.user.name : '' }}</span>
|
<span class="headline ml-2"
|
||||||
|
style="letter-spacing:0 !important">{{ data.user ? data.user.name : '' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6 md4>
|
||||||
<v-flex xs12 md6 sm6>
|
<div>
|
||||||
<div class="WM-d-flex">
|
|
||||||
<span class="title">Cycle Number :</span>
|
<span class="title">Cycle Number :</span>
|
||||||
<span class="headline ml-2" style="letter-spacing:0 !important">{{ data.cycle_number }}</span>
|
<span class="headline ml-2"
|
||||||
|
style="letter-spacing:0 !important">{{ data.cycle_number }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-flex xs12 sm6 md4>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-Industry"></v-icon>
|
<v-icon class="WMi-Industry"/>
|
||||||
<span class="headline ml-2" style="letter-spacing:0 !important">{{ data.date }}</span>
|
<span class="headline ml-2" style="letter-spacing:0 !important">{{ data.date }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-flex xs12 sm6 md4>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-pencil"></v-icon>
|
<v-icon class="WMi-pencil"/>
|
||||||
<span class="headline ml-1" style="letter-spacing:0 !important">{{ data.note }}</span>
|
<span class="headline ml-1" style="letter-spacing:0 !important">{{ data.note }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
<v-layout align-left justify-left wrap class="px-5 my-3">
|
</v-flex>
|
||||||
<h3 class="ml-3">Barcode And QRCode Image</h3>
|
<v-flex xs12>
|
||||||
|
<v-layout row wrap class="my-3">
|
||||||
|
<h3 class="mt-0">Barcode And QRCode Image</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light">
|
<hr class="v-divider theme--light">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-layout row wrap class="align-center mt-3">
|
||||||
<v-flex xs12 md6 sm6 v-if="barcodeimg">
|
<v-flex xs12 md6 sm6 v-if="barcodeimg">
|
||||||
<img :src="barcodeimg" class="WM-Width-350"><br />
|
<img :src="barcodeimg" class="barcode-container"><br/>
|
||||||
<span>Cycle ID : {{ data.id }}</span>
|
<span>Cycle ID : {{ data.id }}</span>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
|
||||||
<v-layout row wrap class="ml-4">
|
<v-flex xs12 md6 sm6 v-if="QRCodeimg" class="WM-Align-R">
|
||||||
<v-flex xs12 md6 sm6 v-if="QRCodeimg">
|
<a :href="'https://www.cssd-doc.com/Show/Cycle/'+data.id+''" target="_blank">
|
||||||
<img :src="QRCodeimg" class="WM-Width-150">
|
<img :src="QRCodeimg" class="WM-Width-150">
|
||||||
|
</a>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
|
</v-flex>
|
||||||
</v-layout>
|
<v-flex xs12 v-if="data.labels && data.labels.length">
|
||||||
<v-layout align-left justify-left wrap class="px-5 my-3">
|
<v-layout row wrap class="my-3">
|
||||||
<h3 class="ml-3">Labels</h3>
|
<h3 class="mt-0">Labels</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light">
|
<hr class="v-divider theme--light">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
<v-layout row wrap>
|
||||||
<v-layout row wrap style="margin-left: 20px !important;">
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-expansion-panel class="WM-Panel" v-for="(label, key) in data.labels" :key="key">
|
<v-expansion-panel class="WM-Panel" v-for="(label, key) in data.labels" :key="key">
|
||||||
<v-expansion-panel-content>
|
<v-expansion-panel-content>
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<div>{{ label.id }} ({{ label.pivot.count }})</div>
|
<v-layout row wrap class="CSSD-font">
|
||||||
|
<span class="item-counter">{{ key + 1 }}</span>
|
||||||
|
|
||||||
|
<v-layout row wrap class="pl-2">
|
||||||
|
<v-flex xs12 sm6 md6>
|
||||||
|
<span class="sub-text">Label ID:</span>
|
||||||
|
{{label.id}}
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6 md6>
|
||||||
|
<span class="sub-text">Label Pivot counter:</span>
|
||||||
|
{{ label.pivot.count }}
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
</template>
|
</template>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-text> Package :
|
<v-card-text class="pa-0 pl-sm-3" v-if="label.package">
|
||||||
|
Package :
|
||||||
|
<template>
|
||||||
<v-expansion-panel class="WM-Panel">
|
<v-expansion-panel class="WM-Panel">
|
||||||
<v-expansion-panel-content>
|
<v-expansion-panel-content>
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<div>{{ label.package.name }} </div>
|
<v-layout row wrap class="CSSD-font">
|
||||||
|
<span class="item-counter">{{ key + 1 }}</span>
|
||||||
|
|
||||||
|
<v-layout row wrap class="pl-2">
|
||||||
|
<v-flex xs12 sm6 md6>
|
||||||
|
<span class="sub-text">Package ID:</span>
|
||||||
|
{{label.package.id}}
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6 md6>
|
||||||
|
<span class="sub-text">Package Name:</span>
|
||||||
|
{{ label.package.name }}
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
</template>
|
</template>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-text>note : {{ label.package.note }}</v-card-text>
|
<v-card-text class="pa-0 pl-sm-3">
|
||||||
<v-card-text>
|
note : {{label.package.note }}
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-text class="pa-0 pl-sm-3"
|
||||||
|
v-if="label.package && label.package.items && label.package.items.length">
|
||||||
Items :
|
Items :
|
||||||
<v-expansion-panel class="WM-Panel" v-for="item in label.package.items" :key="item.key">
|
<v-expansion-panel class="WM-Panel"
|
||||||
|
v-for="(item, key) in label.package.items"
|
||||||
|
:key="key">
|
||||||
<v-expansion-panel-content>
|
<v-expansion-panel-content>
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<div>{{ item.name }} ({{ item.pivot.count }})</div>
|
<v-layout row wrap class="CSSD-font">
|
||||||
|
<span class="item-counter">{{ key + 1 }}</span>
|
||||||
|
|
||||||
|
<v-layout row wrap class="pl-2">
|
||||||
|
<v-flex xs12 sm4 md4>
|
||||||
|
<span class="sub-text">Item ID:</span>
|
||||||
|
{{ item.id }}
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm4 md4>
|
||||||
|
<span class="sub-text">Item Name:</span>
|
||||||
|
{{ item.name }}
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm4 md4 class="WM-Align-R">
|
||||||
|
<span v-if="item.pivot">
|
||||||
|
({{ item.pivot.count }})
|
||||||
|
</span>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
</template>
|
</template>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-text>note : {{ item.note }}</v-card-text>
|
<v-card-text>note : {{ item.note }}
|
||||||
</v-card>
|
|
||||||
</v-expansion-panel-content>
|
|
||||||
</v-expansion-panel>
|
|
||||||
|
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-expansion-panel-content>
|
</v-expansion-panel-content>
|
||||||
@@ -109,9 +162,15 @@
|
|||||||
</v-expansion-panel-content>
|
</v-expansion-panel-content>
|
||||||
</v-expansion-panel>
|
</v-expansion-panel>
|
||||||
</template>
|
</template>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-expansion-panel-content>
|
||||||
|
</v-expansion-panel>
|
||||||
|
</template>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
|
|
||||||
|
|
||||||
<v-layout row wrap align-center justify-center style="text-align:center">
|
<v-layout row wrap align-center justify-center style="text-align:center">
|
||||||
<v-flex class xs12 md12 sm12>
|
<v-flex class xs12 md12 sm12>
|
||||||
@@ -137,6 +196,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {urls} from "@show/config/urls";
|
import {urls} from "@show/config/urls";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: () => ({
|
data: () => ({
|
||||||
data: {},
|
data: {},
|
||||||
@@ -209,3 +269,24 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.barcode-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 290px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-counter {
|
||||||
|
font-size: 44px;
|
||||||
|
opacity: .3;
|
||||||
|
font-family: 'Montserrat-Bold';
|
||||||
|
line-height: 44px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
color: #b7b7b7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-text {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light">
|
<hr class="v-divider theme--light">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-layout row wrap class="ml-4 align-center">
|
||||||
<v-flex xs12 md6 sm6>
|
<v-flex xs12 md6 sm6>
|
||||||
<div class>
|
<div class>
|
||||||
<span class="title CSSD-font">Item ID :</span>
|
<span class="title CSSD-font">Item ID :</span>
|
||||||
@@ -31,6 +31,14 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
|
<v-flex xs12 md6 sm6>
|
||||||
|
<div class>
|
||||||
|
<span class="title CSSD-font">UDI :</span>
|
||||||
|
<span class="headline ml-1 CSSD-font" style="letter-spacing:0 !important">
|
||||||
|
{{ data.udi }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</v-flex>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-flex xs12 md6 sm6>
|
||||||
<div class>
|
<div class>
|
||||||
<span class="title CSSD-font">Specific :</span>
|
<span class="title CSSD-font">Specific :</span>
|
||||||
@@ -55,21 +63,38 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
|
|
||||||
</v-layout>
|
</v-layout>
|
||||||
<v-layout align-left justify-left wrap class="my-3">
|
<v-layout align-left justify-left row wrap class="my-3" v-if="data.files && data.files.length">
|
||||||
|
<h3 class="CSSD-font">Image</h3>
|
||||||
|
<v-flex xs12>
|
||||||
|
<hr class="v-divider theme--light"/>
|
||||||
|
</v-flex>
|
||||||
|
<v-layout row wrap class="mt-3">
|
||||||
|
<v-flex xs6 md2 sm2 v-for="(file, key) in data.files" :key="key">
|
||||||
|
<template v-if="file.file_type == 'document'">
|
||||||
|
<a target="_blank" :href="'/'+file.thumbnail">
|
||||||
|
<v-icon class="mr-2 caption">fas fa-check</v-icon>
|
||||||
|
{{ file.file_name }}</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<img :src="file.thumbnail" style="width: 100%" @click="openLightbox(key)"/>
|
||||||
|
</template>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
|
<v-flex xs12></v-flex>
|
||||||
|
<v-layout align-left justify-left row wrap class="my-3">
|
||||||
<h3 class="ml-3 CSSD-font">Barcode And QRCode Image</h3>
|
<h3 class="ml-3 CSSD-font">Barcode And QRCode Image</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light">
|
<hr class="v-divider theme--light">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-layout row wrap class="ml-4 align-center mt-2">
|
||||||
<v-flex xs12 md6 sm6 v-if="barcodeimg">
|
<v-flex xs12 md6 sm6 v-if="barcodeimg">
|
||||||
<img :src="barcodeimg" class="WM-Width-350"><br/>
|
<img :src="barcodeimg" class="barcode-container"><br/>
|
||||||
<span class="CSSD-font">Item ID : {{ data.id }}</span>
|
<span class="CSSD-font">Item ID : {{ data.id }}</span>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
<v-flex xs12 md6 sm6 v-if="QRCodeimg" class="WM-Align-C">
|
||||||
<v-layout row wrap class="ml-4">
|
|
||||||
<v-flex xs12 md6 sm6 v-if="QRCodeimg">
|
|
||||||
<img :src="QRCodeimg" class="WM-Width-150">
|
<img :src="QRCodeimg" class="WM-Width-150">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
@@ -92,21 +117,40 @@
|
|||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</material-card>
|
</material-card>
|
||||||
|
<vue-image-lightbox
|
||||||
|
v-if="showLightbox"
|
||||||
|
:media="lightboxImages"
|
||||||
|
:index="lightboxIndex"
|
||||||
|
@close="showLightbox = false"
|
||||||
|
/>
|
||||||
</v-container>
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import {urls} from "@show/config/urls";
|
import {urls} from "@show/config/urls";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import toast from "@/services/global/toast.service";
|
||||||
|
import VueImageLightbox from "vue-image-lightbox";
|
||||||
|
import 'vue-image-lightbox/dist/vue-image-lightbox.min.css'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: () => ({
|
data: () => ({
|
||||||
data: {},
|
data: {},
|
||||||
QRCodeimg: '',
|
QRCodeimg: '',
|
||||||
barcodeimg: '',
|
barcodeimg: '',
|
||||||
MedicalCenter: ''
|
MedicalCenter: '',
|
||||||
|
showLightbox: false,
|
||||||
|
lightboxIndex: 0,
|
||||||
|
lightboxImages: [],
|
||||||
}),
|
}),
|
||||||
|
components: {
|
||||||
|
VueImageLightbox,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
imagesOnly() {
|
||||||
|
return this.data.files && this.data.files.length ? this.data.files.filter(file => file.file_type !== 'document') : [];
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async load(id) {
|
async load(id) {
|
||||||
try {
|
try {
|
||||||
@@ -114,7 +158,7 @@ export default {
|
|||||||
if (result.status == 200) {
|
if (result.status == 200) {
|
||||||
this.data = result.data.data;
|
this.data = result.data.data;
|
||||||
if (this.data) {
|
if (this.data) {
|
||||||
this.generateBarcode(this.data.id);
|
this.generateBarcode(this.data);
|
||||||
this.MedicalCenter = this.data.user.medical_center.name;
|
this.MedicalCenter = this.data.user.medical_center.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,13 +166,31 @@ export default {
|
|||||||
console.error("Error loading data:", error);
|
console.error("Error loading data:", error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async loadByUdi(udi) {
|
||||||
async generateBarcode(itemId) {
|
try {
|
||||||
const result = await axios.post(urls.Barcode(itemId, 'Item'));
|
const result = await axios.get(urls.showItemByUdi(udi));
|
||||||
|
if (result.status == 200) {
|
||||||
|
this.data = result.data.data;
|
||||||
|
if (this.data) {
|
||||||
|
this.generateBarcode(this.data);
|
||||||
|
this.MedicalCenter = this.data.user.medical_center.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error loading data:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async generateBarcode(item) {
|
||||||
|
let code = item.udi;
|
||||||
|
if (code) {
|
||||||
|
const result = await axios.post(urls.Barcode(code, 'Item'));
|
||||||
if (result && result.status == 200) {
|
if (result && result.status == 200) {
|
||||||
this.QRCodeimg = result.data.data.QRCode ? result.data.data.QRCode : null;
|
this.QRCodeimg = result.data.data.QRCode ? result.data.data.QRCode : null;
|
||||||
this.barcodeimg = result.data.data.Barcode ? result.data.data.Barcode : null;
|
this.barcodeimg = result.data.data.Barcode ? result.data.data.Barcode : null;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
toast.error('An error occurred while generating the barcode . please first set UDI');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
editItem(itemId) {
|
editItem(itemId) {
|
||||||
window.location.href = '/item/' + itemId + '/edit';
|
window.location.href = '/item/' + itemId + '/edit';
|
||||||
@@ -154,29 +216,38 @@ export default {
|
|||||||
"left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0"
|
"left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0"
|
||||||
);
|
);
|
||||||
|
|
||||||
WinPrint.document.write(`<!DOCTYPE html>
|
WinPrint.document.write(`<!DOCTYPE html><html><head>${stylesHtml}</head><body> ${prtHtml}</body></html>`);
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
${stylesHtml}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
${prtHtml}
|
|
||||||
</body>
|
|
||||||
</html>`);
|
|
||||||
|
|
||||||
WinPrint.document.close();
|
WinPrint.document.close();
|
||||||
WinPrint.focus();
|
WinPrint.focus();
|
||||||
WinPrint.print();
|
WinPrint.print();
|
||||||
WinPrint.close();
|
WinPrint.close();
|
||||||
|
},
|
||||||
|
openLightbox(index) {
|
||||||
|
this.lightboxIndex = index;
|
||||||
|
this.showLightbox = false;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.showLightbox = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.$route.params.item) {
|
if (this.$route.params.item) {
|
||||||
this.load(this.$route.params.item);
|
this.load(this.$route.params.item);
|
||||||
|
} else if (this.$route.params.udi) {
|
||||||
|
this.loadByUdi(this.$route.params.udi);
|
||||||
}
|
}
|
||||||
|
this.lightboxImages = this.imagesOnly && this.imagesOnly.length ? this.imagesOnly.map(file => ({
|
||||||
|
src: file.thumbnail,
|
||||||
|
thumb: file.thumbnail,
|
||||||
|
})) : [];
|
||||||
},
|
},
|
||||||
// mounted() {
|
|
||||||
// this.generateBarcode(this.data.id);
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.barcode-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 290px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-container grid-list-xs>
|
<v-container grid-list-xs>
|
||||||
<material-card color="black" title="Show Label">
|
<material-card color="black" title="Show Label">
|
||||||
@@ -13,60 +11,71 @@
|
|||||||
<!-- ________ row1::Begin ________ -->
|
<!-- ________ row1::Begin ________ -->
|
||||||
<v-layout row wrap>
|
<v-layout row wrap>
|
||||||
<!-- ________ Column1::Begin ________ -->
|
<!-- ________ Column1::Begin ________ -->
|
||||||
<v-flex xs6 md6 sm6>
|
<v-flex xs12 md6 sm6>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-layout row wrap class="">
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<span class="headline ml-1 mb-1" style="letter-spacing:0 !important">{{ MedicalCenter }}</span>
|
<span class="headline ml-1 mb-1" style="letter-spacing:0 !important">
|
||||||
|
{{ MedicalCenter }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12 class="">
|
<v-flex xs12 md12 sm12 class="">
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-location"></v-icon>
|
<v-icon class="WMi-location"/>
|
||||||
<span class="headline ml-1 mb-1" style="letter-spacing:0 !important" v-if="dataLoaded">{{data.package.name}}</span>
|
<span class="headline ml-1 mb-1" style="letter-spacing:0 !important"
|
||||||
|
v-if="dataLoaded">{{ data.package.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-Industry"></v-icon>
|
<v-icon class="WMi-Industry"/>
|
||||||
<span class="headline ml-2 mb-1" style="letter-spacing:0 !important">{{ data.sterile_date }}</span>
|
<span class="headline ml-2 mb-1"
|
||||||
|
style="letter-spacing:0 !important">{{ data.sterile_date }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-hourglass"></v-icon>
|
<v-icon class="WMi-hourglass"/>
|
||||||
<span class="headline ml-2 mb-1" style="letter-spacing:0 !important">{{ data.expire_date }}</span>
|
<span class="headline ml-2 mb-1"
|
||||||
|
style="letter-spacing:0 !important">{{ data.expire_date }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-user"></v-icon>
|
<v-icon class="WMi-user"/>
|
||||||
<span class="headline ml-2 mb-1" style="letter-spacing:0 !important">{{ data.user ? data.user.name : '' }}</span>
|
<span class="headline ml-2 mb-1" style="letter-spacing:0 !important">
|
||||||
|
{{ data.user ? data.user.name : '' }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<!-- ________ Column1::End ________ -->
|
<!-- ________ Column1::End ________ -->
|
||||||
<!-- ________ Column2::Begin ________ -->
|
<!-- ________ Column2::Begin ________ -->
|
||||||
<v-flex xs6 md6 sm6>
|
<v-flex xs12 md6 sm6>
|
||||||
<v-layout row wrap class="">
|
<v-layout row wrap class="mt-4">
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div>
|
<div>
|
||||||
<v-flex xs6 md6 sm6 v-if="QRCodeimg">
|
<v-flex xs6 md6 sm6 v-if="QRCodeimg">
|
||||||
<a :href="'/Show/Package/'+data.package.id+''" target="_blank"><img :src="QRCodeimg" class="WM-Width-120"></a>
|
<a :href="'/Show/Package/'+data.package.id+''" target="_blank">
|
||||||
|
<img :src="QRCodeimg" class="WM-Width-120">
|
||||||
|
</a>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class>
|
<div class>
|
||||||
<span class="title">Sterilizer ID :</span>
|
<span class="headline">Sterilizer ID :</span>
|
||||||
<span class="headline ml-1 mb-1" style="letter-spacing:0 !important">{{ data.sterilizer_id}}</span>
|
<span class="title ml-1 mb-1"
|
||||||
|
style="letter-spacing:0 !important">{{ data.sterilizer_id }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class>
|
<div class>
|
||||||
<span class="title">Cycle No :</span>
|
<span class="headline">Cycle No :</span>
|
||||||
<span class="headline ml-2 mb-1" style="letter-spacing:0 !important">{{ data.cycle_number }}</span>
|
<span class="title ml-2 mb-1"
|
||||||
|
style="letter-spacing:0 !important">{{ data.cycle_number }}</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
@@ -74,15 +83,14 @@
|
|||||||
<!-- ________ Column2::End ________ -->
|
<!-- ________ Column2::End ________ -->
|
||||||
</v-layout>
|
</v-layout>
|
||||||
<!-- ________ row1::Begin ________ -->
|
<!-- ________ row1::Begin ________ -->
|
||||||
|
|
||||||
|
|
||||||
<!-- ________ row2::Begin ________ -->
|
<!-- ________ row2::Begin ________ -->
|
||||||
<v-layout row wrap>
|
<v-layout row wrap>
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class="mt-4" style="text-align:center">
|
<div class="mt-4" style="text-align:center">
|
||||||
<v-layout row wrap>
|
<v-layout row wrap>
|
||||||
<v-flex xs6 md12 sm12 v-if="barcodeimg">
|
<v-flex xs12 md12 sm12 v-if="barcodeimg">
|
||||||
<img :src="barcodeimg" class="WM-Width-350"><br />
|
<img :src="barcodeimg" class="barcode-container"><br/>
|
||||||
|
<span class="WM-Font-14">Lebel ID :</span>
|
||||||
<span>{{ data.id }}</span>
|
<span>{{ data.id }}</span>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
@@ -90,28 +98,60 @@
|
|||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
<!-- ________ row2::End ________ -->
|
<!-- ________ row2::End ________ -->
|
||||||
</v-flex>
|
<v-layout wrap row v-if="dataLoaded">
|
||||||
</v-layout>
|
|
||||||
</v-layout>
|
|
||||||
<v-layout align-left justify-left wrap class="px-2 my-3" v-if="dataLoaded">
|
|
||||||
<h3 class="ml-3">Package</h3>
|
<h3 class="ml-3">Package</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light">
|
<hr class="v-divider theme--light">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="mx-3">
|
<v-layout row wrap class="mx-sm-3">
|
||||||
<template>
|
<template>
|
||||||
<v-expansion-panel class="WM-Panel">
|
<v-expansion-panel class="WM-Panel">
|
||||||
<v-expansion-panel-content>
|
<v-expansion-panel-content>
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<div>{{ data.package.name }}</div>
|
<v-layout row wrap class="CSSD-font">
|
||||||
|
<span class="item-counter">{{ key + 1 }}</span>
|
||||||
|
|
||||||
|
<v-layout row wrap class="pl-2">
|
||||||
|
<v-flex xs12 sm6 md6>
|
||||||
|
<span class="sub-text">Package ID:</span>
|
||||||
|
{{data.package.id}}
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm6 md6>
|
||||||
|
<span class="sub-text">Package Name:</span>
|
||||||
|
{{ data.package.name }}
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
</template>
|
</template>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-text>note : {{ data.package.note }}</v-card-text>
|
<v-card-text>note : {{ data.package.note }}</v-card-text>
|
||||||
<v-card-text> Items :
|
<v-card-text class="pa-0 pl-sm-3"
|
||||||
<v-expansion-panel class="WM-Panel" v-for="item in data.package.items" :key="item.key">
|
v-if="data.package && data.package.items && data.package.items.length">
|
||||||
|
Items :
|
||||||
|
<v-expansion-panel class="WM-Panel"
|
||||||
|
v-for="(item, key) in data.package.items"
|
||||||
|
:key="key">
|
||||||
<v-expansion-panel-content>
|
<v-expansion-panel-content>
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<div>{{ item.name }} <span v-if="item.pivot">({{ item.pivot.count }})</span></div>
|
<v-layout row wrap class="CSSD-font">
|
||||||
|
<span class="item-counter">{{ key + 1 }}</span>
|
||||||
|
|
||||||
|
<v-layout row wrap class="pl-2">
|
||||||
|
<v-flex xs12 sm4 md4>
|
||||||
|
<span class="sub-text">Item ID:</span>
|
||||||
|
{{ item.id }}
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm4 md4>
|
||||||
|
<span class="sub-text">Item Name:</span>
|
||||||
|
{{ item.name }}
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm4 md4 class="WM-Align-R">
|
||||||
|
<span v-if="item.pivot">
|
||||||
|
({{ item.pivot.count }})
|
||||||
|
</span>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
</template>
|
</template>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-text>note : {{ item.note }}</v-card-text>
|
<v-card-text>note : {{ item.note }}</v-card-text>
|
||||||
@@ -125,9 +165,13 @@
|
|||||||
</template>
|
</template>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
<v-layout row wrap align-center justify-center style="text-align:center">
|
<v-layout row wrap align-center justify-center style="text-align:center">
|
||||||
<v-flex class xs12 md12 sm12>
|
<v-flex class xs12 md12 sm12>
|
||||||
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black" @click="addLabel()">
|
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black" @click="goToAddLabel()">
|
||||||
<v-icon class="black--text">keyboard_arrow_left</v-icon>
|
<v-icon class="black--text">keyboard_arrow_left</v-icon>
|
||||||
<span class="black--text">Back</span>
|
<span class="black--text">Back</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
@@ -146,14 +190,10 @@
|
|||||||
</v-container>
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style media="screen">
|
|
||||||
.WM-d-flex{
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
<script>
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {urls} from "@show/config/urls";
|
import {urls} from "@show/config/urls";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: () => ({
|
data: () => ({
|
||||||
data: {},
|
data: {},
|
||||||
@@ -189,7 +229,7 @@ export default {
|
|||||||
editLabel(LabelId) {
|
editLabel(LabelId) {
|
||||||
window.location.href = '/label/' + LabelId + '/edit';
|
window.location.href = '/label/' + LabelId + '/edit';
|
||||||
},
|
},
|
||||||
addLabel(LabelId){
|
goToAddLabel(LabelId) {
|
||||||
window.location.href = '/add-label';
|
window.location.href = '/add-label';
|
||||||
},
|
},
|
||||||
print() {
|
print() {
|
||||||
@@ -234,3 +274,30 @@ export default {
|
|||||||
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style media="screen">
|
||||||
|
.WM-d-flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.barcode-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 290px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-counter {
|
||||||
|
font-size: 44px;
|
||||||
|
opacity: .3;
|
||||||
|
font-family: 'Montserrat-Bold';
|
||||||
|
line-height: 44px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
color: #b7b7b7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-text {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,74 +1,94 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container grid-list-xs>
|
<v-container grid-list-xs>
|
||||||
<material-card color="black" title="Show Package">
|
<material-card color="black" title="Show Package">
|
||||||
<v-layout id="printMe" align-left justify-left wrap class="px-5 my-3">
|
<v-layout id="printMe" align-left justify-left wrap class="px-3 mb-3">
|
||||||
<h3 class="ml-3 CSSD-font"> {{ data.name }} - MC {{ MedicalCenter }}</h3>
|
<h3 class="CSSD-font mt-0">
|
||||||
|
{{ data.name }} - MC
|
||||||
|
{{ (data.user != null && data.user.medical_center != null) ? data.user.medical_center.name : '' }}
|
||||||
|
</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light">
|
<hr class="v-divider theme--light">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-flex xs12>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-layout align-left justify-left wrap class="pt-3">
|
||||||
|
<v-flex xs12 sm4 md4>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-info"></v-icon>
|
<v-icon class="WMi-info"/>
|
||||||
<span class="headline ml-1 CSSD-font" style="letter-spacing:0 !important">
|
<span class="headline ml-1 CSSD-font" style="letter-spacing:0 !important">
|
||||||
{{ data.name }}
|
{{ data.name }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-flex xs12 sm4 md4>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-Industry"></v-icon>
|
<v-icon class="WMi-Industry"/>
|
||||||
<span class="headline ml-2 CSSD-font" style="letter-spacing:0 !important">
|
<span class="headline ml-2 CSSD-font" style="letter-spacing:0 !important">
|
||||||
{{ data.created_at }}
|
{{ data.created_at }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-flex xs12 sm4 md4>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-user"></v-icon>
|
<v-icon class="WMi-user"/>
|
||||||
<span class="headline ml-2 CSSD-font"
|
<span class="headline ml-2 CSSD-font" style="letter-spacing:0 !important">
|
||||||
style="letter-spacing:0 !important">{{ data.user ? data.user.name : '' }}</span>
|
{{ data.user ? data.user.name : '' }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md6 sm6>
|
<v-flex xs12 sm12 md12>
|
||||||
<div class="WM-d-flex">
|
<div class="WM-d-flex">
|
||||||
<v-icon class="WMi-pencil"></v-icon>
|
<v-icon class="WMi-pencil"/>
|
||||||
<span class="headline ml-1 CSSD-font" style="letter-spacing:0 !important">
|
<span class="headline ml-1 CSSD-font" style="letter-spacing:0 !important">
|
||||||
{{ data.note }}
|
{{ data.note }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
<v-layout align-left justify-left wrap class="px-5 my-3">
|
</v-flex>
|
||||||
<h3 class="ml-3 CSSD-font">Barcode And QRCode Image</h3>
|
<v-flex xs12>
|
||||||
|
<v-layout align-left justify-left wrap class="pt-3">
|
||||||
|
<h3 class="CSSD-font">Barcode And QRCode Image</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light">
|
<hr class="v-divider theme--light">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-layout row wrap class="align-center mt-2">
|
||||||
<v-flex xs12 md6 sm6 v-if="barcodeimg">
|
<v-flex xs12 md6 sm6 v-if="barcodeimg">
|
||||||
<img :src="barcodeimg" class="WM-Width-350"><br/>
|
<img :src="barcodeimg" class="barcode-container"><br/>
|
||||||
<span class="CSSD-font">Package ID : {{ data.id }}</span>
|
<span class="CSSD-font">Package ID : {{ data.id }}</span>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
<v-flex xs12 md6 sm6 v-if="QRCodeimg" class="WM-Align-R">
|
||||||
<v-layout row wrap class="ml-4">
|
<a :href="'https://www.cssd-doc.com/Show/Package/'+data.id+''" target="_blank">
|
||||||
<v-flex xs12 md6 sm6 v-if="QRCodeimg">
|
|
||||||
<img :src="QRCodeimg" class="WM-Width-150">
|
<img :src="QRCodeimg" class="WM-Width-150">
|
||||||
|
</a>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
|
</v-flex>
|
||||||
</v-layout>
|
<v-flex xs12>
|
||||||
<v-layout align-left justify-left wrap class="px-5 my-3">
|
<v-layout align-left justify-left wrap class="pt-3">
|
||||||
<h3 class="ml-3 CSSD-font">Items</h3>
|
<h3 class="CSSD-font mt-0">Items</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light">
|
<hr class="v-divider theme--light">
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-layout row wrap class="ml-sm-4 WM-Relative">
|
||||||
<template>
|
<template v-if="data.items && data.items.length">
|
||||||
<v-expansion-panel class="WM-Panel">
|
<v-expansion-panel class="WM-Panel">
|
||||||
<v-expansion-panel-content v-for="(item, key) in data.items" :key="key">
|
<v-expansion-panel-content v-for="(item, key) in data.items" :key="key">
|
||||||
<template v-slot:header>
|
<template v-slot:header>
|
||||||
<div>{{ key + 1 + ": " + item.name }} ({{ item.pivot.count }})</div>
|
<v-layout row wrap class="CSSD-font">
|
||||||
|
<span class="item-counter">{{ key + 1 }}</span>
|
||||||
|
<v-layout row wrap class="pl-2">
|
||||||
|
<v-flex xs12 sm4 md4>
|
||||||
|
<span class="sub-text">Item ID:</span> {{ item.id }}
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm4 md4>
|
||||||
|
<span class="sub-text">Item Name:</span> {{ item.name }}
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 sm4 md4 class="WM-Align-R">
|
||||||
|
<span v-if="item.pivot">({{ item.pivot.count }})</span>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
</template>
|
</template>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-text>note : {{ item.note }}</v-card-text>
|
<v-card-text>note : {{ item.note }}</v-card-text>
|
||||||
@@ -76,9 +96,14 @@
|
|||||||
</v-expansion-panel-content>
|
</v-expansion-panel-content>
|
||||||
</v-expansion-panel>
|
</v-expansion-panel>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<p class="mt-3" style="width: 100%;"> No Item Has Been Selected</p>
|
||||||
|
</template>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
</v-layout>
|
|
||||||
</v-layout>
|
|
||||||
<v-layout row wrap align-center justify-center style="text-align:center">
|
<v-layout row wrap align-center justify-center style="text-align:center">
|
||||||
<v-flex class xs12 md12 sm12>
|
<v-flex class xs12 md12 sm12>
|
||||||
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black" @click="addPackage()">
|
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Black" @click="addPackage()">
|
||||||
@@ -154,15 +179,7 @@ export default {
|
|||||||
"left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0"
|
"left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0"
|
||||||
);
|
);
|
||||||
|
|
||||||
WinPrint.document.write(`<!DOCTYPE html>
|
WinPrint.document.write(`<!DOCTYPE html><html><head>${stylesHtml} </head> <body>${prtHtml}</body></html>`);
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
${stylesHtml}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
${prtHtml}
|
|
||||||
</body>
|
|
||||||
</html>`);
|
|
||||||
|
|
||||||
WinPrint.document.close();
|
WinPrint.document.close();
|
||||||
WinPrint.focus();
|
WinPrint.focus();
|
||||||
@@ -178,3 +195,24 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.barcode-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 290px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-counter {
|
||||||
|
font-size: 44px;
|
||||||
|
opacity: .3;
|
||||||
|
font-family: 'Montserrat-Bold';
|
||||||
|
line-height: 44px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
color: #b7b7b7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub-text {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-container grid-list-xs>
|
<v-container grid-list-xs>
|
||||||
<material-card color="black" title="Show Test Result" id="printMe">
|
<material-card color="black" title="Show Test Result" id="printMe">
|
||||||
<v-layout align-left justify-left wrap class="my-3">
|
<v-layout align-left justify-left wrap class="my-3">
|
||||||
<h3 class="ml-3 CSSD-font">Test Type : {{ TestType }}</h3>
|
|
||||||
|
<h3 class="ml-4 CSSD-font" style="font-size: 18px!important;">
|
||||||
|
<span class="WM-Font-16">Test Type :</span>
|
||||||
|
<span class="font-weight-bold">{{ TestType }}</span>
|
||||||
|
</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light"/>
|
<hr class="v-divider theme--light"/>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
@@ -11,67 +14,56 @@
|
|||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class>
|
<div class>
|
||||||
<span class="title CSSD-font">{{ data.device_label || 'AutoclaveID' }} :</span>
|
<span class="title CSSD-font">{{ data.device_label || 'AutoclaveID' }} :</span>
|
||||||
<span
|
<span class="headline ml-2 CSSD-font" style="letter-spacing:0 !important">
|
||||||
class="headline ml-2 CSSD-font"
|
{{ data.device_id }}
|
||||||
style="letter-spacing:0 !important"
|
</span>
|
||||||
>{{ data.device_id }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12>
|
|
||||||
<div class>
|
<v-flex xs12 sm12 class="py-1">
|
||||||
<span class="title CSSD-font">Result :</span>
|
<span class="subtitle-1">Result :</span>
|
||||||
<span v-if="data.result === 'Reject'" class="NotVerified">
|
<v-icon size="20"
|
||||||
<v-icon class="caption fa fa-times NotVerified"></v-icon>
|
:class="['caption fa ml-2', data.result == 'Reject'?'NotVerified':( data.result == 'Accept'?'Verified':'')]">
|
||||||
|
{{ data.result == 'Reject' ? 'fa-times' : (data.result == 'Accept' ? 'fa-check' : '') }}
|
||||||
|
</v-icon>
|
||||||
|
<span class="headline ml-1 CSSD-font" style="letter-spacing:0 !important">
|
||||||
|
{{ data.result }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="data.result === 'Accept'" class="">
|
|
||||||
<v-icon class="caption fa fa-check Verified"></v-icon>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="headline ml-1 CSSD-font"
|
|
||||||
style="letter-spacing:0 !important"
|
|
||||||
>{{ data.result }}</span>
|
|
||||||
</div>
|
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class>
|
<div class>
|
||||||
<span class="title CSSD-font">verify :</span>
|
<span class="title CSSD-font">verify :</span>
|
||||||
<span v-if="data.verified === 'NotVerified'" class="NotVerified">
|
<v-icon size="20"
|
||||||
<v-icon class="caption fa fa-times NotVerified"></v-icon>
|
:class="['caption fa ml-2', data.verified == 'NotVerified'?'NotVerified':(data.verified == 'Verified'? 'Verified' : '')]">
|
||||||
|
{{ data.verified == 'NotVerified' ? 'fa-times' :(data.verified == 'Verified' ? 'fa-check':'') }}
|
||||||
|
</v-icon>
|
||||||
|
<span class="headline ml-1" style="letter-spacing:0 !important">
|
||||||
|
{{ data.verified }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="data.verified === 'Verified'" class="">
|
|
||||||
<v-icon class="caption fa fa-check Verified"></v-icon>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="headline ml-1"
|
|
||||||
style="letter-spacing:0 !important"
|
|
||||||
>{{ data.verified }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class>
|
<div class>
|
||||||
<span class="title CSSD-font">Register User :</span>
|
<span class="title CSSD-font">Register User :</span>
|
||||||
<span
|
<span class="headline ml-2 CSSD-font" style="letter-spacing:0 !important">
|
||||||
class="headline ml-2 CSSD-font"
|
{{ User }}
|
||||||
style="letter-spacing:0 !important"
|
</span>
|
||||||
>{{ User }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md12 sm12>
|
<v-flex xs12 md12 sm12>
|
||||||
<div class>
|
<div class>
|
||||||
<span class="title CSSD-font">Date :</span>
|
<span class="title CSSD-font">Date :</span>
|
||||||
<span
|
<span class="headline ml-2" style="letter-spacing:0 !important">
|
||||||
class="headline ml-2"
|
{{ data.created_at }}
|
||||||
style="letter-spacing:0 !important"
|
</span>
|
||||||
>{{ data.created_at }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md6 sm12>
|
<v-flex xs12 md6 sm12>
|
||||||
<div class>
|
<div class>
|
||||||
<span class="title CSSD-font">Medical Center :</span>
|
<span class="title CSSD-font">Medical Center :</span>
|
||||||
<span
|
<span class="headline ml-2 CSSD-font" style="letter-spacing:0 !important">
|
||||||
class="headline ml-2 CSSD-font"
|
{{ MedicalCenter }}
|
||||||
style="letter-spacing:0 !important"
|
</span>
|
||||||
>{{ MedicalCenter }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
@@ -83,56 +75,34 @@
|
|||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-layout row wrap class="ml-4">
|
||||||
<template v-if="data.inputs">
|
<template v-if="data.inputs">
|
||||||
<v-flex
|
<v-flex xs12 md12 sm12 v-for="(inputData, keyInputs) in data.inputs" :key="keyInputs">
|
||||||
xs12
|
|
||||||
md12
|
|
||||||
sm12
|
|
||||||
v-for="(inputData, keyInputs) in data.inputs"
|
|
||||||
:key="keyInputs"
|
|
||||||
>
|
|
||||||
<span class="title">{{ keyInputs }} :</span>
|
<span class="title">{{ keyInputs }} :</span>
|
||||||
<span
|
<span class="headline ml-2 CSSD-font" style="letter-spacing:0 !important">
|
||||||
class="headline ml-2 CSSD-font"
|
{{ inputData }}
|
||||||
style="letter-spacing:0 !important"
|
</span>
|
||||||
>{{inputData}}</span>
|
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="data.options">
|
<template v-if="data.options">
|
||||||
<v-flex
|
<v-flex xs12 md12 sm12 v-for="(optionData, keyOptions) in data.options" :key="keyOptions">
|
||||||
xs12
|
|
||||||
md12
|
|
||||||
sm12
|
|
||||||
v-for="(optionData, keyOptions) in data.options"
|
|
||||||
:key="keyOptions"
|
|
||||||
>
|
|
||||||
<span class="title CSSD-font">{{ keyOptions }} :</span>
|
<span class="title CSSD-font">{{ keyOptions }} :</span>
|
||||||
<span
|
<span style="letter-spacing:0 !important" class="headline ml-2 CSSD-font"
|
||||||
style="letter-spacing:0 !important"
|
v-for="(data, dataKey) in optionData" :key="dataKey">
|
||||||
class="headline ml-2 CSSD-font"
|
{{ data }},
|
||||||
v-for="(data, dataKey) in optionData"
|
</span>
|
||||||
:key="dataKey"
|
|
||||||
>{{data}},</span>
|
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="data.children">
|
<template v-if="data.children">
|
||||||
<v-flex class="mt-4 pb-4" style="border-left:3px solid #32c5d2;border-bottom:1px solid #ddd"
|
<v-flex class="mt-4 pb-4" style="border-left:3px solid #32c5d2;border-bottom:1px solid #ddd"
|
||||||
xs12
|
xs12 md12 sm12 v-for="(formData, keyForm) in data.children" :key="keyForm">
|
||||||
md12
|
|
||||||
sm12
|
|
||||||
v-for="(formData, keyForm) in data.children"
|
|
||||||
:key="keyForm"
|
|
||||||
>
|
|
||||||
<h3 class="ml-3 CSSD-font">{{ keyForm }}</h3>
|
<h3 class="ml-3 CSSD-font">{{ keyForm }}</h3>
|
||||||
<div v-for="(childData, keyChild) in formData" :key="keyChild">
|
<div v-for="(childData, keyChild) in formData" :key="keyChild">
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<span class="title CSSD-font">{{ keyChild }} :</span>
|
<span class="title CSSD-font">{{ keyChild }} :</span>
|
||||||
<template v-if="Array.isArray(childData)">
|
<template v-if="Array.isArray(childData)">
|
||||||
<span
|
<span style="letter-spacing:0 !important" class="headline ml-2 CSSD-font"
|
||||||
style="letter-spacing:0 !important"
|
v-for="(data, dataKey) in childData" :key="dataKey">
|
||||||
class="headline ml-2 CSSD-font"
|
{{ data }},
|
||||||
v-for="(data, dataKey) in childData"
|
</span>
|
||||||
:key="dataKey"
|
|
||||||
>{{data}},</span>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<span class="headline ml-2 CSSD-font">{{ childData }}</span>
|
<span class="headline ml-2 CSSD-font">{{ childData }}</span>
|
||||||
@@ -143,49 +113,88 @@
|
|||||||
</template>
|
</template>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
|
|
||||||
<v-layout align-left justify-left wrap class="my-3">
|
<v-layout align-left justify-left wrap class="my-3">
|
||||||
<h3 class="ml-3 CSSD-font">Image</h3>
|
<v-layout align-left justify-left wrap class="my-3" v-if="data.media && data.media.length">
|
||||||
|
<h3 class="CSSD-font">Image</h3>
|
||||||
<v-flex xs12>
|
<v-flex xs12>
|
||||||
<hr class="v-divider theme--light"/>
|
<hr class="v-divider theme--light"/>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-layout row wrap class="ml-4">
|
<v-layout row wrap class="align-center">
|
||||||
<v-flex xs6 md2 sm2 v-for="(file, key) in data.files" :key="key">
|
<v-flex xs6 md2 sm2 v-for="(file, key) in data.media" :key="key">
|
||||||
<template v-if="file.file_type == 'document'">
|
<template v-if="file.file_type == 'document'">
|
||||||
<a target="_blank" :href="'/'+file.path"><v-icon class="mr-2 caption">fas fa-check</v-icon>{{ file.file_name }}</a>
|
<a target="_blank" :href="'/'+file.original_url">
|
||||||
|
<v-icon class="mr-2 caption">fas fa-check</v-icon>
|
||||||
|
{{ file.file_name }}
|
||||||
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<img :src="'/'+file.path" style="width: 100%" />
|
<img :src="file.original_url" style="width: 100%" class="mx-2" @click="openLightbox(key)"/>
|
||||||
</template>
|
</template>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
|
<v-layout align-left justify-left wrap class="my-3">
|
||||||
|
<h3 class="ml-3 CSSD-font">Barcode And QRCode Image</h3>
|
||||||
|
<v-flex xs12>
|
||||||
|
<hr class="v-divider theme--light">
|
||||||
|
</v-flex>
|
||||||
|
<v-layout row wrap class="ml-4 align-center mt-2">
|
||||||
|
<v-flex xs12 md6 sm6 v-if="barcodeimg">
|
||||||
|
<img :src="barcodeimg" class="barcode-container" style="width: 100%;max-width: 300px;"><br/>
|
||||||
|
<span class="CSSD-font">Item ID : {{ data.id }}</span>
|
||||||
|
</v-flex>
|
||||||
|
<v-flex xs12 md6 sm6 v-if="QRCodeimg" class="WM-Align-C">
|
||||||
|
<img :src="QRCodeimg" class="WM-Width-150">
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
|
</v-layout>
|
||||||
<v-layout row wrap style="text-align:center">
|
<v-layout row wrap style="text-align:center">
|
||||||
<v-flex class xs12 md2 sm12>
|
<v-flex class xs12 md2 sm12>
|
||||||
<v-btn
|
<v-btn class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Gray" @click="print">
|
||||||
class="WM-NoShadow WM-Outline-Btn WM-Border WM-Border-Gray"
|
|
||||||
@click="print"
|
|
||||||
>
|
|
||||||
<v-icon class="black--text mr-2 caption">fas fa-print</v-icon>
|
<v-icon class="black--text mr-2 caption">fas fa-print</v-icon>
|
||||||
<span class="black--text">Print</span>
|
<span class="black--text">Print</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</material-card>
|
</material-card>
|
||||||
|
<vue-image-lightbox
|
||||||
|
v-if="showLightbox"
|
||||||
|
:media="lightboxImages"
|
||||||
|
:index="lightboxIndex"
|
||||||
|
@close="showLightbox = false"
|
||||||
|
/>
|
||||||
</v-container>
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapMutations } from "vuex";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import {urls} from "@show/config/urls";
|
import {urls} from "@show/config/urls";
|
||||||
|
import VueImageLightbox from 'vue-image-lightbox'
|
||||||
|
import 'vue-image-lightbox/dist/vue-image-lightbox.min.css'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: () => ({
|
data: () => ({
|
||||||
data: {},
|
data: {},
|
||||||
TestType: '',
|
TestType: '',
|
||||||
MedicalCenter: '',
|
MedicalCenter: '',
|
||||||
User : ''
|
User: '',
|
||||||
|
QRCodeimg: '',
|
||||||
|
barcodeimg: '',
|
||||||
|
showLightbox: false,
|
||||||
|
lightboxIndex: 0,
|
||||||
|
lightboxImages: [],
|
||||||
}),
|
}),
|
||||||
|
components: {
|
||||||
|
VueImageLightbox,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
imagesOnly() {
|
||||||
|
return this.data.media && this.data.media.length ? this.data.media.filter(file => file.mime_type !== 'document') : [];
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async load(id) {
|
async load(id) {
|
||||||
const result = await axios.get(urls.showTestResult(id));
|
const result = await axios.get(urls.showTestResult(id));
|
||||||
@@ -195,19 +204,25 @@ export default {
|
|||||||
this.TestType = result.data.data.test_type.name;
|
this.TestType = result.data.data.test_type.name;
|
||||||
this.MedicalCenter = result.data.data.user.medical_center.name;
|
this.MedicalCenter = result.data.data.user.medical_center.name;
|
||||||
this.User = this.data.user.name;
|
this.User = this.data.user.name;
|
||||||
|
if (this.data) {
|
||||||
|
this.generateBarcode(this.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async generateBarcode(item) {
|
||||||
|
const result = await axios.post(urls.Barcode(item.id, 'TestResult'));
|
||||||
|
if (result && result.status == 200) {
|
||||||
|
this.QRCodeimg = result.data.data.QRCode ? result.data.data.QRCode : null;
|
||||||
|
this.barcodeimg = result.data.data.Barcode ? result.data.data.Barcode : null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
print() {
|
print() {
|
||||||
const prtHtml = document.getElementById("printMe").innerHTML;
|
const prtHtml = document.getElementById("printMe").innerHTML;
|
||||||
|
|
||||||
// Get all stylesheets HTML
|
// Get all stylesheets HTML
|
||||||
let stylesHtml = "";
|
let stylesHtml = "";
|
||||||
for (const node of [
|
for (const node of [...document.querySelectorAll('link[rel="stylesheet"], style')])
|
||||||
...document.querySelectorAll('link[rel="stylesheet"], style')
|
{stylesHtml += node.outerHTML;}
|
||||||
]) {
|
|
||||||
stylesHtml += node.outerHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the print window
|
// Open the print window
|
||||||
const WinPrint = window.open(
|
const WinPrint = window.open(
|
||||||
@@ -216,26 +231,28 @@ export default {
|
|||||||
"left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0"
|
"left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0"
|
||||||
);
|
);
|
||||||
|
|
||||||
WinPrint.document.write(`<!DOCTYPE html>
|
WinPrint.document.write(`<!DOCTYPE html><html><head>${stylesHtml} </head><body>${prtHtml} </body></html>`);
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
${stylesHtml}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
${prtHtml}
|
|
||||||
</body>
|
|
||||||
</html>`);
|
|
||||||
|
|
||||||
WinPrint.document.close();
|
WinPrint.document.close();
|
||||||
WinPrint.focus();
|
WinPrint.focus();
|
||||||
WinPrint.print();
|
WinPrint.print();
|
||||||
WinPrint.close();
|
WinPrint.close();
|
||||||
|
},
|
||||||
|
openLightbox(index) {
|
||||||
|
this.lightboxIndex = index;
|
||||||
|
this.showLightbox = false;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.showLightbox = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (this.$route.params.id) {
|
if (this.$route.params.id) {
|
||||||
this.load(this.$route.params.id);
|
this.load(this.$route.params.id);
|
||||||
}
|
}
|
||||||
|
this.lightboxImages = this.imagesOnly && this.imagesOnly.length ? this.imagesOnly.map(file => ({
|
||||||
|
src: file.original_url,
|
||||||
|
thumb: file.original_url,
|
||||||
|
})) : [];
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,12 +23,12 @@
|
|||||||
></v-autocomplete>
|
></v-autocomplete>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
|
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
|
||||||
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
|
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"/>
|
||||||
<v-text-field class="py-3" v-model="filter.sterilizer_id" label="Sterilizer ID" color="black"></v-text-field>
|
<v-text-field class="py-3" v-model="filter.sterilizer_id" label="Sterilizer ID" color="black"/>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
|
<v-flex xs12 md3 sm3 class="WM-FlexCenter pl-3">
|
||||||
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"></v-icon>
|
<v-icon class="fas fa-sort-numeric-up mr-2 WM-Margin-B-8"/>
|
||||||
<v-text-field class="py-3" v-model="filter.cycle_number" label="Cycle Number" color="black"></v-text-field>
|
<v-text-field class="py-3" v-model="filter.cycle_number" label="Cycle Number" color="black"/>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
<v-flex xs12 md2 sm3>
|
<v-flex xs12 md2 sm3>
|
||||||
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="load()">
|
<v-btn class="WM-CyanBlueGradient-BG" style="padding:10px 60px" @click="load()">
|
||||||
@@ -78,8 +78,7 @@
|
|||||||
<router-link
|
<router-link
|
||||||
class="LinkBtn"
|
class="LinkBtn"
|
||||||
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
|
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
|
||||||
:to="{name: 'EditLabel', params: {label: item.id}}"
|
:to="{name: 'EditLabel', params: {label: item.id}}">
|
||||||
>
|
|
||||||
<v-btn v-bind="attrs" v-on="on" color="orange" class="mr-2">
|
<v-btn v-bind="attrs" v-on="on" color="orange" class="mr-2">
|
||||||
<v-icon class="white--text mr-1 caption">fas fa-pen</v-icon>
|
<v-icon class="white--text mr-1 caption">fas fa-pen</v-icon>
|
||||||
<span>Edit</span>
|
<span>Edit</span>
|
||||||
@@ -95,8 +94,7 @@
|
|||||||
color="pink"
|
color="pink"
|
||||||
class="WM-ActionButton mr-2"
|
class="WM-ActionButton mr-2"
|
||||||
@click="remove(item.id)"
|
@click="remove(item.id)"
|
||||||
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id"
|
v-if="$hasRole('Admin') || item.user_id == $store.state.user.id">
|
||||||
>
|
|
||||||
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
|
<v-icon class="white--text mr-2 caption">fas fa-times</v-icon>
|
||||||
<span>Remove</span>
|
<span>Remove</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
@@ -119,7 +117,7 @@
|
|||||||
</v-layout>
|
</v-layout>
|
||||||
<v-divider></v-divider>
|
<v-divider></v-divider>
|
||||||
<div class="text-xs-center" v-if="lastPage > 1">
|
<div class="text-xs-center" v-if="lastPage > 1">
|
||||||
<v-pagination color="black" v-model="currentPage" :length="lastPage" :total-visible="6"></v-pagination>
|
<v-pagination color="black" v-model="currentPage" :length="lastPage" :total-visible="6"/>
|
||||||
</div>
|
</div>
|
||||||
<v-layout row wrap align-center justify-center class="mt-3">
|
<v-layout row wrap align-center justify-center class="mt-3">
|
||||||
<router-link to="/dashboard">
|
<router-link to="/dashboard">
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'reset_password' => "کد فعالسازی شما: :activation_code
|
||||||
|
لغو ۱۱",
|
||||||
|
];
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'reset_password' => "کد فعالسازی شما: :activation_code
|
||||||
|
لغو ۱۱",
|
||||||
|
];
|
||||||
+7
-2
@@ -31,11 +31,11 @@ Route::group(['namespace' => 'Api'], function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Route::middleware('auth:api')->group(function () {
|
Route::middleware('auth:api')->group(function () {
|
||||||
Route::get('TestTypes/ListNames', [TestTypeController::class, 'listNames']);
|
Route::get('TestTypes/List', [TestTypeController::class, 'list']);
|
||||||
Route::post('/TestTypes/Barcode/{TestType}', [TestTypeController::class, 'generateBarcode']);
|
Route::post('/TestTypes/Barcode/{TestType}', [TestTypeController::class, 'generateBarcode']);
|
||||||
Route::resource('TestTypes', TestTypeController::class);
|
Route::resource('TestTypes', TestTypeController::class);
|
||||||
Route::resource('MedicalCenters', MedicalCenterController::class);
|
Route::resource('MedicalCenters', MedicalCenterController::class);
|
||||||
Route::post('/GetInputs', [TestTypeController::class, 'getInputs']);
|
Route::get('/GetInputs/{idOrCode}', [TestTypeController::class, 'getInputs']); // Route::post('/GetInputs', [TestTypeController::class, 'getInputs']) این بود قبلا
|
||||||
|
|
||||||
Route::get('/GetInfo', [UserController::class, 'getInfo']);
|
Route::get('/GetInfo', [UserController::class, 'getInfo']);
|
||||||
Route::get('Users/MedicalCenter/{MedicalCenter}', [UserController::class, 'getByMedicalCenter']);
|
Route::get('Users/MedicalCenter/{MedicalCenter}', [UserController::class, 'getByMedicalCenter']);
|
||||||
@@ -91,9 +91,14 @@ Route::middleware('auth:api')->group(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Route::get('/show-item/{Item}',[ItemController::class, 'show'])->middleware('guest');
|
Route::get('/show-item/{Item}',[ItemController::class, 'show'])->middleware('guest');
|
||||||
|
Route::get('/show-item/udi/{udi}',[ItemController::class, 'showUdi'])->middleware('guest');
|
||||||
Route::get('/show-package/{Package}',[PackageController::class, 'show'])->middleware('guest');
|
Route::get('/show-package/{Package}',[PackageController::class, 'show'])->middleware('guest');
|
||||||
Route::post('/BarCode/{Code}/{Type?}', [BarCodeController::class, 'generateBarcode']);
|
Route::post('/BarCode/{Code}/{Type?}', [BarCodeController::class, 'generateBarcode']);
|
||||||
Route::post('Package/Barcode/{Code}', [BarCodeController::class, 'generatePackageBarcode']);
|
Route::post('Package/Barcode/{Code}', [BarCodeController::class, 'generatePackageBarcode']);
|
||||||
Route::post('Package/QRCode/{Package}', [BarCodeController::class, 'generatePackageQRCode']);
|
Route::post('Package/QRCode/{Package}', [BarCodeController::class, 'generatePackageQRCode']);
|
||||||
|
|
||||||
Route::get('TestResults/{id}', [TestResultController::class, 'show']);
|
Route::get('TestResults/{id}', [TestResultController::class, 'show']);
|
||||||
|
|
||||||
|
Route::get('smstesting',function(){
|
||||||
|
dd(env('SMS_WEBSERVICE', ''),env('SMS_USERNAME', ''),env('SMS_PASSWORD', ''),env('SMS_FROM_NUMBER', ''));
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user