initial commit
This commit is contained in:
commit
6e65bc3a62
18
.editorconfig
Normal file
18
.editorconfig
Normal file
@ -0,0 +1,18 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
323
.eslintrc-auto-import.json
Normal file
323
.eslintrc-auto-import.json
Normal file
@ -0,0 +1,323 @@
|
||||
{
|
||||
"globals": {
|
||||
"Component": true,
|
||||
"ComponentPublicInstance": true,
|
||||
"ComputedRef": true,
|
||||
"EffectScope": true,
|
||||
"ExtractDefaultPropTypes": true,
|
||||
"ExtractPropTypes": true,
|
||||
"ExtractPublicPropTypes": true,
|
||||
"InjectionKey": true,
|
||||
"PropType": true,
|
||||
"Ref": true,
|
||||
"VNode": true,
|
||||
"WritableComputedRef": true,
|
||||
"acceptHMRUpdate": true,
|
||||
"asyncComputed": true,
|
||||
"autoResetRef": true,
|
||||
"computed": true,
|
||||
"computedAsync": true,
|
||||
"computedEager": true,
|
||||
"computedInject": true,
|
||||
"computedWithControl": true,
|
||||
"controlledComputed": true,
|
||||
"controlledRef": true,
|
||||
"createApp": true,
|
||||
"createEventHook": true,
|
||||
"createGenericProjection": true,
|
||||
"createGlobalState": true,
|
||||
"createInjectionState": true,
|
||||
"createPinia": true,
|
||||
"createProjection": true,
|
||||
"createReactiveFn": true,
|
||||
"createReusableTemplate": true,
|
||||
"createSharedComposable": true,
|
||||
"createTemplatePromise": true,
|
||||
"createUnrefFn": true,
|
||||
"customRef": true,
|
||||
"debouncedRef": true,
|
||||
"debouncedWatch": true,
|
||||
"defineAsyncComponent": true,
|
||||
"defineComponent": true,
|
||||
"defineStore": true,
|
||||
"eagerComputed": true,
|
||||
"effectScope": true,
|
||||
"extendRef": true,
|
||||
"getActivePinia": true,
|
||||
"getCurrentInstance": true,
|
||||
"getCurrentScope": true,
|
||||
"h": true,
|
||||
"ignorableWatch": true,
|
||||
"inject": true,
|
||||
"injectLocal": true,
|
||||
"isDefined": true,
|
||||
"isProxy": true,
|
||||
"isReactive": true,
|
||||
"isReadonly": true,
|
||||
"isRef": true,
|
||||
"logicAnd": true,
|
||||
"logicNot": true,
|
||||
"logicOr": true,
|
||||
"makeDestructurable": true,
|
||||
"mapActions": true,
|
||||
"mapGetters": true,
|
||||
"mapState": true,
|
||||
"mapStores": true,
|
||||
"mapWritableState": true,
|
||||
"markRaw": true,
|
||||
"nextTick": true,
|
||||
"onActivated": true,
|
||||
"onBeforeMount": true,
|
||||
"onBeforeRouteLeave": true,
|
||||
"onBeforeRouteUpdate": true,
|
||||
"onBeforeUnmount": true,
|
||||
"onBeforeUpdate": true,
|
||||
"onClickOutside": true,
|
||||
"onDeactivated": true,
|
||||
"onErrorCaptured": true,
|
||||
"onKeyStroke": true,
|
||||
"onLongPress": true,
|
||||
"onMounted": true,
|
||||
"onRenderTracked": true,
|
||||
"onRenderTriggered": true,
|
||||
"onScopeDispose": true,
|
||||
"onServerPrefetch": true,
|
||||
"onStartTyping": true,
|
||||
"onUnmounted": true,
|
||||
"onUpdated": true,
|
||||
"pausableWatch": true,
|
||||
"provide": true,
|
||||
"provideLocal": true,
|
||||
"reactify": true,
|
||||
"reactifyObject": true,
|
||||
"reactive": true,
|
||||
"reactiveComputed": true,
|
||||
"reactiveOmit": true,
|
||||
"reactivePick": true,
|
||||
"readonly": true,
|
||||
"ref": true,
|
||||
"refAutoReset": true,
|
||||
"refDebounced": true,
|
||||
"refDefault": true,
|
||||
"refThrottled": true,
|
||||
"refWithControl": true,
|
||||
"resolveComponent": true,
|
||||
"resolveRef": true,
|
||||
"resolveUnref": true,
|
||||
"setActivePinia": true,
|
||||
"setMapStoreSuffix": true,
|
||||
"shallowReactive": true,
|
||||
"shallowReadonly": true,
|
||||
"shallowRef": true,
|
||||
"storeToRefs": true,
|
||||
"syncRef": true,
|
||||
"syncRefs": true,
|
||||
"templateRef": true,
|
||||
"throttledRef": true,
|
||||
"throttledWatch": true,
|
||||
"toRaw": true,
|
||||
"toReactive": true,
|
||||
"toRef": true,
|
||||
"toRefs": true,
|
||||
"toValue": true,
|
||||
"triggerRef": true,
|
||||
"tryOnBeforeMount": true,
|
||||
"tryOnBeforeUnmount": true,
|
||||
"tryOnMounted": true,
|
||||
"tryOnScopeDispose": true,
|
||||
"tryOnUnmounted": true,
|
||||
"unref": true,
|
||||
"unrefElement": true,
|
||||
"until": true,
|
||||
"useAbs": true,
|
||||
"useActiveElement": true,
|
||||
"useAnimate": true,
|
||||
"useArrayDifference": true,
|
||||
"useArrayEvery": true,
|
||||
"useArrayFilter": true,
|
||||
"useArrayFind": true,
|
||||
"useArrayFindIndex": true,
|
||||
"useArrayFindLast": true,
|
||||
"useArrayIncludes": true,
|
||||
"useArrayJoin": true,
|
||||
"useArrayMap": true,
|
||||
"useArrayReduce": true,
|
||||
"useArraySome": true,
|
||||
"useArrayUnique": true,
|
||||
"useAsyncQueue": true,
|
||||
"useAsyncState": true,
|
||||
"useAttrs": true,
|
||||
"useAverage": true,
|
||||
"useBase64": true,
|
||||
"useBattery": true,
|
||||
"useBluetooth": true,
|
||||
"useBreakpoints": true,
|
||||
"useBroadcastChannel": true,
|
||||
"useBrowserLocation": true,
|
||||
"useCached": true,
|
||||
"useCeil": true,
|
||||
"useClamp": true,
|
||||
"useClipboard": true,
|
||||
"useClipboardItems": true,
|
||||
"useCloned": true,
|
||||
"useColorMode": true,
|
||||
"useConfirmDialog": true,
|
||||
"useCounter": true,
|
||||
"useCssModule": true,
|
||||
"useCssVar": true,
|
||||
"useCssVars": true,
|
||||
"useCurrentElement": true,
|
||||
"useCycleList": true,
|
||||
"useDark": true,
|
||||
"useDateFormat": true,
|
||||
"useDebounce": true,
|
||||
"useDebounceFn": true,
|
||||
"useDebouncedRefHistory": true,
|
||||
"useDeviceMotion": true,
|
||||
"useDeviceOrientation": true,
|
||||
"useDevicePixelRatio": true,
|
||||
"useDevicesList": true,
|
||||
"useDisplayMedia": true,
|
||||
"useDocumentVisibility": true,
|
||||
"useDraggable": true,
|
||||
"useDropZone": true,
|
||||
"useElementBounding": true,
|
||||
"useElementByPoint": true,
|
||||
"useElementHover": true,
|
||||
"useElementSize": true,
|
||||
"useElementVisibility": true,
|
||||
"useEventBus": true,
|
||||
"useEventListener": true,
|
||||
"useEventSource": true,
|
||||
"useEyeDropper": true,
|
||||
"useFavicon": true,
|
||||
"useFetch": true,
|
||||
"useFileDialog": true,
|
||||
"useFileSystemAccess": true,
|
||||
"useFloor": true,
|
||||
"useFocus": true,
|
||||
"useFocusWithin": true,
|
||||
"useFps": true,
|
||||
"useFullscreen": true,
|
||||
"useGamepad": true,
|
||||
"useGeolocation": true,
|
||||
"useIdle": true,
|
||||
"useImage": true,
|
||||
"useInfiniteScroll": true,
|
||||
"useIntersectionObserver": true,
|
||||
"useInterval": true,
|
||||
"useIntervalFn": true,
|
||||
"useKeyModifier": true,
|
||||
"useLastChanged": true,
|
||||
"useLink": true,
|
||||
"useLocalStorage": true,
|
||||
"useMagicKeys": true,
|
||||
"useManualRefHistory": true,
|
||||
"useMath": true,
|
||||
"useMax": true,
|
||||
"useMediaControls": true,
|
||||
"useMediaQuery": true,
|
||||
"useMemoize": true,
|
||||
"useMemory": true,
|
||||
"useMin": true,
|
||||
"useMounted": true,
|
||||
"useMouse": true,
|
||||
"useMouseInElement": true,
|
||||
"useMousePressed": true,
|
||||
"useMutationObserver": true,
|
||||
"useNavigatorLanguage": true,
|
||||
"useNetwork": true,
|
||||
"useNow": true,
|
||||
"useObjectUrl": true,
|
||||
"useOffsetPagination": true,
|
||||
"useOnline": true,
|
||||
"usePageLeave": true,
|
||||
"useParallax": true,
|
||||
"useParentElement": true,
|
||||
"usePerformanceObserver": true,
|
||||
"usePermission": true,
|
||||
"usePointer": true,
|
||||
"usePointerLock": true,
|
||||
"usePointerSwipe": true,
|
||||
"usePrecision": true,
|
||||
"usePreferredColorScheme": true,
|
||||
"usePreferredContrast": true,
|
||||
"usePreferredDark": true,
|
||||
"usePreferredLanguages": true,
|
||||
"usePreferredReducedMotion": true,
|
||||
"usePrevious": true,
|
||||
"useProjection": true,
|
||||
"useRafFn": true,
|
||||
"useRefHistory": true,
|
||||
"useResizeObserver": true,
|
||||
"useRound": true,
|
||||
"useRoute": true,
|
||||
"useRouter": true,
|
||||
"useScreenOrientation": true,
|
||||
"useScreenSafeArea": true,
|
||||
"useScriptTag": true,
|
||||
"useScroll": true,
|
||||
"useScrollLock": true,
|
||||
"useSessionStorage": true,
|
||||
"useShare": true,
|
||||
"useSlots": true,
|
||||
"useSorted": true,
|
||||
"useSpeechRecognition": true,
|
||||
"useSpeechSynthesis": true,
|
||||
"useStepper": true,
|
||||
"useStorage": true,
|
||||
"useStorageAsync": true,
|
||||
"useStyleTag": true,
|
||||
"useSum": true,
|
||||
"useSupported": true,
|
||||
"useSwipe": true,
|
||||
"useTemplateRefsList": true,
|
||||
"useTextDirection": true,
|
||||
"useTextSelection": true,
|
||||
"useTextareaAutosize": true,
|
||||
"useThrottle": true,
|
||||
"useThrottleFn": true,
|
||||
"useThrottledRefHistory": true,
|
||||
"useTimeAgo": true,
|
||||
"useTimeout": true,
|
||||
"useTimeoutFn": true,
|
||||
"useTimeoutPoll": true,
|
||||
"useTimestamp": true,
|
||||
"useTitle": true,
|
||||
"useToNumber": true,
|
||||
"useToString": true,
|
||||
"useToggle": true,
|
||||
"useTransition": true,
|
||||
"useTrunc": true,
|
||||
"useUrlSearchParams": true,
|
||||
"useUserMedia": true,
|
||||
"useVModel": true,
|
||||
"useVModels": true,
|
||||
"useVibrate": true,
|
||||
"useVirtualList": true,
|
||||
"useWakeLock": true,
|
||||
"useWebNotification": true,
|
||||
"useWebSocket": true,
|
||||
"useWebWorker": true,
|
||||
"useWebWorkerFn": true,
|
||||
"useWindowFocus": true,
|
||||
"useWindowScroll": true,
|
||||
"useWindowSize": true,
|
||||
"watch": true,
|
||||
"watchArray": true,
|
||||
"watchAtMost": true,
|
||||
"watchDebounced": true,
|
||||
"watchDeep": true,
|
||||
"watchEffect": true,
|
||||
"watchIgnorable": true,
|
||||
"watchImmediate": true,
|
||||
"watchOnce": true,
|
||||
"watchPausable": true,
|
||||
"watchPostEffect": true,
|
||||
"watchSyncEffect": true,
|
||||
"watchThrottled": true,
|
||||
"watchTriggerable": true,
|
||||
"watchWithFilter": true,
|
||||
"whenever": true
|
||||
}
|
||||
}
|
230
.eslintrc.js
Normal file
230
.eslintrc.js
Normal file
@ -0,0 +1,230 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
},
|
||||
extends: [
|
||||
'.eslintrc-auto-import.json',
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:promise/recommended',
|
||||
'plugin:sonarjs/recommended',
|
||||
|
||||
// 'plugin:unicorn/recommended',
|
||||
],
|
||||
parser: 'vue-eslint-parser',
|
||||
parserOptions: {
|
||||
ecmaVersion: 13,
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: [
|
||||
'vue',
|
||||
'regex',
|
||||
],
|
||||
ignorePatterns: ['resources/js/@iconify/*.js', 'node_modules', 'dist'],
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
|
||||
// indentation (Already present in TypeScript)
|
||||
'comma-spacing': ['error', { before: false, after: true }],
|
||||
'key-spacing': ['error', { afterColon: true }],
|
||||
|
||||
'vue/first-attribute-linebreak': ['error', {
|
||||
singleline: 'beside',
|
||||
multiline: 'below',
|
||||
}],
|
||||
|
||||
|
||||
// indentation (Already present in TypeScript)
|
||||
'indent': ['error', 2],
|
||||
|
||||
// Enforce trailing comma (Already present in TypeScript)
|
||||
'comma-dangle': ['error', 'always-multiline'],
|
||||
|
||||
// Enforce consistent spacing inside braces of object (Already present in TypeScript)
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
|
||||
// Disable max-len
|
||||
'max-len': 'off',
|
||||
|
||||
// we don't want it
|
||||
'semi': ['error', 'never'],
|
||||
|
||||
// add parens ony when required in arrow function
|
||||
'arrow-parens': ['error', 'as-needed'],
|
||||
|
||||
// add new line above comment
|
||||
'newline-before-return': 'error',
|
||||
|
||||
// add new line above comment
|
||||
'lines-around-comment': [
|
||||
'error',
|
||||
{
|
||||
beforeBlockComment: true,
|
||||
beforeLineComment: true,
|
||||
allowBlockStart: true,
|
||||
allowClassStart: true,
|
||||
allowObjectStart: true,
|
||||
allowArrayStart: true,
|
||||
},
|
||||
],
|
||||
|
||||
// Ignore _ as unused variable
|
||||
|
||||
'array-element-newline': ['error', 'consistent'],
|
||||
'array-bracket-newline': ['error', 'consistent'],
|
||||
|
||||
'vue/multi-word-component-names': 'off',
|
||||
|
||||
'padding-line-between-statements': [
|
||||
'error',
|
||||
{ blankLine: 'always', prev: 'expression', next: 'const' },
|
||||
{ blankLine: 'always', prev: 'const', next: 'expression' },
|
||||
{ blankLine: 'always', prev: 'multiline-const', next: '*' },
|
||||
{ blankLine: 'always', prev: '*', next: 'multiline-const' },
|
||||
],
|
||||
|
||||
// Plugin: eslint-plugin-import
|
||||
'import/prefer-default-export': 'off',
|
||||
'import/newline-after-import': ['error', { count: 1 }],
|
||||
'no-restricted-imports': ['error', 'vuetify/components'],
|
||||
|
||||
// For omitting extension for ts files
|
||||
'import/extensions': [
|
||||
'error',
|
||||
'ignorePackages',
|
||||
{
|
||||
js: 'never',
|
||||
jsx: 'never',
|
||||
ts: 'never',
|
||||
tsx: 'never',
|
||||
},
|
||||
],
|
||||
|
||||
// ignore virtual files
|
||||
'import/no-unresolved': [2, {
|
||||
ignore: [
|
||||
'~pages$',
|
||||
'virtual:generated-layouts',
|
||||
|
||||
// Ignore vite's ?raw imports
|
||||
'.*\?raw',
|
||||
],
|
||||
}],
|
||||
|
||||
// Thanks: https://stackoverflow.com/a/63961972/10796681
|
||||
'no-shadow': 'off',
|
||||
|
||||
|
||||
// Plugin: eslint-plugin-promise
|
||||
'promise/always-return': 'off',
|
||||
'promise/catch-or-return': 'off',
|
||||
|
||||
// ESLint plugin vue
|
||||
'vue/block-tag-newline': 'error',
|
||||
'vue/component-api-style': 'error',
|
||||
'vue/component-name-in-template-casing': ['error', 'PascalCase', { registeredComponentsOnly: false }],
|
||||
'vue/custom-event-name-casing': ['error', 'camelCase', {
|
||||
ignores: [
|
||||
'/^(click):[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?/',
|
||||
],
|
||||
}],
|
||||
'vue/define-macros-order': 'error',
|
||||
'vue/html-comment-content-newline': 'error',
|
||||
'vue/html-comment-content-spacing': 'error',
|
||||
'vue/html-comment-indent': 'error',
|
||||
'vue/match-component-file-name': 'error',
|
||||
'vue/no-child-content': 'error',
|
||||
'vue/require-default-prop': 'off',
|
||||
|
||||
// NOTE this rule only supported in SFC, Users of the unplugin-vue-define-options should disable that rule: https://github.com/vuejs/eslint-plugin-vue/issues/1886
|
||||
// 'vue/no-duplicate-attr-inheritance': 'error',
|
||||
'vue/no-empty-component-block': 'error',
|
||||
'vue/no-multiple-objects-in-class': 'error',
|
||||
'vue/no-reserved-component-names': 'error',
|
||||
'vue/no-template-target-blank': 'error',
|
||||
'vue/no-useless-mustaches': 'error',
|
||||
'vue/no-useless-v-bind': 'error',
|
||||
'vue/padding-line-between-blocks': 'error',
|
||||
'vue/prefer-separate-static-class': 'error',
|
||||
'vue/prefer-true-attribute-shorthand': 'error',
|
||||
'vue/v-on-function-call': 'error',
|
||||
'vue/no-restricted-class': ['error', '/^(p|m)(l|r)-/'],
|
||||
'vue/valid-v-slot': ['error', {
|
||||
allowModifiers: true,
|
||||
}],
|
||||
|
||||
// -- Extension Rules
|
||||
'vue/no-irregular-whitespace': 'error',
|
||||
'vue/template-curly-spacing': 'error',
|
||||
|
||||
// -- Sonarlint
|
||||
'sonarjs/no-duplicate-string': 'off',
|
||||
'sonarjs/no-nested-template-literals': 'off',
|
||||
|
||||
// -- Unicorn
|
||||
// 'unicorn/filename-case': 'off',
|
||||
// 'unicorn/prevent-abbreviations': ['error', {
|
||||
// replacements: {
|
||||
// props: false,
|
||||
// },
|
||||
// }],
|
||||
|
||||
// https://github.com/gmullerb/eslint-plugin-regex
|
||||
'regex/invalid': [
|
||||
'error',
|
||||
[
|
||||
{
|
||||
regex: '@/assets/images',
|
||||
replacement: '@images',
|
||||
message: 'Use \'@images\' path alias for image imports',
|
||||
},
|
||||
{
|
||||
regex: '@/styles',
|
||||
replacement: '@styles',
|
||||
message: 'Use \'@styles\' path alias for importing styles from \'resources/js/styles\'',
|
||||
},
|
||||
|
||||
// {
|
||||
// id: 'Disallow icon of icon library',
|
||||
// regex: 'tabler-\\w',
|
||||
// message: 'Only \'mdi\' icons are allowed',
|
||||
// },
|
||||
|
||||
{
|
||||
regex: '@core/\\w',
|
||||
message: 'You can\'t use @core when you are in @layouts module',
|
||||
files: {
|
||||
inspect: '@layouts/.*',
|
||||
},
|
||||
},
|
||||
{
|
||||
regex: 'useLayouts\\(',
|
||||
message: '`useLayouts` composable is only allowed in @layouts & @core directory. Please use `useThemeConfig` composable instead.',
|
||||
files: {
|
||||
inspect: '^(?!.*(@core|@layouts)).*',
|
||||
},
|
||||
},
|
||||
{
|
||||
regex: 'import axios from \'axios\'',
|
||||
replacement: 'import axios from \'@axios\'',
|
||||
message: 'Use axios instances created in \'resources/js/plugin/axios.js\' instead of unconfigured axios',
|
||||
files: {
|
||||
ignore: '^.*plugins/axios.js.*',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
// Ignore files
|
||||
'\.eslintrc\.js',
|
||||
],
|
||||
},
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
node: {
|
||||
extensions: ['.js', '.js', '.jsx', '.jsx', '.mjs', '.png', '.jpg'],
|
||||
}, alias: { 'extensions': ['.ts', '.js', '.tsx', '.jsx', '.mjs'], 'map': [["@", "./resources/js"], ["@core", "./resources/js/@core"], ["@layouts", "./resources/js/@layouts"], ["@images", "./resources/images/"], ["@styles", "./resources/styles/"], ["@configured-variables", "./resources/styles/variables/_template.scss"], ["@axios", "./resources/js/plugins/axios"], ["apexcharts", "node_modules/apexcharts-clevision"]] },
|
||||
},
|
||||
},
|
||||
}
|
11
.gitattributes
vendored
Normal file
11
.gitattributes
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
* text=auto eol=lf
|
||||
|
||||
*.blade.php diff=html
|
||||
*.css diff=css
|
||||
*.html diff=html
|
||||
*.md diff=markdown
|
||||
*.php diff=php
|
||||
|
||||
/.github export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
.styleci.yml export-ignore
|
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
node_modules
|
||||
/public/build
|
||||
/public/hot
|
||||
/public/storage
|
||||
vendor
|
||||
/storage/*.key
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.phpunit.result.cache
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
auth.json
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
/.fleet
|
||||
/.idea
|
||||
/.vscode
|
||||
/.phpunit.cache
|
||||
vendor/*
|
||||
.env copy
|
||||
jaasauth.key
|
||||
jaasauth.key.pub
|
34
.stylelintrc.json
Normal file
34
.stylelintrc.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"extends": [
|
||||
"stylelint-config-standard-scss",
|
||||
"stylelint-config-idiomatic-order"
|
||||
],
|
||||
"plugins": [
|
||||
"stylelint-use-logical-spec"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"**/*.scss"
|
||||
],
|
||||
"customSyntax": "postcss-scss"
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"**/*.vue"
|
||||
],
|
||||
"customSyntax": "postcss-html"
|
||||
}
|
||||
],
|
||||
"rules": {
|
||||
"max-line-length": [
|
||||
120,
|
||||
{
|
||||
"ignore": "comments"
|
||||
}
|
||||
],
|
||||
"liberty/use-logical-spec": true,
|
||||
"selector-class-pattern": null,
|
||||
"color-function-notation": null
|
||||
}
|
||||
}
|
66
README.md
Normal file
66
README.md
Normal file
@ -0,0 +1,66 @@
|
||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
||||
</p>
|
||||
|
||||
## About Laravel
|
||||
|
||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
||||
|
||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
||||
|
||||
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
||||
|
||||
## Learning Laravel
|
||||
|
||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
|
||||
|
||||
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
|
||||
|
||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
||||
|
||||
## Laravel Sponsors
|
||||
|
||||
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com).
|
||||
|
||||
### Premium Partners
|
||||
|
||||
- **[Vehikl](https://vehikl.com/)**
|
||||
- **[Tighten Co.](https://tighten.co)**
|
||||
- **[WebReinvent](https://webreinvent.com/)**
|
||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
||||
- **[64 Robots](https://64robots.com)**
|
||||
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
|
||||
- **[Cyber-Duck](https://cyber-duck.co.uk)**
|
||||
- **[DevSquad](https://devsquad.com/hire-laravel-developers)**
|
||||
- **[Jump24](https://jump24.co.uk)**
|
||||
- **[Redberry](https://redberry.international/laravel/)**
|
||||
- **[Active Logic](https://activelogic.com)**
|
||||
- **[byte5](https://byte5.de)**
|
||||
- **[OP.GG](https://op.gg)**
|
||||
|
||||
## Contributing
|
||||
|
||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
||||
|
||||
## Security Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
||||
|
||||
## License
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
51
_jaasauth.key
Normal file
51
_jaasauth.key
Normal file
@ -0,0 +1,51 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIJKQIBAAKCAgEAy097HDz6C7OD1P8dUW0ehu01L1FMz+TtdzruDVGNuzmUFkBK
|
||||
tX2BFJJtXB5AiR7fhHzH0rsHCI2iq1X6LpdNuoItzKvdG2yxGhQGOkONi2m1KxTQ
|
||||
Qh77+84mEyaS+PFm6e7Ppt/l/iGiySlo7k9nYmmLLoBEada6LOQvaeV6+MuO/pCk
|
||||
4zQEiIfr2LhpFZPVTxlzKl37phvZjj1+jFsaNtVnAZVOT15HQvcQWoSqXJ9B2wvw
|
||||
254JAAoJ705NY7wNVzzQT8NiTlt2OCyIbS1m6LAhXydQyZXlpDZCtOniScQF8VA6
|
||||
zKgY7WwtXRVNB1gbpLzaIaWOjOp6iufOAjduuG9Ccsh1icNqVxEHmqGdmJQGayBc
|
||||
qdWebRkT6rZK5Y0APU46hcdc8eRy05+eB8V13hr9nK9eY5PDoW4nJEM/ep6V68vO
|
||||
+mam9/L3EPBCb1WmFhdQrS5WTr4UC7kc12BCh67UHeZC065/m/mz2gDbkd3ch6Hr
|
||||
PmmKCWf64QHdG6LWhRFNEqSyLFHCiFTNu7mutPNJPBkBtBtCim8pAE1zGCDO6V/9
|
||||
yoc03VbVA/6y0qHDPcYiYrqUkoLKjqMdikFT4gH5xF8ClCJdPbLVBGeF4eBEyQkF
|
||||
z5g6fR3gPt/fXsLfAsLwjbq6mSjvxL3qj2Cq4i/yB4JJNHbAdwPI7uhBpw8CAwEA
|
||||
AQKCAgBi1jzPOYWFcrvALFWgZB/XEDIu0qM43d3jfK6FowP35MHtH0wydtTtn1Gy
|
||||
2rIc9vlKey7Zbzq4GcLe8GkzhTKwXODPAy32Sxy9xMZSRMzm3XjJfNDRlCaD/2/b
|
||||
F4GTrCePyh0AzxAMP2XXzV3JnKhx20ViUdDwcwcHE9dI79qcYLkfYEoIeh1KEmnB
|
||||
bcUITFoCniiyjAXudtOIprSCnzdbONtelasAQqD6GQnGN4BqjrGBP4jT+zv83OR/
|
||||
hd1xgtYpdtL+M8nytdv+6wdXrB6/OADBNWe82DZPYmGDecAchEMvUQWEwKN9qH1V
|
||||
JynPTDIEIBsbCFUIhGUWaiJoSXJ1MQ2jtaQ8dh7ap8l+3dd6epbc3HG5N5Dv6OZV
|
||||
ZuxhFgYD5jGqNuSWXbUJvpJJAdTFv9QhmBvxMdGEj52JLazQ50TTufZAYdG1Bfbo
|
||||
NotNO8RQBRyCwkM4ZU8KdM2tKpV1IJbVtwy4dgtAU6/sgJfsfWzc9aAZhJ82OQ82
|
||||
YSJgtDD8/8/E/iKammKU15xYCOmwgbS1hdDAJ1O5qAPLRaHlEpEJG4f/7lz0Fo3e
|
||||
qzizQeFudtDcCbWfv9O0Pl1gWNpjTPoFLKBUZarFYcc6OVSKbOoBQXsElGZ+1BX5
|
||||
/UNaYpzwxHK+afx0aulXZa8vVLhYGdhFgspv7/C4QMlal7ovoQKCAQEA7DtlggDw
|
||||
Z/2isCbNkXdZjUIgsIeCUrZXlxRHepqU/gQyk5S7CxGY+kdH+f8umEC/dEb7dxbq
|
||||
jMlnKLPaq9T6/a8aUHbjzwSGLrghId0E7QNq+rVyO9FKj9SyoIJWQ7eBWHFMNVgJ
|
||||
076fcizyyP1d0wbB5PdLtOsxilUjdugy91Tip3MTAJlQiSwcIiTN0UJRoXnQYyjS
|
||||
k067Jj5CJw1EaDkth/F0MYDpJryedbNjry0V6SGJ1ioGzjbAHZP99g0p4Lp0P0I/
|
||||
3zaGDqYeg4xwC27JamUIwfWMwPWIVWmvJYw6MCCAVdx40UAae4jezQZhElG1QN3F
|
||||
v/g98lcOJ8T/gwKCAQEA3FLVUv2hNm+v/G//j7JYNUNxhoDN1CQHzRfaaJMpvtlg
|
||||
/imY6cAzUuvQp+80CYRhwYkjrTn+0IJroVLRrmFqB4NBNlq8sce8n+1xWngG4HF2
|
||||
fHIG6+o0rTUY2SgqEpctHV5t8ZCCanT0cEFRNr1YzOOjU+ByErCwx9g0pzPC2hjA
|
||||
AjEgFnTnP/LE0ve9r9eQxXFBQ7KV74rlFAi0HFQQTWlA9z9x9OuiQ/FFi+VAQjm3
|
||||
bvWTOQ+sJ97CEQvz7ftx1+yImyCEjblh8zZKU1HE3v0pFc2g4jNtsMwhclftNlmq
|
||||
o7DBqjQ+bmU9sjXPRZNd53dhHK7wIAmQMHKXC3b4hQKCAQEAzFIjXepKBOfPiuRE
|
||||
8Qh1oEQN2iGaisfDwpx7poOFUp92z0bY8J3r3q1Ah+468t0tuviaD0r224Znf0Dw
|
||||
Zab03+5PqEDskOWs2UPRBGUSGZ3XLbk6cJp5DyY8ya9xxWg2q7Ry4cCf31EEv9A4
|
||||
vbbHK/qwQcXS6UxzsN4qqnHzgxEcaRCS4vW4Pqy0OKP0kIX37N5bayin2VlDbbRz
|
||||
qytCe5LY2rfwc9C32BVUSSE7mww340hq253F/R5F1E9oXSTNj941JXG7pOiX0pvD
|
||||
0KvrTTgpZai1hm1HrK2xmY6rOqKqwW2bEqh6pyH2xdqAOnzGAP5C8zPeEkg37B93
|
||||
0tYE2QKCAQEAn+9pd+MxoeiVofRTWiamrZOV14Os5rB5EUKdg4hAp4/5PsdHf3fM
|
||||
Sgdw4ldcOQRmSi2ZPmh5NzdVljgeii2g4G9BaYmYrJ1HqfidboTuyQLUdiX4LE1J
|
||||
i+qdbRYg5HnlgApKWS8D3O+lec+QeuIcki81IvAtHrAwxAGIx09lxRhuWaj7mBGo
|
||||
xN0gT90TT5B2QT2jmNcMzGTRQifHR0EmzGr5hAIEYTykABom2BTE/s4TAHM4OhXM
|
||||
bOzhh6pbmogK7imASMvkLVVDa2AfuDgFZ7Hynyc0AMBAgjTMmsqFIg0ZN9ZZ34op
|
||||
P84yaSlymxkM87fPQRkkqr0GdITabLIiWQKCAQAENsMr1kFIiS6dOo2xMNd26pfS
|
||||
dA/icV/stOqdqxjbULPQF5DIu+HHPbEkIZRcJXIxjRV6uuNLg2PG2UNZeqa2C6RE
|
||||
2vgwHXy0ost+YXaVtJv6jK4c56m6CBwiBIPO9mQQkZSKClX16KqTSqXLZj+h4RTH
|
||||
zM/Lwa/Arac2UT2CBI+h/wBEPJVflXbfMDfyUdRpA6XwXMuitjXiPSlhL7v0JrNA
|
||||
KksjJnKzyAEYHbxLEJbIiE/sQfjpsVPZt5h/OK1modHKIxdx4yQERQQN7Ql4AEn1
|
||||
+jReaD4P161rTRCrChpTf12zGoV7AqSoKpOlpMSCiPhCyYkE40yokihao+zw
|
||||
-----END RSA PRIVATE KEY-----
|
BIN
app/.DS_Store
vendored
Normal file
BIN
app/.DS_Store
vendored
Normal file
Binary file not shown.
357
app/Classes/Calendly.php
Normal file
357
app/Classes/Calendly.php
Normal file
@ -0,0 +1,357 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes;
|
||||
|
||||
use App\Models\Setting;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Calendly
|
||||
{
|
||||
|
||||
protected $clientId = "1SW4eLp_g-nFim1XOORcAh-2lH2H-dfUVCiB1tLpkvo";
|
||||
protected $clientSecret = "qXtkthnPxdCoHzVekWsgKr1QEH2q5nm5B3R81x6IG28";
|
||||
//protected $redirectUri = 'https://hgh.codelfi.com/calendly/redirect-code/';
|
||||
public function authUrl()
|
||||
{
|
||||
$url = 'https://auth.calendly.com/oauth/authorize';
|
||||
$url .= '?client_id=' . urlencode($this->clientId);
|
||||
$url .= '&response_type=code';
|
||||
$url .= '&redirect_uri=' . urlencode(route('redirectURI'));
|
||||
//$url .= '&redirect_uri=' . urlencode('https://app.example.com/calendly/redirect-code/');
|
||||
|
||||
return $url;
|
||||
}
|
||||
public function authorize($code)
|
||||
{
|
||||
$tokenUrl = 'https://auth.calendly.com/oauth/token';
|
||||
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
$response = $client->post($tokenUrl, [
|
||||
'form_params' => [
|
||||
'grant_type' => 'authorization_code',
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
'redirect_uri' => route("redirectURI"),
|
||||
//'redirect_uri' => 'https://app.example.com/calendly/redirect-code/',
|
||||
'code' => $code,
|
||||
],
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
],
|
||||
]);
|
||||
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
Log::info('Info from function authorize(): ', $data);
|
||||
$setting = Setting::find(1);
|
||||
$setting->calendly_access_token = $data['access_token'];
|
||||
$setting->calendly_refresh_token = $data['refresh_token'];
|
||||
$setting->save();
|
||||
Cache::forget('calendly_access_token');
|
||||
Cache::put('calendly_access_token', $data['access_token'], now()->addSeconds($data['expires_in']));
|
||||
|
||||
return [
|
||||
'access_token' => $data['access_token'],
|
||||
'refresh_token' => $data['refresh_token'],
|
||||
'token_type' => $data['token_type'],
|
||||
'expires_in' => $data['expires_in']
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
public function accessToken()
|
||||
{
|
||||
|
||||
if (Cache::has('calendly_access_token')) {
|
||||
return Cache::get('calendly_access_token');
|
||||
}
|
||||
|
||||
$setting = Setting::find(1);
|
||||
|
||||
$tokenUrl = 'https://auth.calendly.com/oauth/token';
|
||||
|
||||
$client = new Client();
|
||||
|
||||
$response = $client->post($tokenUrl, [
|
||||
'form_params' => [
|
||||
'grant_type' => 'refresh_token',
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
'refresh_token' => $setting->calendly_refresh_token,
|
||||
],
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
],
|
||||
]);
|
||||
|
||||
// Decode the response
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
Log::info('Info from function accessToken(): ', $data);
|
||||
// Store the new access token and refresh token in cache
|
||||
Cache::put('calendly_access_token', $data['access_token'], now()->addSeconds($data['expires_in']));
|
||||
|
||||
return $data['access_token'];
|
||||
}
|
||||
public function getUserUri()
|
||||
{
|
||||
// 1. Call the /users/me API to get user information
|
||||
$client = new Client();
|
||||
try {
|
||||
$response = $client->request('GET', 'https://api.calendly.com/users/me', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $this->accessToken(),
|
||||
'Content-Type' => 'application/json',
|
||||
]
|
||||
]);
|
||||
|
||||
$data = json_decode($response->getBody(), true);
|
||||
return $userUri = $data['resource']['uri'];
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public function eventTypes()
|
||||
{
|
||||
// 1. Call the /users/me API to get user information
|
||||
$client = new Client();
|
||||
$responseEvent = $client->request('GET', 'https://api.calendly.com/event_types?user=' . $this->getUserUri(), [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $this->accessToken(),
|
||||
'Content-Type' => 'application/json',
|
||||
]
|
||||
]);
|
||||
$dataEvent = json_decode($responseEvent->getBody(), true);
|
||||
return $dataEvent['collection'];
|
||||
}
|
||||
public function setEventUri($even_type_url)
|
||||
{
|
||||
$setting = Setting::find(1);
|
||||
$setting->event_type = $even_type_url;
|
||||
$setting->save();
|
||||
}
|
||||
public function resetEventUri()
|
||||
{
|
||||
$setting = Setting::find(1);
|
||||
$setting->event_type = null;
|
||||
$setting->calendly_access_token = null;
|
||||
$setting->calendly_refresh_token = null;
|
||||
|
||||
$setting->save();
|
||||
}
|
||||
function getAvailableDates($even_type_url, $month, $tz = "UTC")
|
||||
{
|
||||
|
||||
try {
|
||||
$availableTimes = [];
|
||||
|
||||
$date = Carbon::createFromDate(Carbon::now()->year, $month, 1, $tz);
|
||||
$date = $date->startOfMonth()->tz("UTC");
|
||||
$endMonthDate = Carbon::createFromDate(Carbon::now()->year, $month, 1, $tz);
|
||||
$endMonthDate = $endMonthDate->endOfMonth()->tz("UTC");
|
||||
|
||||
|
||||
while ($date < $endMonthDate) {
|
||||
$start_time = $date->startOfDay()->format('Y-m-d\T24:00:00.000000\Z');
|
||||
$end_time = $date->addDays(7)->endOfDay()->format('Y-m-d\T24:00:00.000000\Z');
|
||||
|
||||
|
||||
$client = new Client();
|
||||
try {
|
||||
|
||||
// Prepare API endpoint with the required parameters
|
||||
$eventTypeUrl = 'https://api.calendly.com/event_type_available_times';
|
||||
$queryParams = [
|
||||
'event_type' => $even_type_url,
|
||||
'start_time' => $start_time,
|
||||
'end_time' => $end_time
|
||||
];
|
||||
$str = "event_type=" . urlencode($queryParams['event_type']) . "&" . "start_time=" . urlencode($queryParams['start_time']) . "&" . "end_time=" . urlencode($queryParams['end_time']);
|
||||
$eventTypeUrl = $eventTypeUrl . "?" . ($str);
|
||||
// Send the request to Calendly
|
||||
$response = $client->request('GET', $eventTypeUrl, [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $this->accessToken(),
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
// 'query' => $queryParams
|
||||
]);
|
||||
|
||||
|
||||
$data = json_decode($response->getBody(), true);
|
||||
//$availableTimes += $data['collection'];
|
||||
foreach ($data['collection'] as $slot) {
|
||||
$slotDate = Carbon::parse($slot['start_time'])->tz($tz)->format('Y-m-d');
|
||||
if (!isset($availableTimes[$slotDate])) {
|
||||
$availableTimes[$slotDate] = [];
|
||||
}
|
||||
$slotDateTime = Carbon::parse($slot['start_time'])->tz($tz);
|
||||
$dateKey = $slotDateTime->format('Y-m-d');
|
||||
$slot['formatted_datetime'] = $slotDateTime->format('Y-m-d g:i:00');
|
||||
$availableTimes[$slotDate][] = $slot;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::error('Error from function getAvailableDates(): ' . $e->getMessage(), [
|
||||
'eventTypeUrl' => $eventTypeUrl,
|
||||
'queryParams' => $queryParams,
|
||||
'full_rul' => $eventTypeUrl,
|
||||
|
||||
'Authorization' => 'Bearer ' . $this->accessToken(),
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
$date->addSecond();
|
||||
}
|
||||
|
||||
return $availableTimes;
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => 'Failed to fetch available times: ' . $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// write function to do php get and post request and add json support
|
||||
function makeRequest($url, $method = 'GET', $data = [], $headers = [], $json = false, $proxy = "iproyal15202:pb86ljih495_country-us@geo.iproyal.com:12321")
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_ENCODING, '',);
|
||||
if ($proxy) {
|
||||
curl_setopt($ch, CURLOPT_PROXY, 'http://geo.iproyal.com:12321'); // Set the proxy address and port
|
||||
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'iproyal15202:Pb86ljiH495_country-us'); // Set the proxy authentication credentials
|
||||
}
|
||||
$headers = ['User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36', ...$headers];
|
||||
if ($method === 'POST') {
|
||||
|
||||
if ($json) {
|
||||
$headers = ['Content-Type: application/json', ...$headers];
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
||||
} else {
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
}
|
||||
}
|
||||
if (!empty($headers)) {
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
}
|
||||
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
function getCrfToken($url)
|
||||
{
|
||||
$response = $this->makeRequest($url);
|
||||
|
||||
// var_dump($response);
|
||||
//<meta name="csrf-token" content="mTW6eNk5xiDTzby7yHl_iVTO1_pi-CXZ2U9MYPcXGJGMpksW4iGLJniNxs-T4xrmYlLbXFaLuU8FZ75cuorz8w" />
|
||||
preg_match('/<meta name="csrf-token" content="(.*?)" \/>/', $response, $matches);
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
function getEventDetails($url)
|
||||
{
|
||||
$response = $this->makeRequest($url);
|
||||
return $response;
|
||||
}
|
||||
|
||||
//random string function
|
||||
function generateRandomString($length = 10)
|
||||
{
|
||||
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
$randomString = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$randomString .= $characters[rand(0, strlen($characters) - 1)];
|
||||
}
|
||||
return $randomString;
|
||||
}
|
||||
|
||||
|
||||
public function bookEvent($url, $name, $email, $timezone = "UTC")
|
||||
{
|
||||
$url_parts = explode("/", $url);
|
||||
$bookingDate = $url_parts[5];
|
||||
$event_type = $url_parts[4];
|
||||
$owner_id = $url_parts[3];
|
||||
$eventDetailsUrl = "https://calendly.com/api/booking/profiles/$owner_id/event_types/$event_type";
|
||||
$eventDetails = json_decode($this->makeRequest($eventDetailsUrl));
|
||||
// var_dump($eventDetails);
|
||||
$crfToken = $this->getCrfToken($url);
|
||||
|
||||
$eventUuid = $eventDetails->uuid;
|
||||
$link_uuid = $eventDetails->scheduling_link->uid;
|
||||
$custom_fields_id = $eventDetails->custom_fields[0]->id;
|
||||
$booking_request_id = urlencode($this->generateRandomString(36) . "|$bookingDate|$eventUuid|$name");
|
||||
//convert to php array
|
||||
$bookingData = [
|
||||
"analytics" => [
|
||||
//php date with 10 sec gap
|
||||
"invitee_landed_at" => date("Y-m-d\TH:i:s.uP", strtotime($bookingDate) - 200),
|
||||
"browser" => "Chrome 129",
|
||||
"device" => "undefined Mac OS X 10.15.7",
|
||||
"fields_filled" => 1,
|
||||
"fields_presented" => 1,
|
||||
"booking_flow" => "v3",
|
||||
"seconds_to_convert" => 200
|
||||
],
|
||||
"embed" => [],
|
||||
"event" => [
|
||||
"start_time" => $bookingDate,
|
||||
"location_configuration" => [
|
||||
"location" => "",
|
||||
"phone_number" => "",
|
||||
"additional_info" => ""
|
||||
],
|
||||
"guests" => []
|
||||
],
|
||||
"event_fields" => [
|
||||
[
|
||||
"id" => $custom_fields_id,
|
||||
"name" => "Please share anything that will help prepare for our meeting.",
|
||||
"format" => "text",
|
||||
"required" => false,
|
||||
"position" => 0,
|
||||
"answer_choices" => null,
|
||||
"include_other" => false,
|
||||
"value" => ""
|
||||
]
|
||||
],
|
||||
"invitee" => [
|
||||
"timezone" => $timezone,
|
||||
"time_notation" => "24h",
|
||||
"full_name" => $name,
|
||||
"email" => $email
|
||||
],
|
||||
"payment_token" => [],
|
||||
"tracking" => [
|
||||
"fingerprint" => $this->generateRandomString(32)
|
||||
],
|
||||
"scheduling_link_uuid" => $link_uuid,
|
||||
"locale" => "en",
|
||||
"verification_code" => null,
|
||||
"remember_device" => false
|
||||
];
|
||||
|
||||
|
||||
$response = $this->makeRequest("https://calendly.com/api/booking/invitees", 'POST', $bookingData, [
|
||||
'x-csrf-token: ' . $crfToken,
|
||||
'x-page-rendered-at: ' . date('Y-m-d\TH:i:s'),
|
||||
'x-requested-with: XMLHttpRequest',
|
||||
'referer: ' . $url,
|
||||
"booking-request-id: $booking_request_id"
|
||||
], true);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
49
app/Classes/Constant.php
Normal file
49
app/Classes/Constant.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes;
|
||||
|
||||
class Constant
|
||||
{
|
||||
static function getFullSql($query)
|
||||
{
|
||||
$sqlStr = $query->toSql();
|
||||
foreach ($query->getBindings() as $iter => $binding) {
|
||||
|
||||
$type = gettype($binding);
|
||||
switch ($type) {
|
||||
case "integer":
|
||||
case "double":
|
||||
$bindingStr = "$binding";
|
||||
break;
|
||||
case "string":
|
||||
$bindingStr = "'$binding'";
|
||||
break;
|
||||
case "object":
|
||||
$class = get_class($binding);
|
||||
switch ($class) {
|
||||
case "DateTime":
|
||||
$bindingStr = "'" . $binding->format('Y-m-d H:i:s') . "'";
|
||||
break;
|
||||
default:
|
||||
throw new \Exception("Unexpected binding argument class ($class)");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new \Exception("Unexpected binding argument type ($type)");
|
||||
}
|
||||
|
||||
$currentPos = strpos($sqlStr, '?');
|
||||
if ($currentPos === false) {
|
||||
throw new \Exception("Cannot find binding location in Sql String for bundung parameter $binding ($iter)");
|
||||
}
|
||||
|
||||
$sqlStr = substr($sqlStr, 0, $currentPos) . $bindingStr . substr($sqlStr, $currentPos + 1);
|
||||
}
|
||||
|
||||
$search = ["select", "distinct", "from", "where", "and", "order by", "asc", "desc", "inner join", "join"];
|
||||
$replace = ["SELECT", "DISTINCT", "\n FROM", "\n WHERE", "\n AND", "\n ORDER BY", "ASC", "DESC", "\n INNER JOIN", "\n JOIN"];
|
||||
$sqlStr = str_replace($search, $replace, $sqlStr);
|
||||
|
||||
return $sqlStr;
|
||||
}
|
||||
}
|
84
app/Classes/JassJWT.php
Normal file
84
app/Classes/JassJWT.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes;
|
||||
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Jose\Component\Core\AlgorithmManager;
|
||||
use Jose\Component\Core\JWK;
|
||||
use Jose\Component\Signature\Algorithm\RS256;
|
||||
use Jose\Component\Signature\JWSBuilder;
|
||||
use Jose\Component\KeyManagement\JWKFactory;
|
||||
use Jose\Component\Signature\Serializer\CompactSerializer;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class JassJWT
|
||||
{
|
||||
public static function generate()
|
||||
{
|
||||
$API_KEY = env('JASS_API_KEY');
|
||||
$APP_ID = env('JASS_APP_ID');
|
||||
$USER_EMAIL = env('JASS_USER_EMAIL');
|
||||
$USER_NAME = "Telemed Pro";
|
||||
$USER_IS_MODERATOR = true;
|
||||
$USER_AVATAR_URL = "";
|
||||
$USER_ID = uuid_create(UUID_TYPE_RANDOM);
|
||||
$LIVESTREAMING_IS_ENABLED = false;
|
||||
$RECORDING_IS_ENABLED = true;
|
||||
$OUTBOUND_IS_ENABLED = false;
|
||||
$TRANSCRIPTION_IS_ENABLED = false;
|
||||
$EXP_DELAY_SEC = 7200;
|
||||
$NBF_DELAY_SEC = 10;
|
||||
|
||||
$file = App::basePath('jaasauth.key');
|
||||
$jwk = JWKFactory::createFromKeyFile($file);
|
||||
|
||||
|
||||
$algorithm = new AlgorithmManager([
|
||||
new RS256()
|
||||
]);
|
||||
|
||||
|
||||
$jwsBuilder = new JWSBuilder($algorithm);
|
||||
|
||||
|
||||
$payload = json_encode([
|
||||
'iss' => 'chat',
|
||||
'aud' => 'jitsi',
|
||||
'exp' => time() + $EXP_DELAY_SEC,
|
||||
'nbf' => time() - $NBF_DELAY_SEC,
|
||||
'room' => "*",
|
||||
'sub' => $APP_ID,
|
||||
'context' => [
|
||||
'user' => [
|
||||
'moderator' => $USER_IS_MODERATOR ? "true" : "false",
|
||||
'email' => $USER_EMAIL,
|
||||
'name' => $USER_NAME,
|
||||
'avatar' => $USER_AVATAR_URL,
|
||||
'id' => $USER_ID
|
||||
],
|
||||
'features' => [
|
||||
'recording' => $RECORDING_IS_ENABLED ? "true" : "false",
|
||||
'livestreaming' => $LIVESTREAMING_IS_ENABLED ? "true" : "false",
|
||||
'transcription' => $TRANSCRIPTION_IS_ENABLED ? "true" : "false",
|
||||
'outbound-call' => $OUTBOUND_IS_ENABLED ? "true" : "false"
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
|
||||
$jws = $jwsBuilder
|
||||
->create()
|
||||
->withPayload($payload)
|
||||
->addSignature($jwk, [
|
||||
'alg' => 'RS256',
|
||||
'kid' => $API_KEY,
|
||||
'typ' => 'JWT'
|
||||
])
|
||||
->build();
|
||||
|
||||
|
||||
$serializer = new CompactSerializer();
|
||||
$token = $serializer->serialize($jws, 0);
|
||||
return $token;
|
||||
}
|
||||
}
|
BIN
app/Console/.DS_Store
vendored
Normal file
BIN
app/Console/.DS_Store
vendored
Normal file
Binary file not shown.
216
app/Console/Commands/InsertDataForApp.php
Normal file
216
app/Console/Commands/InsertDataForApp.php
Normal file
@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\LabKit;
|
||||
use App\Models\Telemedpro;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPlan;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Models\PlanV1;
|
||||
use App\Models\Prescription;
|
||||
use App\Models\ProfileCategory;
|
||||
use App\Models\QuestionBuilder;
|
||||
use Illuminate\Support\Str;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Faker\Factory as Faker;
|
||||
|
||||
class InsertDataForApp extends Command
|
||||
{
|
||||
protected $signature = 'insert:data';
|
||||
|
||||
protected $description = 'Insert plans data into the database based on the provided type';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
/* for ($i = 0; $i < 10; $i++) {
|
||||
Telemedpro::create([
|
||||
'name' => 'Telemedpro ' . ($i + 1),
|
||||
'email' => 'telemedpro' . ($i + 1) . '@example.com',
|
||||
'phone' => '123-456-789' . $i,
|
||||
]);
|
||||
} */
|
||||
|
||||
$faker = Faker::create();
|
||||
|
||||
for ($i = 500; $i < 800; $i++) {
|
||||
$patient = Patient::create([
|
||||
'first_name' => $faker->firstName,
|
||||
'last_name' => $faker->lastName,
|
||||
'email' => $faker->unique()->safeEmail,
|
||||
'phone' => $faker->phoneNumber,
|
||||
'password' => bcrypt("12345"),
|
||||
'address' => $faker->address,
|
||||
'city' => $faker->city,
|
||||
'state' => $faker->state,
|
||||
'zip_code' => $faker->postcode,
|
||||
'lat' => $faker->latitude,
|
||||
'long' => $faker->longitude,
|
||||
'dob' => $faker->date($format = 'Y-m-d', $max = 'now'),
|
||||
'recording_switch' => $faker->boolean,
|
||||
'country' => $faker->country,
|
||||
'phone_no' => $faker->phoneNumber,
|
||||
'shipping_address' => $faker->address,
|
||||
'shipping_city' => $faker->city,
|
||||
'shipping_state' => $faker->state,
|
||||
'shipping_country' => $faker->country,
|
||||
'shipping_zipcode' => $faker->postcode,
|
||||
'timezone' => 'UTC',
|
||||
'gender' => $faker->randomElement(['male', 'female']),
|
||||
'marital_status' => $faker->randomElement(['single', 'married']),
|
||||
'height' => $faker->numberBetween(150, 200), // Height in cm
|
||||
'weight' => $faker->numberBetween(50, 100) // Weight in kg
|
||||
]);
|
||||
|
||||
PatientRegActivity::create([
|
||||
'patient_id' => $patient->id,
|
||||
'activity' => 'patient_registered'
|
||||
]);
|
||||
$plans = PlanV1::all();
|
||||
PatientPlan::create([
|
||||
'patient_id' => $patient->id,
|
||||
'plan_id' => $plans->random()->id,
|
||||
]);
|
||||
/* } */
|
||||
|
||||
$telemedpros = Telemedpro::all();
|
||||
#$patients = Patient::all();
|
||||
|
||||
|
||||
/* for ($i = 0; $i < 50; $i++) { */
|
||||
$telemedpro = $telemedpros->random();
|
||||
#$patient = $patients->random();
|
||||
#$appointmentTime = Carbon::now()->addDays(rand(0, 30))->addHours(rand(0, 23))->addMinutes(rand(0, 59));
|
||||
$appointmentTime = Carbon::now()->subMonth()->addDays(rand(0, 30))->addHours(rand(0, 23))->addMinutes(rand(0, 59));
|
||||
$duration = rand(15, 120); // Duration between 15 minutes to 2 hours
|
||||
$startTime = $appointmentTime;
|
||||
$endTime = $startTime->copy()->addMinutes($duration);
|
||||
|
||||
$appointment = Appointment::create([
|
||||
'telemed_pros_id' => $telemedpro->id,
|
||||
'patient_id' => $patient->id,
|
||||
'appointment_time' => $appointmentTime->toDateTimeString(),
|
||||
'in_call' => rand(0, 1),
|
||||
'meeting_id' => Str::uuid(),
|
||||
'agent_call_token' => Str::random(20),
|
||||
'patient_call_token' => Str::random(20),
|
||||
'video_token' => Str::random(20),
|
||||
'appointment_date' => $appointmentTime->toDateString(),
|
||||
'patient_email' => $patient->email,
|
||||
'patient_name' => $patient->name,
|
||||
'timezone' => 'UTC',
|
||||
'analytics' => json_encode(['metric1' => rand(0, 100), 'metric2' => rand(0, 100)]),
|
||||
'start_time' => $startTime->toDateTimeString(),
|
||||
'end_time' => $endTime->toDateTimeString(),
|
||||
'duration' => $duration
|
||||
]);
|
||||
$statusOptions = ['delivered', 'pending'];
|
||||
|
||||
$labkit = LabKit::inRandomOrder()->first();
|
||||
$cart = new Cart();
|
||||
$cart->lab_kit_id = $labkit->id;
|
||||
$cart->first_name = $patient->first_name;
|
||||
$cart->last_name = $patient->last_name;
|
||||
$cart->email = $patient->email;
|
||||
$cart->phone = $patient->phone;
|
||||
$cart->status = $statusOptions[array_rand($statusOptions)];
|
||||
$cart->date_of_birth = $patient->dob;
|
||||
$cart->patient_id = $patient->id;
|
||||
$cart->shipping_address1 = $faker->streetAddress;
|
||||
$cart->shipping_address2 = $faker->secondaryAddress;
|
||||
$cart->shipping_city = $faker->city;
|
||||
$cart->shipping_state = $faker->state;
|
||||
$cart->shipping_zipcode = $faker->postcode;
|
||||
$cart->shipping_country = $faker->country;
|
||||
$cart->billing_address1 = $faker->streetAddress;
|
||||
$cart->billing_address2 = $faker->secondaryAddress;
|
||||
$cart->billing_city = $faker->city;
|
||||
$cart->billing_state = $faker->state;
|
||||
$cart->billing_zipcode = $faker->postcode;
|
||||
$cart->billing_country = $faker->country;
|
||||
$cart->shipping_amount = $faker->randomFloat(2, 5, 20); // Random shipping amount between $5 and $20
|
||||
$cart->total_amount = $faker->randomFloat(2, 50, 200); // Random total amount between $50 and $200
|
||||
$cart->save();
|
||||
|
||||
$prescription = Prescription::inRandomOrder()->first();
|
||||
|
||||
PatientPrescription::create([
|
||||
'patient_id' => $patient->id,
|
||||
'appointment_id' => $appointment->id,
|
||||
'prescription_id' => $prescription->id,
|
||||
'direction_one' => $faker->sentence,
|
||||
'direction_two' => $faker->sentence,
|
||||
'dont_substitute' => rand(0, 1),
|
||||
'comments' => $faker->sentence,
|
||||
'status' => $statusOptions[array_rand($statusOptions)],
|
||||
]);
|
||||
|
||||
$addNotePatient = PatientNote::create([
|
||||
'note' => "Patient didn't send back test kit yet",
|
||||
'note_type' => "Notes",
|
||||
'patient_id' => $patient->id,
|
||||
'appointment_id' => $appointment->id,
|
||||
'telemed_pros_id' => $telemedpro->id
|
||||
]);
|
||||
$category = ProfileCategory::where("category_link", 'weight_loss')->first();
|
||||
|
||||
|
||||
$jsonString = '{
|
||||
"weight_lb": "42",
|
||||
"height_feet": "5",
|
||||
"height_inches": "2",
|
||||
"expecting": "not_applicable",
|
||||
"evaluate_weight_loss": "yes",
|
||||
"weight_management": "no",
|
||||
"caloric_intake": "yes",
|
||||
"physical_activity": "no",
|
||||
"weightloss_goal": "yes",
|
||||
"medical_evaluation": "less_then_a_year_ago",
|
||||
"lab_tests_completed": "no",
|
||||
"comorbidities": [
|
||||
"high_cholesterol",
|
||||
"fatty_liver_disease"
|
||||
],
|
||||
"chronic_pancreatitis": [
|
||||
"none_of_the_above"
|
||||
],
|
||||
"smoke_alcohol": null,
|
||||
"family_history_thyroid_cancer": [
|
||||
"none_of_above_them"
|
||||
],
|
||||
"kindney_history": [
|
||||
"appointment_or_consultation_with",
|
||||
"history_of_solitary_kidney_or_kidney_transplant"
|
||||
]
|
||||
}';
|
||||
$questionBuilderData = [];
|
||||
// Convert JSON string to PHP array
|
||||
$data = json_decode($jsonString, true);
|
||||
foreach ($data as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$value = serialize($value);
|
||||
}
|
||||
if (!empty($value)) {
|
||||
$questionBuilderData[] = [
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
'profile_category_id' => $category->id,
|
||||
'customer_id' => $patient->id
|
||||
];
|
||||
}
|
||||
}
|
||||
$questionBuilder = QuestionBuilder::insert($questionBuilderData);
|
||||
}
|
||||
}
|
||||
}
|
87
app/Console/Commands/InsertDataForPatient.php
Normal file
87
app/Console/Commands/InsertDataForPatient.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\LabKit;
|
||||
use App\Models\Telemedpro;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPlan;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Models\PlanV1;
|
||||
use App\Models\Prescription;
|
||||
use App\Models\ProfileCategory;
|
||||
use App\Models\QuestionBuilder;
|
||||
use Illuminate\Support\Str;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Faker\Factory as Faker;
|
||||
|
||||
class InsertDataForPatient extends Command
|
||||
{
|
||||
protected $signature = 'insert:data-patient';
|
||||
|
||||
protected $description = 'Insert plans data into the database based on the provided type';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
/* for ($i = 0; $i < 10; $i++) {
|
||||
Telemedpro::create([
|
||||
'name' => 'Telemedpro ' . ($i + 1),
|
||||
'email' => 'telemedpro' . ($i + 1) . '@example.com',
|
||||
'phone' => '123-456-789' . $i,
|
||||
]);
|
||||
} */
|
||||
|
||||
$faker = Faker::create();
|
||||
|
||||
for ($i = 10000; $i < 20000; $i++) {
|
||||
$patient = Patient::create([
|
||||
'first_name' => $faker->firstName,
|
||||
'last_name' => $faker->lastName,
|
||||
'email' => $faker->unique()->safeEmail,
|
||||
'phone' => $faker->phoneNumber,
|
||||
'password' => bcrypt("12345"),
|
||||
'address' => $faker->address,
|
||||
'city' => $faker->city,
|
||||
'state' => $faker->state,
|
||||
'zip_code' => $faker->postcode,
|
||||
'lat' => $faker->latitude,
|
||||
'long' => $faker->longitude,
|
||||
'dob' => $faker->date($format = 'Y-m-d', $max = 'now'),
|
||||
'recording_switch' => $faker->boolean,
|
||||
'country' => $faker->country,
|
||||
'phone_no' => $faker->phoneNumber,
|
||||
'shipping_address' => $faker->address,
|
||||
'shipping_city' => $faker->city,
|
||||
'shipping_state' => $faker->state,
|
||||
'shipping_country' => $faker->country,
|
||||
'shipping_zipcode' => $faker->postcode,
|
||||
'timezone' => 'UTC',
|
||||
'gender' => $faker->randomElement(['male', 'female']),
|
||||
'marital_status' => $faker->randomElement(['single', 'married']),
|
||||
'height' => $faker->numberBetween(150, 200), // Height in cm
|
||||
'weight' => $faker->numberBetween(50, 100) // Weight in kg
|
||||
]);
|
||||
|
||||
PatientRegActivity::create([
|
||||
'patient_id' => $patient->id,
|
||||
'activity' => 'patient_registered'
|
||||
]);
|
||||
$plans = PlanV1::all();
|
||||
PatientPlan::create([
|
||||
'patient_id' => $patient->id,
|
||||
'plan_id' => $plans->random()->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
100
app/Console/Commands/InsertDataForPatientBulk.php
Normal file
100
app/Console/Commands/InsertDataForPatientBulk.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Models\PatientPlan;
|
||||
use App\Models\PlanV1;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Faker\Factory as Faker;
|
||||
|
||||
class InsertDataForPatientBulk extends Command
|
||||
{
|
||||
protected $signature = 'insert:data-patient-bulk';
|
||||
protected $description = 'Insert patient data into the database using bulk insert';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$faker = Faker::create();
|
||||
$batchSize = 500; // Number of records to insert in each batch
|
||||
$totalRecords = 20000; // Total number of records to insert
|
||||
|
||||
$plans = PlanV1::all();
|
||||
|
||||
for ($j = 0; $j < $totalRecords; $j += $batchSize) {
|
||||
$patientData = [];
|
||||
$patientRegActivityData = [];
|
||||
$patientPlanData = [];
|
||||
|
||||
for ($i = 0; $i < $batchSize; $i++) {
|
||||
$patientId = $j + $i + 37000; // Starting from 10001 as per your original code
|
||||
|
||||
$email = $faker->unique()->safeEmail;
|
||||
$emailParts = explode('@', $email);
|
||||
$emailParts[0] .= rand(1000, 9999); // Append a random 4-digit number
|
||||
$uniqueEmail = implode('@', $emailParts);
|
||||
|
||||
$patientData[] = [
|
||||
'id' => $patientId,
|
||||
'first_name' => $faker->firstName,
|
||||
'last_name' => $faker->lastName,
|
||||
'email' => $uniqueEmail,
|
||||
//'phone' => $faker->phoneNumber,
|
||||
'password' => bcrypt("12345"),
|
||||
'address' => $faker->address,
|
||||
'city' => $faker->city,
|
||||
'state' => $faker->state,
|
||||
'zip_code' => $faker->postcode,
|
||||
'lat' => $faker->latitude,
|
||||
'long' => $faker->longitude,
|
||||
'dob' => $faker->date($format = 'Y-m-d', $max = 'now'),
|
||||
'recording_switch' => $faker->boolean,
|
||||
'country' => $faker->country,
|
||||
'phone_no' => $faker->phoneNumber,
|
||||
'shipping_address' => $faker->address,
|
||||
'shipping_city' => $faker->city,
|
||||
'shipping_state' => $faker->state,
|
||||
'shipping_country' => $faker->country,
|
||||
'shipping_zipcode' => $faker->postcode,
|
||||
'timezone' => 'UTC',
|
||||
'gender' => $faker->randomElement(['male', 'female']),
|
||||
'marital_status' => $faker->randomElement(['single', 'married']),
|
||||
'height' => $faker->numberBetween(150, 200),
|
||||
'weight' => $faker->numberBetween(50, 100),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
|
||||
$patientRegActivityData[] = [
|
||||
'patient_id' => $patientId,
|
||||
'activity' => 'patient_registered',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
|
||||
$patientPlanData[] = [
|
||||
'patient_id' => $patientId,
|
||||
'plan_id' => $plans->random()->id,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
}
|
||||
|
||||
// Bulk insert data
|
||||
DB::table('patients')->insert($patientData);
|
||||
DB::table('patient_reg_activity')->insert($patientRegActivityData);
|
||||
DB::table('patient_plan')->insert($patientPlanData);
|
||||
|
||||
$this->info("Inserted batch of $batchSize records. Total progress: " . ($j + $batchSize) . " / $totalRecords");
|
||||
}
|
||||
|
||||
$this->info('Data insertion completed successfully.');
|
||||
}
|
||||
}
|
746
app/Console/Commands/InsertPlansData.php
Normal file
746
app/Console/Commands/InsertPlansData.php
Normal file
@ -0,0 +1,746 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\PlanV1;
|
||||
|
||||
class InsertPlansData extends Command
|
||||
{
|
||||
protected $signature = 'insert:plans {type}';
|
||||
|
||||
protected $description = 'Insert plans data into the database based on the provided type';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$type = $this->argument('type');
|
||||
|
||||
/* $plansData = [
|
||||
'hgh' => [
|
||||
[
|
||||
'title' => 'Basic Plan',
|
||||
'currency' => '$',
|
||||
'price' => '195.00',
|
||||
'list_one_title' => 'TRT prescription',
|
||||
'list_two_title' => 'A nazial mist or a pre-filled syringe for self-injection',
|
||||
'list_sub_title' => 'Either be cream or oral liquied',
|
||||
'image_url' => '',
|
||||
],
|
||||
[
|
||||
'title' => 'Pro Plan',
|
||||
'currency' => '$',
|
||||
'price' => '195.00',
|
||||
'list_one_title' => 'TRT prescription',
|
||||
'list_two_title' => 'A nazial mist or a pre-filled syringe for self-injection',
|
||||
'list_sub_title' => 'Either be cream or oral liquied',
|
||||
'image_url' => '',
|
||||
],
|
||||
[
|
||||
'title' => 'Elite Plan',
|
||||
'currency' => '$',
|
||||
'price' => '995.00',
|
||||
'list_one_title' => 'HGH & TRT prescription',
|
||||
'list_two_title' => 'Growth hormone zinc and magnesium',
|
||||
'list_sub_title' => 'Everything in Pro Plan',
|
||||
'image_url' => '',
|
||||
],
|
||||
],
|
||||
'peptide' => [
|
||||
[
|
||||
'title' => 'Semaglutide',
|
||||
'currency' => '$',
|
||||
'price' => '399.00',
|
||||
'list_one_title' => 'RX Prescription',
|
||||
'list_two_title' => 'Semaglutide, generic Ozempic and generic wegovy, is a potent medical weight loss treatment, with users typically experiencing an average loss of 15% of their body weight.',
|
||||
'list_sub_title' => 'Weight Loss',
|
||||
'image_url' => 'semaglutide.png',
|
||||
],
|
||||
[
|
||||
'title' => 'Tirzepatide',
|
||||
'currency' => '$',
|
||||
'price' => '499.00',
|
||||
'list_one_title' => 'RX Prescription',
|
||||
'list_two_title' => 'Tirzepatide, generic Zepbound and generic Mounjaro, is a powerful medical weight loss treatment, often enabling individuals to lose 20% or more of their body weight, showcasing its enhanced efficacy compared to Semaglutide.',
|
||||
'list_sub_title' => 'Weight Loss',
|
||||
'image_url' => 'Tirzepatide.webp',
|
||||
],
|
||||
[
|
||||
'title' => 'Sermorelin Injections',
|
||||
'currency' => '$',
|
||||
'price' => '249.00',
|
||||
'list_one_title' => 'RX Prescription',
|
||||
'list_two_title' => 'Sermorelin injections stimulate the body\'s natural production of growth hormone, promoting muscle growth, fat loss, and overall rejuvenation.',
|
||||
'list_sub_title' => 'Lean Muscle Mass & Fat Loss',
|
||||
'image_url' => 'Sermorelin.webp',
|
||||
],
|
||||
[
|
||||
'title' => 'PT-141 Injections',
|
||||
'currency' => '$',
|
||||
'price' => '345.00',
|
||||
'list_one_title' => 'RX Prescription',
|
||||
'list_two_title' => 'Sexual health and Performance. Supplies are shipped with treatment',
|
||||
'list_sub_title' => 'Sexual Performance',
|
||||
'image_url' => 'PT-141.webp',
|
||||
],
|
||||
[
|
||||
'title' => 'PT-141 Troche',
|
||||
'currency' => '$',
|
||||
'price' => '418.00',
|
||||
'list_one_title' => 'RX Prescription',
|
||||
'list_two_title' => 'Sexual health and Performance. Supplies are shipped with treatment',
|
||||
'list_sub_title' => 'Sexual Performance',
|
||||
'image_url' => 'pt-141_troche-2.webp',
|
||||
],
|
||||
[
|
||||
'title' => 'VIP Nasal Spray',
|
||||
'currency' => '$',
|
||||
'price' => '210.00',
|
||||
'list_one_title' => 'RX Prescription',
|
||||
'list_two_title' => 'VIP nasal spray offers targeted delivery of therapeutic peptides to support digestive health, immune function, and circadian regulation.',
|
||||
'list_sub_title' => 'Systemic Wellness',
|
||||
'image_url' => 'vip_nasal-spray.webp',
|
||||
],
|
||||
[
|
||||
'title' => 'SS-31 Injections',
|
||||
'currency' => '$',
|
||||
'price' => '1230.00',
|
||||
'list_one_title' => 'RX Prescription',
|
||||
'list_two_title' => 'VIP nasal spray offers targeted delivery of therapeutic peptides to support digestive health, immune function, and circadian regulation.',
|
||||
'list_sub_title' => 'Longevity & Performance',
|
||||
'image_url' => 'ss-31_syringes.webp',
|
||||
],
|
||||
],
|
||||
'peptide_new' => [
|
||||
[
|
||||
'title' => 'AOD9604 [ 5mg]',
|
||||
'currency' => '$',
|
||||
'price' => '70.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'AOD9604 is a peptide fragment of human growth hormone (HGH) used for its potential benefits in fat metabolism, weight loss, and joint health.',
|
||||
'list_sub_title' => 'Weight Loss',
|
||||
'image_url' => 'AOD9604-05mg.webp',
|
||||
'slug' => 'AOD9604-5mg',
|
||||
],
|
||||
[
|
||||
'title' => 'BPC – 157',
|
||||
'currency' => '$',
|
||||
'price' => '199.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => "BPC-157 is a penta-decapeptide composed of 15 amino acids. It is a partial sequence of the body protection compound (BPC) that was discovered in and isolated from human gastric juice. Animal studies have shown it to accelerate the healing of many different wounds, including muscle, tendon, and damaged ligaments. Additionally, BPC 157 has been shown to protect organs and aid in the prevention of gastric ulcers.",
|
||||
'list_sub_title' => 'Body Protection Compound',
|
||||
'image_url' => 'BPC-157-10mg.webp',
|
||||
'slug' => 'bpc–157',
|
||||
],
|
||||
[
|
||||
'title' => 'CJC-1295, Ipamorelin Blend [ 10mg]',
|
||||
'currency' => '$',
|
||||
'price' => '95.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'CJC-1295 causes the natural release of GH by naturally stimulating the growth hormone-releasing hormone receptor',
|
||||
'list_sub_title' => 'Growth hormone',
|
||||
'image_url' => 'CJC-1295-Ipamorelin-Blend-10mg.webp',
|
||||
'slug' => 'CJC-1295-10mg',
|
||||
],
|
||||
[
|
||||
'title' => 'PT-141 Injection',
|
||||
'currency' => '$',
|
||||
'price' => '149.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'PT-141, also known as Bremelanotide, is a melanocortin receptor agonist that boosts sexual desire and arousal by stimulating specific receptors in the brain. This peptide promotes increased libido and sexual function for both men and women, offering a unique solution for enhancing intimate experiences. Enjoy the convenience of our peptide subscription, delivering in-home treatments directly to your door',
|
||||
'list_sub_title' => 'Sexual Performance',
|
||||
'image_url' => 'PT-141-10-mg.webp',
|
||||
'slug' => 'pt-141-Injection-10mg',
|
||||
],
|
||||
[
|
||||
'title' => 'Semaglutide [3mg]',
|
||||
'currency' => '$',
|
||||
'price' => '199.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'Our Semaglutide weight loss program, led by board-certified physicians, can help you on a transformative journey toward a healthier lifestyle. The program includes monthly personalized Semaglutide prescriptions, regular virtual check-ins, and unlimited messaging with providers. Join the thousands of people who have already achieved their weight loss goals through this program.',
|
||||
'list_sub_title' => 'Weight Loss',
|
||||
'image_url' => 'Semaglutide-05mg.webp',
|
||||
'slug' => 'semaglutide-3mg',
|
||||
],
|
||||
[
|
||||
'title' => 'Semaglutide [5mg]',
|
||||
'currency' => '$',
|
||||
'price' => '220.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'Our Semaglutide weight loss program, led by board-certified physicians, can help you on a transformative journey toward a healthier lifestyle. The program includes monthly personalized Semaglutide prescriptions, regular virtual check-ins, and unlimited messaging with providers. Join the thousands of people who have already achieved their weight loss goals through this program.',
|
||||
'list_sub_title' => 'Weight Loss',
|
||||
'image_url' => 'Semaglutide-05mg.webp',
|
||||
'slug' => 'semaglutide-5mg',
|
||||
],
|
||||
[
|
||||
'title' => 'TB-500 (Thymosin Beta-4) [ 10mg ]',
|
||||
'currency' => '$',
|
||||
'price' => '170.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'TB-500, also known as Thymosin Beta-4, is a peptide consisting of 43 amino acids. In animal studies, Thymosin Beta-4 has demonstrated the ability to promote blood vessel growth, regulate wound healing, decrease inflammation, and reduce oxidative damage in the heart and central nervous system. This peptide plays a significant role in protecting tissues, and facilitating tissue repair, regeneration, and remodeling of injured or damaged tissues. Additionally, it is a subject of active research in the field of anti-aging.',
|
||||
'list_sub_title' => 'Injury Recovery',
|
||||
'image_url' => 'TB-500-Thymosin-Beta-4-10-mg.webp',
|
||||
'slug' => 'tb-500-10mg',
|
||||
],
|
||||
[
|
||||
'title' => 'Tesamorelin [5mg]',
|
||||
'currency' => '$',
|
||||
'price' => '75.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'Tesamorelin is a synthetic peptide consisting of 44 amino acids that mimic the growth hormone-releasing hormone (GHRH). It is specifically designed to stimulate the production and release of endogenous growth hormone (GH) from the pituitary gland. Originally developed for the treatment of lipodystrophy in HIV-positive individuals, Tesamorelin has shown potential benefits in reducing visceral adipose tissue and improving body composition. This peptide is utilized in various research and clinical settings for its ability to enhance GH levels, which may support lean muscle mass development, fat loss, and overall metabolic health., immune function, and circadian regulation.',
|
||||
'list_sub_title' => 'Weight loss',
|
||||
'image_url' => 'Tesamorelin-05mg.webp',
|
||||
'slug' => 'tesamorelin-5mg',
|
||||
],
|
||||
[
|
||||
'title' => 'Tesamorelin [10mg]',
|
||||
'currency' => '$',
|
||||
'price' => '135.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'Tesamorelin is a synthetic peptide consisting of 44 amino acids that mimic the growth hormone-releasing hormone (GHRH). It is specifically designed to stimulate the production and release of endogenous growth hormone (GH) from the pituitary gland. Originally developed for the treatment of lipodystrophy in HIV-positive individuals, Tesamorelin has shown potential benefits in reducing visceral adipose tissue and improving body composition. This peptide is utilized in various research and clinical settings for its ability to enhance GH levels, which may support lean muscle mass development, fat loss, and overall metabolic health., immune function, and circadian regulation.',
|
||||
'list_sub_title' => 'Weight loss',
|
||||
'image_url' => 'Tesamorelin-05mg.webp',
|
||||
'slug' => 'tesamorelin-10mg',
|
||||
],
|
||||
[
|
||||
'title' => 'Tirzepatide [ 5mg ]',
|
||||
'currency' => '$',
|
||||
'price' => '249.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'Tirzepatide, the same active ingredient in Mounjaro®, represents the latest and most potent GLP-1 class medication for sustained weight loss. Patients have experienced an impressive average weight reduction of 24.3% over 72 weeks, in conjunction with a calorie-restricted diet and heightened physical activity. This dual-action GLP-1/GIP is for individuals with obesity (BMI ≥30) or overweight (BMI ≥27) accompanied by a weight-related condition, alongside dietary and exercise modifications.',
|
||||
'list_sub_title' => 'Weight loss',
|
||||
'image_url' => 'Tirzepatide-0mg.webp',
|
||||
'slug' => 'tirzepatide-5mg',
|
||||
],
|
||||
[
|
||||
'title' => 'GHK-CU',
|
||||
'currency' => '$',
|
||||
'price' => '0.00',
|
||||
'list_one_title' => 'Peptides',
|
||||
'list_two_title' => 'GHK-Cu is a natural peptide found in human blood plasma, urine, and saliva. Research in animals indicates that GHK-Cu can enhance wound healing, boost immune function, and improve skin health by stimulating collagen production, activating fibroblasts, and promoting blood vessel growth. Evidence suggests that it acts as a feedback signal generated after tissue injury. Additionally, GHK-Cu suppresses free-radical damage, making it a potent antioxidant.',
|
||||
'list_sub_title' => 'Skin Regeneration',
|
||||
'image_url' => 'GHK-Cu-10mg.webp',
|
||||
'slug' => 'GHK-CU',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
if (isset($plansData[$type])) {
|
||||
foreach ($plansData[$type] as $plan) {
|
||||
PlanV1::create($plan);
|
||||
}
|
||||
$this->info('Plans data inserted successfully.');
|
||||
} else {
|
||||
$this->error('Invalid type provided.');
|
||||
} */
|
||||
|
||||
|
||||
|
||||
$data = [
|
||||
[
|
||||
"Category" => "Weight Loss",
|
||||
"Sub-Category" => "GLP-1 Weight Loss",
|
||||
"Drug" => "Semaglutide Injection",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 299,
|
||||
"Plus Shipping Cost" => 22.5,
|
||||
"Description" => "GLP-1 Weight Loss Injection",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Weight Loss",
|
||||
"Sub-Category" => "GLP-1 Weight Loss",
|
||||
"Drug" => "Semaglutide Oral Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 299,
|
||||
"Plus Shipping Cost" => 22.5,
|
||||
"Description" => "GLP-1 Weight Loss Injection",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Weight Loss",
|
||||
"Sub-Category" => "GLP-1 Weight Loss",
|
||||
"Drug" => "Semaglutide Oral Suspension",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 299,
|
||||
"Plus Shipping Cost" => 22.5,
|
||||
"Description" => "GLP-1 Weight Loss Injection",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Weight Loss",
|
||||
"Sub-Category" => "GLP-1 Weight Loss",
|
||||
"Drug" => "Semaglutide Oral Troche",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 299,
|
||||
"Plus Shipping Cost" => 22.5,
|
||||
"Description" => "GLP-1 Weight Loss Injection",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Weight Loss",
|
||||
"Sub-Category" => "GLP-1 Weight Loss",
|
||||
"Drug" => "Tirzepatide Injection",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 599,
|
||||
"Plus Shipping Cost" => 22.5,
|
||||
"Description" => "GLP-1 Weight Loss Injection",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Female Health & Wellness",
|
||||
"Sub-Category" => "Hair Loss/Regrowth",
|
||||
"Drug" => "Hair Loss Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 99,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Stopping Hair Loss/Hair Regrowth",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Female Health & Wellness",
|
||||
"Sub-Category" => "Hair Loss/Regrowth",
|
||||
"Drug" => "Hair Loss Topical Solution",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 99,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Stopping Hair Loss/Hair Regrowth",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Female Health & Wellness",
|
||||
"Sub-Category" => "Menopausal",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Female Health & Wellness",
|
||||
"Sub-Category" => "Pain and Mental Wellness",
|
||||
"Drug" => "Low Dose Naltrexone ",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 69,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Treats Pain, Depression, Chronic Fatigue",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Female Sexual Health",
|
||||
"Sub-Category" => "Sexual Health",
|
||||
"Drug" => "OXYTOCIN 250 unit, 500 unit tab triturate",
|
||||
"Supply" => "Per Dose, Qty 15",
|
||||
"Retail Cost" => 89,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Female Sexual Health Solutions",
|
||||
"__EMPTY" => "One time + Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Female Sexual Health",
|
||||
"Sub-Category" => "Sexual Health",
|
||||
"Drug" => "SCREAM CREAM (Arginine 60 mg/Pentoxifylline 50 mg/Sildenafil 10 mg/Testosterone 1 mg/gm)",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 79,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Female Sexual Health Solutions",
|
||||
"__EMPTY" => "One time + Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Female Sexual Health",
|
||||
"Sub-Category" => "Sexual Health",
|
||||
"Drug" => "TADALAFIL 2.5 mg/PT141 1mg/Oxytocin 250 unit tab triturate",
|
||||
"Supply" => "Per Dose, Qty 15",
|
||||
"Retail Cost" => 119,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Female Sexual Health Solutions",
|
||||
"__EMPTY" => "One time + Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Female Sexual Health",
|
||||
"Sub-Category" => "Sexual Health",
|
||||
"Drug" => "TADALAFIL 5 mg/PT141 2 mg/Oxytocin 500 unit tab triturate",
|
||||
"Supply" => "Per Dose, Qty 15",
|
||||
"Retail Cost" => 119,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Female Sexual Health Solutions",
|
||||
"__EMPTY" => "One time + Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hair Loss/Regrowth",
|
||||
"Drug" => "Hair Loss Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 99,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Stopping Hair Loss/Hair Regrowth",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hair Loss/Regrowth",
|
||||
"Drug" => "Hair Loss Topical Solution",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 99,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Stopping Hair Loss/Hair Regrowth",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "Clomiphine Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 69,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Low Testosterone Levels, Low Energy",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "Enclomaphine Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 119,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Low Testosterone Levels, Low Energy",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "HGH (Zomacton)",
|
||||
"Supply" => "1 Week",
|
||||
"Retail Cost" => 549,
|
||||
"Plus Shipping Cost" => 22.5,
|
||||
"Description" => "Human Growth Hormone",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "Nandralone Injection",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 299,
|
||||
"Plus Shipping Cost" => 22.5,
|
||||
"Description" => "Promotes Lean Muscle, Endurance, Healing, Increase Bone Density",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "Oxandralone Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 159,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Maintain Weight, Decrease Muscle Loss",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "Sermorelin Injection",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 129,
|
||||
"Plus Shipping Cost" => 22.5,
|
||||
"Description" => "Growth Homrone Promotes Lean Muscle, Endurance, Healing, Sleep",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "Stanozolol Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 109,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Retention of Lean Muscle",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "T3/T4 Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 69,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Thyroid Deficiency",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "Testosterone Cream",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 139,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Low Testosterone Levels, Low Energy",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Hormone Therapy",
|
||||
"Drug" => "Testosterone Injection",
|
||||
"Supply" => "10 Week Supply",
|
||||
"Retail Cost" => 139,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Low Testosterone Levels, Low Energy",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Sexual Health",
|
||||
"Sub-Category" => "Erectile Dysfunction",
|
||||
"Drug" => "OXYTOCIN 250 unit, 500 unit tab triturate",
|
||||
"Supply" => "Per Dose, Qty 15",
|
||||
"Retail Cost" => 89,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Erectile Dysfuction Solutions",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Sexual Health",
|
||||
"Sub-Category" => "Erectile Dysfunction",
|
||||
"Drug" => "Sildenafil (Viagra)",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 69,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Erectile Dysfuction Solutions",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Sexual Health",
|
||||
"Sub-Category" => "Erectile Dysfunction",
|
||||
"Drug" => "Tadalafil (Cialas)",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 69,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Erectile Dysfuction Solutions",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Sexual Health",
|
||||
"Sub-Category" => "Erectile Dysfunction",
|
||||
"Drug" => "TADALAFIL 10 mg/PT-141 2 mg/Oxytocin 250 unit tab triturate",
|
||||
"Supply" => "Per Dose, Qty 15",
|
||||
"Retail Cost" => 119,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Erectile Dysfuction Solutions",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Sexual Health",
|
||||
"Sub-Category" => "Erectile Dysfunction",
|
||||
"Drug" => "TADALAFIL 20 mg/PT-141 2 mg/Oxytocin 500 unit tab triturate",
|
||||
"Supply" => "Per Dose, Qty 15",
|
||||
"Retail Cost" => 119,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Erectile Dysfuction Solutions",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Sexual Health",
|
||||
"Sub-Category" => "Erectile Dysfunction",
|
||||
"Drug" => "Trimix Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 129,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Erectile Dysfuction Solutions",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Peptides",
|
||||
"Sub-Category" => "Oral Peptides",
|
||||
"Drug" => "AOD 600 mcg cap",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 139,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Weight Loss - Speed Metabolism, Burn Fat",
|
||||
"__EMPTY" => "Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Peptides",
|
||||
"Sub-Category" => "Oral Peptides",
|
||||
"Drug" => "BPC-157 500 mcg cap",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 129,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Promotes GI Protection, Wound Healing, Muscle Recovery, Anabolic Effects",
|
||||
"__EMPTY" => "One time + Subscription"
|
||||
],
|
||||
[
|
||||
"Category" => "Peptides",
|
||||
"Sub-Category" => "Oral Peptides",
|
||||
"Drug" => "DIHEXA 10mg Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 159,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Enhances Memory and Cognition",
|
||||
"__EMPTY" => "One time + Subscription"
|
||||
],
|
||||
[
|
||||
"Category" => "Peptides",
|
||||
"Sub-Category" => "Oral Peptides",
|
||||
"Drug" => "DIHEXA 20mg Capsule",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 299,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Enhances Memory and Cognition",
|
||||
"__EMPTY" => "One time + Subscription"
|
||||
],
|
||||
[
|
||||
"Category" => "Peptides",
|
||||
"Sub-Category" => "Oral Peptides",
|
||||
"Drug" => "DSIP 500 mcg cap",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 119,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Promotes Sleep, Regulates Circadian Rythms, Reduces Pain, Improves Mood",
|
||||
"__EMPTY" => "One time + Subscription"
|
||||
],
|
||||
[
|
||||
"Category" => "Peptides",
|
||||
"Sub-Category" => "Oral Peptides",
|
||||
"Drug" => "KPV 500 mcg cap",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 129,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Lowers Inflammation, Improves Gut Health",
|
||||
"__EMPTY" => "One time + Subscription"
|
||||
],
|
||||
[
|
||||
"Category" => "Peptides",
|
||||
"Sub-Category" => "Oral Peptides",
|
||||
"Drug" => "KPV 500 mcg/BPC-157 mcg cap",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 139,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Lowers Inflammation, Improves Gut Health",
|
||||
"__EMPTY" => "One time + Subscription"
|
||||
],
|
||||
[
|
||||
"Category" => "Peptides",
|
||||
"Sub-Category" => "Oral Peptides",
|
||||
"Drug" => "NAD+ 300 mg/mL Nasal Spray",
|
||||
"Supply" => "1 Month or +",
|
||||
"Retail Cost" => 99,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Energy, Cell Repair, Overall Health",
|
||||
"__EMPTY" => "One time + Subscription"
|
||||
],
|
||||
[
|
||||
"Category" => "Peptides",
|
||||
"Sub-Category" => "Oral Peptides",
|
||||
"Drug" => "NAD+ 400 mg patch",
|
||||
"Supply" => "4 Patches",
|
||||
"Retail Cost" => 129,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Energy, Cell Repair, Overall Health",
|
||||
"__EMPTY" => "One time + Subscription"
|
||||
],
|
||||
[
|
||||
"Category" => "Female Health & Wellness",
|
||||
"Sub-Category" => "Energy",
|
||||
"Drug" => "B12 Injections",
|
||||
"Supply" => "10mL",
|
||||
"Retail Cost" => 129,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Low Energy",
|
||||
"__EMPTY" => "One time + Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Category" => "Male Health & Wellness",
|
||||
"Sub-Category" => "Energy",
|
||||
"Drug" => "B12 Injections",
|
||||
"Supply" => "10mL",
|
||||
"Retail Cost" => 129,
|
||||
"Plus Shipping Cost" => 12.5,
|
||||
"Description" => "Low Energy",
|
||||
"__EMPTY" => "One time + Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
],
|
||||
[
|
||||
"Drug" => "Rapamycin",
|
||||
"__EMPTY" => "One time + Subscription",
|
||||
"__EMPTY_1" => "Prescription required. "
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
foreach ($data as $item) {
|
||||
if (!isset($item['Drug']))
|
||||
continue;
|
||||
if (!isset($item['Description']))
|
||||
continue;
|
||||
// Find the existing record based on title and list_two_title
|
||||
$existingPlan = PlanV1::where('title', $item['Drug'])
|
||||
->where('list_two_title', $item['Description'])
|
||||
->first();
|
||||
$is_prescription_required = false;
|
||||
if (isset($item['__EMPTY_1']) && $item['__EMPTY_1'] == "Prescription required. ")
|
||||
$is_prescription_required = true;
|
||||
if ($existingPlan) {
|
||||
// Update the existing record
|
||||
$existingPlan->update([
|
||||
'currency' => '$',
|
||||
'price' => $item['Retail Cost'] ?? 0,
|
||||
'shipping_cost' => $item['Plus Shipping Cost'] ?? 0,
|
||||
'list_one_title' => "hgh",
|
||||
'is_prescription_required' => $is_prescription_required,
|
||||
'list_sub_title' => $item['Description'] ?? "",
|
||||
'list_sub_title' => $item['Description'] ?? "",
|
||||
'slug' => PlanV1::generateUniqueSlug($item['Drug']),
|
||||
]);
|
||||
} else {
|
||||
// Create a new record
|
||||
PlanV1::create([
|
||||
'title' => $item['Drug'],
|
||||
'currency' => '$',
|
||||
'price' => $item['Retail Cost'] ?? 0,
|
||||
'shipping_cost' => $item['shipping_cost'] ?? 0,
|
||||
'list_one_title' => "hgh",
|
||||
'is_prescription_required' => $is_prescription_required,
|
||||
'list_two_title' => $item['Description'] ?? "",
|
||||
'list_sub_title' => $item['Description'] ?? "",
|
||||
'slug' => PlanV1::generateUniqueSlug($item['Drug']),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
77
app/Console/Commands/ParseQuestionsSheet.php
Normal file
77
app/Console/Commands/ParseQuestionsSheet.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
|
||||
class ParseQuestionsSheet extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:parse-questions-sheet';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// Path to the Excel file
|
||||
$fileName = 'doctor intake request form.xlsx';
|
||||
$filePath = storage_path($fileName);
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
$this->error('File not found: ' . $filePath);
|
||||
return Command::FAILURE;
|
||||
}
|
||||
// Load the Excel file
|
||||
$spreadsheet = IOFactory::load($filePath);
|
||||
$worksheet = $spreadsheet->getSheetByName('doctor intake questions');
|
||||
|
||||
if (!$worksheet) {
|
||||
$this->error('Sheet1 not found in the Excel file.');
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$jsonArray = [];
|
||||
|
||||
// Iterate through rows starting from the second row (assuming the first row contains headers)
|
||||
foreach ($worksheet->getRowIterator(2) as $row) {
|
||||
$cellIterator = $row->getCellIterator();
|
||||
$cellIterator->setIterateOnlyExistingCells(false);
|
||||
|
||||
// Get the data from each cell
|
||||
$label = $cellIterator->current()->getValue();
|
||||
$cellIterator->next();
|
||||
$key = $cellIterator->current()->getValue();
|
||||
$cellIterator->next();
|
||||
$type = $cellIterator->current()->getValue();
|
||||
|
||||
// Add data to the JSON array
|
||||
$jsonArray[] = [
|
||||
'label' => $label,
|
||||
'key' => $key,
|
||||
'type' => $type,
|
||||
];
|
||||
}
|
||||
|
||||
// Convert the array to JSON
|
||||
$json = json_encode($jsonArray, JSON_PRETTY_PRINT);
|
||||
|
||||
// Save JSON to a file
|
||||
$outputFilePath = resource_path('js/views/pages/questionere/questions_parse.json');
|
||||
file_put_contents($outputFilePath, $json);
|
||||
|
||||
$this->info('JSON data saved to: ' . $outputFilePath);
|
||||
}
|
||||
}
|
145
app/Console/Commands/ReadCsv.php
Normal file
145
app/Console/Commands/ReadCsv.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\ProfileCategory;
|
||||
use App\Models\ProfileCategoryQuestion;
|
||||
use App\Models\ProfileQuestion;
|
||||
use App\Models\ProfileSubQuestion;
|
||||
use Exception;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use League\Csv\Reader;
|
||||
use Symfony\Component\HttpKernel\Profiler\Profile;
|
||||
|
||||
class ReadCsv extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:read-csv {file?}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
function convertTextToLowerAndReplaceSpaces($text)
|
||||
{
|
||||
$lowercaseText = rtrim(strtolower($text), " ");
|
||||
$convertedText = str_replace(' ', '_', $lowercaseText);
|
||||
$convertedText = str_replace(',', '_', $lowercaseText);
|
||||
$convertedText = trim(str_replace('/', '_', $lowercaseText));
|
||||
return $convertedText;
|
||||
}
|
||||
function convertTextToLowerAndReplaceDashes($text)
|
||||
{
|
||||
$lowercaseText = rtrim(strtolower($text), " ");
|
||||
$convertedText = str_replace(' ', '-', $lowercaseText);
|
||||
$convertedText = trim(str_replace('/', '-', $lowercaseText));
|
||||
return $convertedText;
|
||||
}
|
||||
public function handle()
|
||||
{
|
||||
|
||||
|
||||
$fileName = 'question data (5).csv'; // Change this to the name of your CSV file
|
||||
$filePath = storage_path($fileName);
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
$this->error('File not found: ' . $filePath);
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$csv = Reader::createFromPath($filePath, 'r');
|
||||
$csv->setHeaderOffset(0);
|
||||
|
||||
$records = $csv->getRecords();
|
||||
|
||||
// Get the header row
|
||||
$header = $csv->getHeader();
|
||||
|
||||
// Loop through each row
|
||||
foreach ($csv->getRecords($header) as $record) {
|
||||
|
||||
|
||||
$Category = $record['Category'];
|
||||
if (count(explode(",", $Category)) > 1) {
|
||||
foreach (explode(",", $Category) as $cat) {
|
||||
$ProfileCategory = ProfileCategory::firstOrCreate([
|
||||
'name' => trim($cat),
|
||||
'icon' => $this->convertTextToLowerAndReplaceDashes($cat) . ".png",
|
||||
'category_link' => $this->convertTextToLowerAndReplaceSpaces($cat)
|
||||
]);
|
||||
$this->insertREcord($ProfileCategory, $record);
|
||||
}
|
||||
} elseif ($Category) {
|
||||
$ProfileCategory = ProfileCategory::firstOrCreate([
|
||||
'name' => trim($Category),
|
||||
'icon' => $this->convertTextToLowerAndReplaceDashes($Category) . ".png",
|
||||
'category_link' => $this->convertTextToLowerAndReplaceSpaces($Category)
|
||||
]);
|
||||
$this->insertREcord($ProfileCategory, $record);
|
||||
}
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
function insertREcord($ProfileCategory, $record)
|
||||
{
|
||||
$type = $record['type'];
|
||||
|
||||
$options = rtrim($record['options']);
|
||||
$options = serialize(explode(",", $options));
|
||||
$Question = $record['Question'];
|
||||
|
||||
$ProfileQuestion = ProfileQuestion::firstOrCreate([
|
||||
'question' => $Question,
|
||||
'question_options' => $options,
|
||||
'question_type' => $type,
|
||||
]);
|
||||
|
||||
try {
|
||||
ProfileCategoryQuestion::firstOrCreate([
|
||||
'category_id' => $ProfileCategory->id,
|
||||
'question_id' => $ProfileQuestion->id
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
$BaseQuestionR = $record['Base Question (Reference)'];
|
||||
$ProfileQuestion_id = null;
|
||||
if ($BaseQuestionR !== "") {
|
||||
$ProfileQuestion = ProfileQuestion::where("question", $BaseQuestionR)->first();
|
||||
if ($ProfileQuestion)
|
||||
$ProfileQuestion_id = $ProfileQuestion->id;
|
||||
}
|
||||
|
||||
|
||||
$SubQuestionR = $record['Sub Question (Reference)'];
|
||||
$parent_sub_question_id = null;
|
||||
if ($SubQuestionR !== "") {
|
||||
$ProfileSubQuestion = ProfileSubQuestion::where("question", $SubQuestionR)->first();
|
||||
if ($ProfileSubQuestion)
|
||||
$parent_sub_question_id = $ProfileSubQuestion->id;
|
||||
}
|
||||
|
||||
$SubQuestion = $record['SubQuestion'];
|
||||
|
||||
$ProfileSubQuestion2 = ProfileSubQuestion::updateOrCreate([
|
||||
'category_id' => $ProfileCategory->id,
|
||||
'question_id' => $ProfileQuestion_id,
|
||||
'question' => $SubQuestion,
|
||||
'parent_sub_question_id' => $parent_sub_question_id,
|
||||
'sub_question_type' => $type,
|
||||
'sub_question_options' => $options,
|
||||
]);
|
||||
}
|
||||
}
|
65
app/Console/Commands/SendReminderEmails.php
Normal file
65
app/Console/Commands/SendReminderEmails.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Notifications\AppointmentReminder;
|
||||
use App\Notifications\RegistrationReminder;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SendReminderEmails extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:send-reminder-emails';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$incompleteRegistrations = PatientRegActivity::where('activity', 'patient_registered')
|
||||
->whereNotExists(function ($query) {
|
||||
$query->select('id')
|
||||
->from('patient_reg_activity')
|
||||
->whereColumn('patient_reg_activity.patient_id', 'patient_reg_activity.patient_id')
|
||||
->where('activity', 'patient_appointment_booked');
|
||||
})->where("patient_reg_activity.email_sent", "!=", 1)->get();
|
||||
|
||||
foreach ($incompleteRegistrations as $patient) {
|
||||
|
||||
$patient->notify(new RegistrationReminder($patient->patient_id));
|
||||
$patient->email_sent = 1;
|
||||
$patient->save();
|
||||
}
|
||||
|
||||
$incompleteAppointments = PatientRegActivity::where('activity', 'patient_appointment_booked')
|
||||
->whereNotExists(function ($query) {
|
||||
$query->select('id')
|
||||
->from('patient_reg_activity')
|
||||
->whereColumn('patient_reg_activity.patient_id', 'patient_reg_activity.patient_id')
|
||||
->where('activity', 'patient_medical_question_entered');
|
||||
})->where("patient_reg_activity.email_sent", "!=", 1)->get();
|
||||
|
||||
foreach ($incompleteAppointments as $patient) {
|
||||
echo "Into patient_medical_question_entered";
|
||||
$patient->notify(new AppointmentReminder($patient->patient_id));
|
||||
$patient->email_sent = 1;
|
||||
$patient->save();
|
||||
}
|
||||
|
||||
$this->info('Reminder emails sent successfully.');
|
||||
}
|
||||
}
|
110
app/Console/Commands/parseTypeSheet.php
Normal file
110
app/Console/Commands/parseTypeSheet.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
|
||||
class parseTypeSheet extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:parse-type-sheet';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// Path to the Excel file
|
||||
$fileName = 'doctor intake request form.xlsx';
|
||||
$filePath = storage_path($fileName);
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
$this->error('File not found: ' . $filePath);
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
// Load the Excel file
|
||||
$spreadsheet = IOFactory::load($filePath);
|
||||
$worksheet = $spreadsheet->getSheetByName('type');
|
||||
|
||||
if (!$worksheet) {
|
||||
$this->error('Sheet2 not found in the Excel file.');
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$objects = [];
|
||||
$counter = 1; // Initialize counter
|
||||
|
||||
// Get the highest column number
|
||||
$highestColumn = $worksheet->getHighestColumn();
|
||||
// Convert the column letter to a number
|
||||
$highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn);
|
||||
|
||||
// Iterate through columns
|
||||
for ($col = 1; $col <= $highestColumnIndex; $col += 2) {
|
||||
$type = $worksheet->getCellByColumnAndRow($col, 1)->getValue(); // Get the type
|
||||
$name = $worksheet->getCellByColumnAndRow($col + 1, 1)->getValue(); // Get the name
|
||||
$values = [];
|
||||
|
||||
// Initialize row counter
|
||||
$row = 2;
|
||||
|
||||
// Iterate through the values in the column pair using a do-while loop to ensure it executes at least once
|
||||
do {
|
||||
$keyCell = $worksheet->getCellByColumnAndRow($col, $row);
|
||||
$valueCell = $worksheet->getCellByColumnAndRow($col + 1, $row);
|
||||
|
||||
// Check if key and value cells are not empty
|
||||
if ($keyCell->getValue() !== null && $valueCell->getValue() !== null) {
|
||||
$key = $keyCell->getValue();
|
||||
$value = $valueCell->getValue();
|
||||
|
||||
// Add key-value pair to the values array
|
||||
$values[$key] = $value;
|
||||
|
||||
// Increment row counter
|
||||
$row++;
|
||||
} else {
|
||||
// If either key or value cell is empty, exit the loop
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
// Add object to the objects array only if type and name are not null and values are not empty
|
||||
if ($type !== null && $name !== null && !empty($values)) {
|
||||
$objects[$type] = [
|
||||
'type' => $name,
|
||||
'values' => $values
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the array to JSON
|
||||
$json = json_encode($objects, JSON_PRETTY_PRINT);
|
||||
|
||||
// Save JSON to a file
|
||||
$outputFilePath = resource_path('js/views/pages/questionere/type_parse.json');
|
||||
file_put_contents($outputFilePath, $json);
|
||||
|
||||
$this->info('JSON data saved to: ' . $outputFilePath);
|
||||
}
|
||||
|
||||
|
||||
// Helper function to get the cell value safely
|
||||
private function getCellValue($cell)
|
||||
{
|
||||
return $cell ? $cell->getValue() : '';
|
||||
}
|
||||
}
|
61
app/Console/Commands/send15MinAlertAppointment.php
Normal file
61
app/Console/Commands/send15MinAlertAppointment.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Appointment;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Carbon\CarbonTimeZone;
|
||||
|
||||
class send15MinAlertAppointment extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:send15-min-alert-appointment';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$appointments = Appointment::where('appointment_time', '<=', $now->addMinutes(15)->format('H:i:s'))->where('appointment_time', '>=', Carbon::now()->format('H:i:s'))->get();
|
||||
|
||||
|
||||
|
||||
foreach ($appointments as $appointment) {
|
||||
|
||||
// Concatenate date and time
|
||||
$datetimeUtc = $appointment->appointment_date . ' ' . $appointment->appointment_time;
|
||||
|
||||
// Convert to UTC timezone
|
||||
$dateTimeUtc = Carbon::createFromFormat('Y-m-d H:i:s', $datetimeUtc, 'UTC');
|
||||
|
||||
// Convert to the appointment's timezone
|
||||
$appointmentTimeZone = new CarbonTimeZone($appointment->timezone);
|
||||
$dateTimeInAppointmentTimeZone = $dateTimeUtc->setTimezone($appointmentTimeZone);
|
||||
|
||||
// Split the datetime into date and time components in the appointment timezone
|
||||
$appointment->appointment_date = $appointmentDate = $dateTimeInAppointmentTimeZone->format('Y-m-d');
|
||||
$appointment->appointment_time = $appointmentTime = $dateTimeInAppointmentTimeZone->format('H:i:s');
|
||||
|
||||
|
||||
$patient = $appointment->patient;
|
||||
Mail::send('emails.upcoming-meeting', ['patient' => $patient, 'appointment' => $appointment], function ($message) use ($patient) {
|
||||
$message->to("muhammadawais95@gmail.com", $patient->first_name)
|
||||
->subject('Upcoming Meeting Reminder');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
58
app/Console/Commands/send1MinAlertAppointment.php
Normal file
58
app/Console/Commands/send1MinAlertAppointment.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Appointment;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonTimeZone;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class send1MinAlertAppointment extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:send1-min-alert-appointment';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$appointments = Appointment::where('appointment_time', '<=', $now->addMinutes(1)->format('H:i:s'))->where('appointment_time', '>=', Carbon::now()->format('H:i:s'))->get();
|
||||
|
||||
foreach ($appointments as $appointment) {
|
||||
|
||||
// Concatenate date and time
|
||||
$datetimeUtc = $appointment->appointment_date . ' ' . $appointment->appointment_time;
|
||||
|
||||
// Convert to UTC timezone
|
||||
$dateTimeUtc = Carbon::createFromFormat('Y-m-d H:i:s', $datetimeUtc, 'UTC');
|
||||
|
||||
// Convert to the appointment's timezone
|
||||
$appointmentTimeZone = new CarbonTimeZone($appointment->timezone);
|
||||
$dateTimeInAppointmentTimeZone = $dateTimeUtc->setTimezone($appointmentTimeZone);
|
||||
|
||||
// Split the datetime into date and time components in the appointment timezone
|
||||
$appointment->appointment_date = $appointmentDate = $dateTimeInAppointmentTimeZone->format('Y-m-d');
|
||||
$appointment->appointment_time = $appointmentTime = $dateTimeInAppointmentTimeZone->format('H:i:s');
|
||||
|
||||
$patient = $appointment->patient;
|
||||
Mail::send('emails.start-meeting', ['patient' => $patient, 'appointment' => $appointment], function ($message) use ($patient) {
|
||||
$message->to($patient->email, $patient->first_name)
|
||||
->subject('Join Our Online Appointment Now');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
28
app/Console/Kernel.php
Normal file
28
app/Console/Kernel.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
$schedule->command('app:send15-min-alert-appointment')->everyMinute();
|
||||
$schedule->command('app:send1-min-alert-appointment')->everyFifteenMinutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*/
|
||||
protected function commands(): void
|
||||
{
|
||||
$this->load(__DIR__ . '/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
39
app/Events/AppointmentBooked.php
Normal file
39
app/Events/AppointmentBooked.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\Appointment;
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class AppointmentBooked
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public $appointment;
|
||||
|
||||
public function __construct(Appointment $appointment)
|
||||
{
|
||||
$this->appointment = $appointment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [
|
||||
new PrivateChannel('channel-name'),
|
||||
];
|
||||
}
|
||||
}
|
52
app/Events/AppointmentCallEnded.php
Normal file
52
app/Events/AppointmentCallEnded.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class AppointmentCallEnded implements ShouldBroadcast
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public $patient_id;
|
||||
public $appointment_id;
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct($patient_id, $appointment_id)
|
||||
{
|
||||
$this->patient_id = $patient_id;
|
||||
$this->appointment_id = $appointment_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [
|
||||
new PrivateChannel('patient-end-call-' . $this->patient_id),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data to broadcast.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function broadcastWith(): array
|
||||
{
|
||||
return [
|
||||
'patient_id' => $this->patient_id,
|
||||
'appointment_id' => $this->appointment_id
|
||||
];
|
||||
}
|
||||
}
|
59
app/Events/AppointmentCreated.php
Normal file
59
app/Events/AppointmentCreated.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class AppointmentCreated implements ShouldBroadcastNow
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public $patient_id;
|
||||
public $appointment_id;
|
||||
public $meeting_id;
|
||||
public $call_type;
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct($patient_id, $appointment_id, $meeting_id, $call_type)
|
||||
{
|
||||
$this->patient_id = $patient_id;
|
||||
$this->appointment_id = $appointment_id;
|
||||
$this->meeting_id = $meeting_id;
|
||||
$this->call_type = $call_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [
|
||||
new PrivateChannel('patient-' . $this->patient_id),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data to broadcast.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function broadcastWith(): array
|
||||
{
|
||||
return [
|
||||
'patient_id' => $this->patient_id,
|
||||
'appointment_id' => $this->appointment_id,
|
||||
'meeting_id' => $this->meeting_id,
|
||||
'call_type' => $this->call_type
|
||||
];
|
||||
}
|
||||
}
|
39
app/Events/DeviceCurrentStatus.php
Normal file
39
app/Events/DeviceCurrentStatus.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
|
||||
class DeviceCurrentStatus implements ShouldBroadcast
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
|
||||
public $micStatus;
|
||||
public $camStatus;
|
||||
|
||||
public function __construct($micStatus, $camStatus)
|
||||
{
|
||||
$this->micStatus = $micStatus;
|
||||
$this->camStatus = $camStatus;
|
||||
}
|
||||
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('agent-queue');
|
||||
}
|
||||
|
||||
public function broadcastWith()
|
||||
{
|
||||
return [
|
||||
'mic' => $this->micStatus,
|
||||
'cam' => $this->camStatus,
|
||||
];
|
||||
}
|
||||
}
|
41
app/Events/PatientRegistered.php
Normal file
41
app/Events/PatientRegistered.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\Patient;
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class PatientRegistered
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public $patient;
|
||||
public $validatedData;
|
||||
|
||||
public function __construct(Patient $patient, array $validatedData)
|
||||
{
|
||||
$this->patient = $patient;
|
||||
$this->validatedData = $validatedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [
|
||||
new PrivateChannel('channel-name'),
|
||||
];
|
||||
}
|
||||
}
|
39
app/Events/PaymentProcessed.php
Normal file
39
app/Events/PaymentProcessed.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\Patient;
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class PaymentProcessed
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public $patient;
|
||||
|
||||
public function __construct(Patient $patient)
|
||||
{
|
||||
$this->patient = $patient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [
|
||||
new PrivateChannel('channel-name'),
|
||||
];
|
||||
}
|
||||
}
|
39
app/Events/StartCall.php
Normal file
39
app/Events/StartCall.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class StartCall
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct($message)
|
||||
{
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return ['my-channel'];
|
||||
}
|
||||
public function broadcastAs()
|
||||
{
|
||||
return 'my-event';
|
||||
}
|
||||
}
|
30
app/Exceptions/Handler.php
Normal file
30
app/Exceptions/Handler.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* The list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
BIN
app/Http/.DS_Store
vendored
Normal file
BIN
app/Http/.DS_Store
vendored
Normal file
Binary file not shown.
70
app/Http/Controllers/Admin/AgentController.php
Normal file
70
app/Http/Controllers/Admin/AgentController.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Telemedpro;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class AgentController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$agents = Telemedpro::all();
|
||||
return view('admin.agents.index', ['agents' => $agents]);
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
return view('admin.agents.add');
|
||||
}
|
||||
|
||||
public function save(Request $request)
|
||||
{
|
||||
$agent = Telemedpro::where('email',$request->input('email'))->first();
|
||||
if($agent)
|
||||
{
|
||||
$request->session()->flash('error', 'The email has already been taken.');
|
||||
return redirect()->back();
|
||||
}
|
||||
Telemedpro::create([
|
||||
'name' => $request->input('name'),
|
||||
'email' => $request->input('email'),
|
||||
'password' => bcrypt($request->input('password')),
|
||||
]);
|
||||
$request->session()->flash('message', 'Agent created successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$agent = Telemedpro::where('id',$id)->first();
|
||||
return view('admin.agents.edit', ['agent' => $agent]);
|
||||
}
|
||||
|
||||
public function update($id,Request $request)
|
||||
{
|
||||
$agent = Telemedpro::where('id',$id)->first();
|
||||
$request->validate([
|
||||
'name' => 'required',
|
||||
'email' => 'required|email|unique:telemed_pros,email,' . $id,
|
||||
// Other validation rules...
|
||||
]);
|
||||
$agent->name = $request->input('name');
|
||||
$agent->email = $request->input('email');
|
||||
if($request->input('password'))
|
||||
$agent->password = $request->input('password');
|
||||
$agent->save();
|
||||
|
||||
$request->session()->flash('message', 'Agent updated successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function delete($id,Request $request)
|
||||
{
|
||||
Telemedpro::where('id',$id)->delete();
|
||||
$request->session()->flash('message', 'Agent deleted successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
122
app/Http/Controllers/Admin/Api/AdminController.php
Normal file
122
app/Http/Controllers/Admin/Api/AdminController.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Admin;
|
||||
use App\Models\Permission;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Yajra\DataTables\DataTables;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
class AdminController extends Controller
|
||||
{
|
||||
protected $user;
|
||||
protected $url;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function index(){
|
||||
try {
|
||||
$this->authorizeForUser($this->user,'list', new Admin);
|
||||
$adminData = Admin::all();
|
||||
foreach($adminData as $admin)
|
||||
{
|
||||
$admin->image_path = $this->url->to('/storage/profile_pictures/' . $admin->image_path);
|
||||
}
|
||||
|
||||
return DataTables::of($adminData)->make(true);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
public function getRoles()
|
||||
{
|
||||
$roles = Permission::select('id','role_name as role')->get();
|
||||
return response()->json([
|
||||
'data' => $roles
|
||||
], 201);
|
||||
}
|
||||
public function saveAdmin(Request $request)
|
||||
{
|
||||
$this->authorize('add', new Admin);
|
||||
$data =[
|
||||
"name" => $request->get('name'),
|
||||
"email" => $request->get('email'),
|
||||
"password" => Hash::make($request->input('password')),
|
||||
"last_name" => $request->get('last_name'),
|
||||
"phone_no" => $request->get('phone_no'),
|
||||
"role_id" => $request->get('role_id')
|
||||
];
|
||||
$admin = Admin::create($data);
|
||||
$image = $request->get('profile_pic');
|
||||
$fileName = 'profile-' . time();
|
||||
|
||||
$logo = base64_decode($image);
|
||||
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
||||
|
||||
$imageName = $fileName . '.' . $ext;
|
||||
Storage::disk('local')->put("/public/profile_pictures/" . $imageName, $logo);
|
||||
|
||||
$admin->image_path = $imageName;
|
||||
$admin->save();
|
||||
return response()->json([
|
||||
'success' => "Data Saved! "
|
||||
], 201);
|
||||
}
|
||||
public function editAdmin($id)
|
||||
{
|
||||
$adminData = Admin::find($id);
|
||||
|
||||
if($adminData->image_path)
|
||||
$adminData->image_path = $this->url->to('/storage/profile_pictures/' . $adminData->image_path);
|
||||
else
|
||||
$adminData->image_path='';
|
||||
|
||||
return response()->json([
|
||||
'data' => $adminData
|
||||
], 201);
|
||||
}
|
||||
public function updateAdmin($id,Request $request)
|
||||
{
|
||||
$admin = Admin::find($id);
|
||||
$admin->name = $request->get('name');
|
||||
// $admin->email = $request->get('email');
|
||||
if($request->input('password'))
|
||||
$admin->password = Hash::make($request->input('password'));
|
||||
$admin->last_name = $request->get('last_name');
|
||||
$admin->phone_no = $request->get('phone_no');
|
||||
$admin->role_id = $request->get('role_id');
|
||||
|
||||
if($request->get('profile_pic'))
|
||||
{
|
||||
$image = $request->get('profile_pic');
|
||||
$fileName = 'profile-' . time();
|
||||
|
||||
$logo = base64_decode($image);
|
||||
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
||||
|
||||
$imageName = $fileName . '.' . $ext;
|
||||
Storage::disk('local')->put("/public/profile_pictures/" . $imageName, $logo);
|
||||
$admin->image_path = $imageName;
|
||||
}
|
||||
|
||||
$admin->save();
|
||||
return response()->json([
|
||||
'data' => $admin
|
||||
], 201);
|
||||
}
|
||||
public function detailAdmin($id)
|
||||
{
|
||||
|
||||
$admin = Admin::find($id);
|
||||
$admin->image_path = $this->url->to('/storage/profile_pictures/' . $admin->image_path);
|
||||
return response()->json([
|
||||
'data' => $admin
|
||||
], 201);
|
||||
}
|
||||
}
|
643
app/Http/Controllers/Admin/Api/AppointmentController.php
Normal file
643
app/Http/Controllers/Admin/Api/AppointmentController.php
Normal file
@ -0,0 +1,643 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use Agence104\LiveKit\VideoGrant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\LabkitOrderItem;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Telemedpro;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonTimeZone;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Error;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Yajra\DataTables\DataTables;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Agence104\LiveKit\AccessToken;
|
||||
use Agence104\LiveKit\AccessTokenOptions;
|
||||
use Agence104\LiveKit\RoomCreateOptions;
|
||||
use Agence104\LiveKit\RoomServiceClient;
|
||||
use Google\Protobuf\TwirpError;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
|
||||
class AppointmentController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function getAppointmentList()
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Appointment);
|
||||
$appointments = Appointment::select("patients.first_name", "patients.last_name", "telemed_pros.name as agent_name", "appointments.*") // Eager load the associated telemed pro
|
||||
->leftJoin("telemed_pros", "telemed_pros.id", "appointments.telemed_pros_id")
|
||||
->leftJoin("patients", "patients.id", "appointments.patient_id")
|
||||
/* ->orderBy('appointment_time', 'desc') */ // Optional: sort by appointment time
|
||||
->get();
|
||||
|
||||
return response()->json($appointments, 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
|
||||
return response()->json(['error' => 'Failed to retrieve appointments'], 500);
|
||||
}
|
||||
}
|
||||
public function getMeetingHistory(Patient $patient, $filter = '12_months')
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'meeting_history', new Appointment);
|
||||
$currentMonth = Carbon::now();
|
||||
|
||||
// Filter logic
|
||||
switch ($filter) {
|
||||
case 'current_month':
|
||||
$startDate = $currentMonth->copy()->startOfMonth();
|
||||
break;
|
||||
case '1_month':
|
||||
$startDate = $currentMonth->copy()->subMonth()->startOfMonth();
|
||||
break;
|
||||
case '2_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(2)->startOfMonth();
|
||||
break;
|
||||
case '3_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(3)->startOfMonth();
|
||||
break;
|
||||
case '6_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(6)->startOfMonth();
|
||||
break;
|
||||
default: // Default to 12 months
|
||||
$startDate = $currentMonth->copy()->subMonths(12)->startOfMonth();
|
||||
}
|
||||
|
||||
$endDate = $currentMonth->endOfMonth();
|
||||
|
||||
// Fetch patient names and appointment counts directly from the database
|
||||
$monthlyData = Appointment::select(
|
||||
'patient_id',
|
||||
/* DB::raw('COUNT(*) as appointment_count'), */
|
||||
'appointment_time',
|
||||
'appointment_date',
|
||||
'start_time',
|
||||
'end_time',
|
||||
'duration',
|
||||
'id'
|
||||
)
|
||||
->where("patient_id", $patient->id)
|
||||
->whereNotNull("end_time")
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
|
||||
->get();
|
||||
|
||||
$patients = [];
|
||||
|
||||
foreach ($monthlyData as $dataPoint) {
|
||||
$patientName = $dataPoint->patient->first_name . " " . $dataPoint->patient->last_name; // Assuming 'name' is the field representing patient names
|
||||
/* $appointmentCount = $dataPoint->appointment_count; */
|
||||
$start_time = $dataPoint->start_time;
|
||||
$end_time = $dataPoint->end_time;
|
||||
$duration = $dataPoint->duration;
|
||||
$appointment_time = $dataPoint->appointment_time;
|
||||
$appointment_date = $dataPoint->appointment_date;
|
||||
$id = $dataPoint->id;
|
||||
|
||||
$patients[] = [
|
||||
'patient_name' => $patientName,
|
||||
'appointment_time' => $appointment_time,
|
||||
'appointment_date' => $appointment_date,
|
||||
/* 'appointment_count' => $appointmentCount, */
|
||||
'start_time' => $start_time,
|
||||
'end_time' => $end_time,
|
||||
'duration' => $duration,
|
||||
'id' => $id,
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'patients' => $patients,
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
|
||||
return response()->json(['error' => 'Failed to retrieve appointments'], 500);
|
||||
}
|
||||
}
|
||||
public function getAppointmentByid($patient, $appointment, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Appointment);
|
||||
// Assuming user can be either telemedPro or patient
|
||||
$data = Appointment::select('appointments.*', 'telemed_pros.name as agent_name')
|
||||
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', '=', 'telemed_pros.id')
|
||||
->where('appointments.patient_id', $patient)
|
||||
->where('appointments.id', $appointment)
|
||||
->first();
|
||||
// dd($data);
|
||||
return response()->json(['data' => $data]);
|
||||
} catch (AuthorizationException $e) {
|
||||
|
||||
return response()->json(['error' => 'Failed to retrieve appointments'], 500);
|
||||
}
|
||||
}
|
||||
public function bookAppointment(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Appointment);
|
||||
$validatedData = $request->validate([
|
||||
/* 'telemed_pros_id' => 'required|exists:telemed_pros,id', */
|
||||
'patient_id' => 'required|exists:patients,id',
|
||||
'appointment_time' => 'required|date_format:H:i:s',
|
||||
'appointment_date' => 'required|date_format:Y-m-d',
|
||||
'patient_name' => 'required',
|
||||
'patient_email' => 'required',
|
||||
'timezone' => 'required',
|
||||
]);
|
||||
try {
|
||||
$tz = new DateTimeZone($validatedData['timezone']);
|
||||
$standardTz = $tz->getName();
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'message' => $e->getMessage()
|
||||
], 400);
|
||||
}
|
||||
try {
|
||||
$timezoneMap = [
|
||||
'EST' => 'America/New_York',
|
||||
'EDT' => 'America/New_York',
|
||||
'CST' => 'America/Chicago',
|
||||
'CDT' => 'America/Chicago',
|
||||
'MST' => 'America/Denver',
|
||||
'MDT' => 'America/Denver',
|
||||
'PST' => 'America/Los_Angeles',
|
||||
'PDT' => 'America/Los_Angeles',
|
||||
// Add more mappings as needed
|
||||
];
|
||||
$timezone = $validatedData['timezone'];
|
||||
if (array_key_exists($timezone, $timezoneMap)) {
|
||||
$timezone = $timezoneMap[$timezone];
|
||||
}
|
||||
|
||||
$appointmentDateTime = new DateTime(
|
||||
$validatedData['appointment_date'] . ' ' . $validatedData['appointment_time'],
|
||||
new DateTimeZone($timezone)
|
||||
);
|
||||
|
||||
$appointmentDateTime->setTimezone(new DateTimeZone('UTC'));
|
||||
|
||||
$validatedData['appointment_time'] = $appointmentDateTime->format('H:i:s');
|
||||
$validatedData['appointment_date'] = $appointmentDateTime->format('Y-m-d');
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'message' => $e->getMessage()
|
||||
], 400);
|
||||
}
|
||||
|
||||
$availableTelemedPros = Telemedpro::select("telemed_pros.id", "telemed_pros.name")/* ->where('is_busy', false) */
|
||||
->leftJoin('appointments', function ($join) use ($validatedData) {
|
||||
$join->on('telemed_pros.id', '=', 'appointments.telemed_pros_id')
|
||||
->where('appointments.appointment_time', '=', $validatedData['appointment_time'])
|
||||
->where('appointments.appointment_date', '=', $validatedData['appointment_date']);
|
||||
})
|
||||
->whereNull('appointments.id')
|
||||
->first();
|
||||
|
||||
if (!$availableTelemedPros)
|
||||
return response()->json([
|
||||
'message' => 'Appointment time not available'
|
||||
], 400);
|
||||
|
||||
$existingAppointment = Appointment::where('telemed_pros_id', $availableTelemedPros->id)
|
||||
->where('appointment_time', $validatedData['appointment_time'])
|
||||
->where('appointment_date', $validatedData['appointment_date'])
|
||||
->first();
|
||||
|
||||
if ($existingAppointment) {
|
||||
return response()->json([
|
||||
'message' => 'Appointment time not available'
|
||||
], 400);
|
||||
}
|
||||
$validatedData['telemed_pros_id'] = $availableTelemedPros->id;
|
||||
$validatedData['status'] = 'pending';
|
||||
|
||||
// Create the appointment
|
||||
$appointment = Appointment::create($validatedData);
|
||||
$appointment_booking_tokens = $this->bookAppointmentApi($appointment, $availableTelemedPros);
|
||||
$appointment->agent_call_token = $appointment_booking_tokens['tokenAgent'];
|
||||
$appointment->patient_call_token = $appointment_booking_tokens['tokenPatient'];
|
||||
$appointment->save();
|
||||
|
||||
PatientRegActivity::create([
|
||||
'patient_id' => $validatedData['patient_id'],
|
||||
'activity' => 'patient_appointment_booked'
|
||||
]);
|
||||
$patient = $appointment->patient;
|
||||
$datetimeUtc = $appointment->appointment_date . ' ' . $appointment->appointment_time;
|
||||
$dateTimeUtc = Carbon::createFromFormat('Y-m-d H:i:s', $datetimeUtc, 'UTC');
|
||||
$appointmentTimeZone = new CarbonTimeZone($appointment->timezone);
|
||||
$dateTimeInAppointmentTimeZone = $dateTimeUtc->setTimezone($appointmentTimeZone);
|
||||
$appointment->appointment_date = $appointmentDate = $dateTimeInAppointmentTimeZone->format('Y-m-d');
|
||||
$appointment->appointment_time = $appointmentTime = $dateTimeInAppointmentTimeZone->format('H:i:s');
|
||||
$setting = Setting::find(1);
|
||||
//event(new AppointmentBooked($appointment));
|
||||
$cart = Cart::find($request->input("cart_id"));
|
||||
$cart->appointment_id = $appointment->id;
|
||||
$cart->save();
|
||||
return response()->json([
|
||||
'message' => 'Appointment booked successfully',
|
||||
'meeting_id' => $appointment->agent_call_token,
|
||||
'appointment' => $appointment,
|
||||
'appointment_time' => $validatedData['appointment_time'],
|
||||
'appointment_date' => $validatedData['appointment_date']
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
|
||||
return response()->json(['error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
public function editAppointment(Appointment $appointment, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Appointment);
|
||||
$validatedData = $request->validate([
|
||||
'patient_id' => 'sometimes|exists:patients,id',
|
||||
'appointment_time' => 'sometimes|date_format:H:i:s',
|
||||
'appointment_date' => 'sometimes|date_format:Y-m-d',
|
||||
'patient_name' => 'sometimes|string',
|
||||
'patient_email' => 'sometimes|email',
|
||||
'timezone' => 'sometimes|string',
|
||||
]);
|
||||
|
||||
if (isset($validatedData['timezone'])) {
|
||||
try {
|
||||
$tz = new DateTimeZone($validatedData['timezone']);
|
||||
$standardTz = $tz->getName();
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'message' => $e->getMessage()
|
||||
], 400);
|
||||
}
|
||||
|
||||
$timezoneMap = [
|
||||
'EST' => 'America/New_York',
|
||||
'EDT' => 'America/New_York',
|
||||
'CST' => 'America/Chicago',
|
||||
'CDT' => 'America/Chicago',
|
||||
'MST' => 'America/Denver',
|
||||
'MDT' => 'America/Denver',
|
||||
'PST' => 'America/Los_Angeles',
|
||||
'PDT' => 'America/Los_Angeles',
|
||||
// Add more mappings as needed
|
||||
];
|
||||
|
||||
$timezone = $validatedData['timezone'];
|
||||
if (array_key_exists($timezone, $timezoneMap)) {
|
||||
$timezone = $timezoneMap[$timezone];
|
||||
}
|
||||
|
||||
if (isset($validatedData['appointment_date']) && isset($validatedData['appointment_time'])) {
|
||||
try {
|
||||
$appointmentDateTime = new DateTime(
|
||||
$validatedData['appointment_date'] . ' ' . $validatedData['appointment_time'],
|
||||
new DateTimeZone($timezone)
|
||||
);
|
||||
|
||||
$appointmentDateTime->setTimezone(new DateTimeZone('UTC'));
|
||||
|
||||
$validatedData['appointment_time'] = $appointmentDateTime->format('H:i:s');
|
||||
$validatedData['appointment_date'] = $appointmentDateTime->format('Y-m-d');
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'message' => $e->getMessage()
|
||||
], 400);
|
||||
}
|
||||
|
||||
// Check if the new time slot is available
|
||||
$availableTelemedPros = Telemedpro::select("telemed_pros.id", "telemed_pros.name")
|
||||
->leftJoin('appointments', function ($join) use ($validatedData, $appointment) {
|
||||
$join->on('telemed_pros.id', '=', 'appointments.telemed_pros_id')
|
||||
->where('appointments.appointment_time', '=', $validatedData['appointment_time'])
|
||||
->where('appointments.appointment_date', '=', $validatedData['appointment_date'])
|
||||
->where('appointments.id', '!=', $appointment->id); // Exclude the current appointment
|
||||
})
|
||||
->whereNull('appointments.id')
|
||||
->first();
|
||||
|
||||
if (!$availableTelemedPros) {
|
||||
return response()->json([
|
||||
'message' => 'New appointment time not available'
|
||||
], 400);
|
||||
}
|
||||
|
||||
// Update the telemed_pros_id if it's different
|
||||
if ($availableTelemedPros->id !== $appointment->telemed_pros_id) {
|
||||
$validatedData['telemed_pros_id'] = $availableTelemedPros->id;
|
||||
|
||||
// Re-book the appointment with the new telemed pro
|
||||
$appointment_booking_tokens = $this->bookAppointmentApi($appointment, $availableTelemedPros);
|
||||
$validatedData['agent_call_token'] = $appointment_booking_tokens['tokenAgent'];
|
||||
$validatedData['patient_call_token'] = $appointment_booking_tokens['tokenPatient'];
|
||||
}
|
||||
}
|
||||
|
||||
// Update the appointment
|
||||
$appointment->update($validatedData);
|
||||
|
||||
// Update related cart if it exists
|
||||
$cart = Cart::where('appointment_id', $appointment->id)->first();
|
||||
if ($cart) {
|
||||
$cart->appointment_id = $appointment->id;
|
||||
$cart->save();
|
||||
}
|
||||
|
||||
// Convert appointment time to the specified timezone for the response
|
||||
$datetimeUtc = $appointment->appointment_date . ' ' . $appointment->appointment_time;
|
||||
$dateTimeUtc = Carbon::createFromFormat('Y-m-d H:i:s', $datetimeUtc, 'UTC');
|
||||
$appointmentTimeZone = new CarbonTimeZone($appointment->timezone);
|
||||
$dateTimeInAppointmentTimeZone = $dateTimeUtc->setTimezone($appointmentTimeZone);
|
||||
$appointmentDate = $dateTimeInAppointmentTimeZone->format('Y-m-d');
|
||||
$appointmentTime = $dateTimeInAppointmentTimeZone->format('H:i:s');
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Appointment updated successfully',
|
||||
'meeting_id' => $appointment->agent_call_token,
|
||||
'appointment' => $appointment,
|
||||
'appointment_time' => $appointmentTime,
|
||||
'appointment_date' => $appointmentDate
|
||||
]);
|
||||
}
|
||||
} catch (AuthorizationException $e) {
|
||||
return response()->json(['error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
public function bookAppointmentApi($appointment, $availableTelemedPros)
|
||||
{
|
||||
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'edit', new Appointment);
|
||||
$roomName = 'appointment-' . $appointment->id . "-" . uniqid();
|
||||
$opts = (new RoomCreateOptions())
|
||||
->setName($roomName)
|
||||
->setEmptyTimeout(10)
|
||||
->setMaxParticipants(5);
|
||||
$host = "https://plugnmeet.codelfi.com";
|
||||
$svc = new RoomServiceClient($host, config('app.LK_API_KEY'), config('app.LK_API_SECRET'));
|
||||
$room = $svc->createRoom($opts);
|
||||
|
||||
$participantPatientName = "patient-" . uniqid() . $appointment->patient->first_name . " " . $appointment->patient->last_name;
|
||||
|
||||
$tokenOptionsPatient = (new AccessTokenOptions())
|
||||
->setIdentity($participantPatientName);
|
||||
$videoGrantPatient = (new VideoGrant())
|
||||
->setRoomJoin()
|
||||
->setRoomName($roomName);
|
||||
$tokenPatient = (new AccessToken(config('app.LK_API_KEY'), config('app.LK_API_SECRET')))
|
||||
->init($tokenOptionsPatient)
|
||||
->setGrant($videoGrantPatient)
|
||||
->toJwt();
|
||||
|
||||
$participantAgentName = "agent-" . uniqid() . $availableTelemedPros->name;
|
||||
$tokenOptionsAgent = (new AccessTokenOptions())
|
||||
->setIdentity($participantAgentName);
|
||||
$videoGrantAgent = (new VideoGrant())
|
||||
->setRoomJoin()
|
||||
->setRoomName($roomName);
|
||||
$tokenAgent = (new AccessToken(config('app.LK_API_KEY'), config('app.LK_API_SECRET')))
|
||||
->init($tokenOptionsAgent)
|
||||
->setGrant($videoGrantAgent)
|
||||
->toJwt();
|
||||
return [
|
||||
'tokenPatient' => $tokenPatient,
|
||||
'tokenAgent' => $tokenAgent,
|
||||
];
|
||||
} catch (AuthorizationException | Error | Exception | TwirpError $e) {
|
||||
|
||||
return response()->json(['error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function availableSlots($date)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'book_appointment', new Appointment);
|
||||
// Ensure date is in a valid format
|
||||
$date = Carbon::parse($date);
|
||||
$originalDate = Carbon::parse($date);
|
||||
|
||||
// Generate all possible 30-minute slots between 9 AM and 4 PM
|
||||
$slots = collect();
|
||||
$startTime = Carbon::parse($date)->subHours(24)->setTime(9, 0, 0);
|
||||
$endTime = Carbon::parse($date)->addHours(24)->setTime(16, 0, 0);
|
||||
while ($startTime < $endTime) {
|
||||
$slots->push($startTime->format('Y-m-d H:i:s'));
|
||||
$startTime->addMinutes(15);
|
||||
}
|
||||
|
||||
/* $user = Patient::find($patient_id); */
|
||||
// Filter out booked slots
|
||||
$bookedAppointments = Appointment::where('appointment_date', '>=', $date->format('Y-m-d'))
|
||||
->where('appointment_date', '<', $date->addDay()->format('Y-m-d'))
|
||||
->pluck('appointment_date');
|
||||
|
||||
$availableSlots = $slots->diff($bookedAppointments);
|
||||
|
||||
$formattedSlots = $availableSlots->map(function ($slot) {
|
||||
$start = Carbon::parse($slot);
|
||||
$startTime = $start->format('Y-m-d H:i:s');
|
||||
return $startTime;
|
||||
});
|
||||
|
||||
// Additional checking if slot is booked
|
||||
$formattedSlots = $formattedSlots->filter(function ($slot) use ($originalDate) {
|
||||
$time = Carbon::parse($slot);
|
||||
return !Appointment::where('appointment_time', $time->format('H:i:s'))
|
||||
->where('appointment_date', $originalDate->format('Y-m-d'))
|
||||
->exists();
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'available_slots' => $formattedSlots->toArray()
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
|
||||
return response()->json(['error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
public function getItemByOrder($order_id)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Appointment);
|
||||
$labkits = LabkitOrderItem::leftJoin(
|
||||
'lab_kit',
|
||||
'labkit_order_items.lab_kit_id',
|
||||
'lab_kit.id'
|
||||
)
|
||||
->leftJoin(
|
||||
'items',
|
||||
'items.id',
|
||||
'labkit_order_items.item_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'plans_v1',
|
||||
'plans_v1.id',
|
||||
'items.plans_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'carts',
|
||||
'carts.id',
|
||||
'labkit_order_items.cart_id'
|
||||
)
|
||||
->where('carts.id', $order_id)
|
||||
->select(
|
||||
'labkit_order_items.id',
|
||||
'labkit_order_items.status',
|
||||
'labkit_order_items.result',
|
||||
'lab_kit.name as lab_kit_name',
|
||||
'plans_v1.id as product_id',
|
||||
'plans_v1.title as product_name'
|
||||
)
|
||||
->get();
|
||||
return response()->json([
|
||||
'order_item' => $labkits
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
|
||||
return response()->json(['error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
public function getAgentLastAppointment(Patient $patient, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Appointment);
|
||||
$appointments = Appointment::select(
|
||||
"patients.first_name",
|
||||
"patients.last_name",
|
||||
"telemed_pros.name as agent_name",
|
||||
"appointments.*",
|
||||
"carts.shipping_address1",
|
||||
"carts.shipping_address2",
|
||||
"carts.id as order_id",
|
||||
"carts.shipping_city",
|
||||
"carts.shipping_state",
|
||||
"carts.shipping_zipcode",
|
||||
"carts.shipping_country"
|
||||
|
||||
) // Eager load the associated telemed pro
|
||||
->leftJoin("telemed_pros", "telemed_pros.id", "appointments.telemed_pros_id")
|
||||
->leftJoin("patients", "patients.id", "appointments.patient_id")
|
||||
->leftJoin("carts", "carts.appointment_id", "appointments.id")
|
||||
->where("appointments.patient_id", $patient->id)
|
||||
->orderBy('appointments.created_at', 'desc')
|
||||
->first();
|
||||
|
||||
$upcoming_appointments = Appointment::select(
|
||||
"patients.first_name",
|
||||
"patients.last_name",
|
||||
"telemed_pros.name as agent_name",
|
||||
"appointments.*",
|
||||
"carts.shipping_address1",
|
||||
"carts.shipping_address2",
|
||||
"carts.id as order_id",
|
||||
"carts.shipping_city",
|
||||
"carts.shipping_state",
|
||||
"carts.shipping_zipcode",
|
||||
"carts.shipping_country",
|
||||
"appointments.id as order_appointment_id"
|
||||
|
||||
) // Eager load the associated telemed pro
|
||||
->leftJoin("telemed_pros", "telemed_pros.id", "appointments.telemed_pros_id")
|
||||
->leftJoin("patients", "patients.id", "appointments.patient_id")
|
||||
->leftJoin("carts", "carts.appointment_id", "appointments.id")
|
||||
//->where('appointments.appointment_date', '<', $appointments->appointment_date)
|
||||
->where("appointments.patient_id", $patient->id)
|
||||
->where("appointments.status", 'pending')
|
||||
->whereNull("appointments.start_time")
|
||||
|
||||
->orderBy('appointments.created_at', 'desc')
|
||||
->get();
|
||||
|
||||
if (!$appointments)
|
||||
return response()->json(['error' => 'No Record found.'], 500);
|
||||
|
||||
$timezone = config('app.timezone');
|
||||
if ($appointments->timezone) {
|
||||
|
||||
$tz = new DateTimeZone($appointments->timezone);
|
||||
|
||||
$standardTz = $tz->getName();
|
||||
$appointmentDateTime = $appointmentCurrent = Carbon::parse($appointments->appointment_date . ' ' . $appointments->appointment_time)->shiftTimezone($standardTz);
|
||||
//$appointmentDateTime = $appointmentDateTime->shiftTimezone($timezone);
|
||||
|
||||
$appointmentCurrent = Carbon::now($timezone);
|
||||
|
||||
$diff = $appointmentDateTime->diff($appointmentCurrent);
|
||||
|
||||
if ($diff->invert == 0) {
|
||||
// Appointment is in future, increment count
|
||||
$diff = $diff->format('0 days 0 hours 0 minutes 0 seconds');
|
||||
} else
|
||||
|
||||
$diff = $diff->format('%a days %h hours %i minutes %s seconds');
|
||||
} else {
|
||||
$diff = "";
|
||||
}
|
||||
$filePath = public_path("assets/profiles/{$patient->id}.png");
|
||||
|
||||
if ($patient->profile_picture)
|
||||
$patient->profile_picture = $this->url->to("storage/profile_pictures", $patient->profile_picture);
|
||||
else
|
||||
$patient->profile_picture = null;
|
||||
|
||||
if (File::exists($filePath)) {
|
||||
$patient->url = "/assets/profiles/{$patient->id}.png";
|
||||
} else {
|
||||
$patient->url = null;
|
||||
}
|
||||
foreach ($upcoming_appointments as $upcoming_appointment) {
|
||||
|
||||
if ($upcoming_appointment->timezone) {
|
||||
|
||||
$tz = new DateTimeZone($upcoming_appointment->timezone);
|
||||
|
||||
$standardTz = $tz->getName();
|
||||
$appointmentDateTime = $appointmentCurrent = Carbon::parse($upcoming_appointment->appointment_date . ' ' . $upcoming_appointment->appointment_time)->shiftTimezone($standardTz);
|
||||
//$appointmentDateTime = $appointmentDateTime->shiftTimezone($timezone);
|
||||
|
||||
$appointmentCurrent = Carbon::now($timezone);
|
||||
|
||||
$diff = $appointmentDateTime->diff($appointmentCurrent);
|
||||
|
||||
if ($diff->invert == 0) {
|
||||
// Appointment is in future, increment count
|
||||
$diff = $diff->format('0 days 0 hours 0 minutes 0 seconds');
|
||||
} else
|
||||
|
||||
$diff = $diff->format('%a days %h hours %i minutes %s seconds');
|
||||
} else {
|
||||
$diff = "";
|
||||
}
|
||||
|
||||
$upcoming_appointment->items_data = $this->getOrderItems($upcoming_appointment->order_id);
|
||||
$upcoming_appointment->time_diff = $diff;
|
||||
}
|
||||
|
||||
return response()->json(['upcoming_appointments' => $upcoming_appointments, 'appointment' => $appointments, 'time_diff' => $diff, 'patient' => $patient, "items_data" => $this->getOrderItems($appointments->order_id)], 200);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => 'Failed to retrieve appointments'], 500);
|
||||
}
|
||||
}
|
||||
}
|
110
app/Http/Controllers/Admin/Api/CalendlyController.php
Normal file
110
app/Http/Controllers/Admin/Api/CalendlyController.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Classes\Calendly;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Setting;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Illuminate\Http\Request;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class CalendlyController extends Controller
|
||||
{
|
||||
public function getCalendlyAuthUrl()
|
||||
{
|
||||
$calendly = new Calendly();
|
||||
$url = $calendly->authUrl();
|
||||
return response()->json(['url' => $url]);
|
||||
}
|
||||
public function getRedirectCode(Request $request)
|
||||
{
|
||||
$calendly = new Calendly();
|
||||
$calendly->authorize($request->input("code"));
|
||||
return redirect("https://webmd-provider.codelfi.com/build/admin/dashboard");
|
||||
}
|
||||
public function getEvent(Request $request)
|
||||
{
|
||||
$calendly = new Calendly();
|
||||
$events = $calendly->eventTypes();
|
||||
$final_event = [];
|
||||
foreach ($events as $event) {
|
||||
$array = [];
|
||||
$array['slug'] = $event['slug'];
|
||||
$array['uri'] = $event['uri'];
|
||||
$array['type'] = $event['type'];
|
||||
array_push($final_event, $array);
|
||||
//$final_event[] += $array;
|
||||
}
|
||||
return response()->json(['message' => 'Admin has been authenticated.', 'events' => $final_event], 200);
|
||||
}
|
||||
public function setEvent(Request $request)
|
||||
{
|
||||
$uri = $request->input('url');
|
||||
$calendly = new Calendly();
|
||||
$calendly->setEventUri($uri);
|
||||
return response()->json(['message' => 'Event URI selected.'], 200);
|
||||
}
|
||||
public function resetEventUri()
|
||||
{
|
||||
$calendly = new Calendly();
|
||||
$calendly->resetEventUri();
|
||||
return response()->json(['message' => 'Event URI reset!.'], 200);
|
||||
}
|
||||
|
||||
public function getAvailableDates(Request $request)
|
||||
{
|
||||
$setting = Setting::find(1);
|
||||
$month = $request->input("month");
|
||||
$timezone = $request->input("timezone");
|
||||
|
||||
$calendly = new Calendly();
|
||||
|
||||
$slots = $calendly->getAvailableDates($setting->event_type, $month, $timezone);
|
||||
|
||||
return response()->json(['slots' => $slots], 200);
|
||||
}
|
||||
public function generateHexString($length = 32)
|
||||
{
|
||||
return bin2hex(random_bytes($length / 2));
|
||||
}
|
||||
public function generateRandomString($length = 37)
|
||||
{
|
||||
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-';
|
||||
$charactersLength = strlen($characters);
|
||||
$randomString = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$randomString .= $characters[rand(0, $charactersLength - 1)];
|
||||
}
|
||||
return $randomString;
|
||||
}
|
||||
|
||||
public function bookSchedule(Request $request)
|
||||
{
|
||||
$referel = $url = $request->input("url");
|
||||
$patient_email = $request->input("patient_email");
|
||||
$patient_name = $request->input("patient_name");
|
||||
$timezone = $request->input("timezone");
|
||||
$calendly = new Calendly();
|
||||
|
||||
$attempts = 0;
|
||||
$maxAttempts = 3;
|
||||
|
||||
while ($attempts < $maxAttempts) {
|
||||
$response = $calendly->bookEvent($url, $patient_name, $patient_email, $timezone);
|
||||
$response = json_decode($response, true);
|
||||
|
||||
if ($response && isset($response["event"]['start_time'])) {
|
||||
return response()->json(['success' => 'Event has been booked. ' . $response["event"]['start_time']], 200);
|
||||
}
|
||||
|
||||
$attempts++;
|
||||
}
|
||||
|
||||
return response()->json(['error' => 'Failed to complete the request after ' . $maxAttempts . ' attempts', 'response' => $response], 400);
|
||||
}
|
||||
}
|
366
app/Http/Controllers/Admin/Api/CalendlyControllerOld.php
Normal file
366
app/Http/Controllers/Admin/Api/CalendlyControllerOld.php
Normal file
@ -0,0 +1,366 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Illuminate\Http\Request;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class CalendlyControllerOld extends Controller
|
||||
{
|
||||
protected $clientId = "eOk7Vb-60_l6U4WmAe9y9MThi-WKGzEuyru_B3I2jwk";
|
||||
protected $clientSecret = "EYLgGEHLudI65wdqG7Qz1azZwFCFx8kvikXYoM2EbiE";
|
||||
protected $redirectUri = 'https://hgh.codelfi.com/calendly/redirect-code/';
|
||||
|
||||
// Generate Calendly authorization URL
|
||||
public function getCalendlyAuthUrl()
|
||||
{
|
||||
$url = 'https://auth.calendly.com/oauth/authorize';
|
||||
$url .= '?client_id=' . urlencode($this->clientId);
|
||||
$url .= '&response_type=code';
|
||||
$url .= '&redirect_uri=' . urlencode($this->redirectUri);
|
||||
|
||||
return response()->json(['url' => $url]);
|
||||
}
|
||||
|
||||
// Handle the redirect with authorization code and exchange for access token
|
||||
public function getRedirectCode(Request $request)
|
||||
{
|
||||
// Get the authorization code from the request
|
||||
$authorizationCode = $request->input('code');
|
||||
|
||||
if (!$authorizationCode) {
|
||||
return response()->json(['error' => 'Authorization code is missing'], 400);
|
||||
}
|
||||
//return $this->getCalendlyUserAndAvailability();
|
||||
// Call method to fetch access token and cache it
|
||||
$this->getAccessTokenFromCode($authorizationCode);
|
||||
return response()->json(['message' => 'Admin has been authenticated.'], 200);
|
||||
}
|
||||
// Handle the redirect with authorization code and exchange for access token
|
||||
public function getAvailabeSlotDates(Request $request)
|
||||
{
|
||||
return $this->getCalendlyUserAndAvailability();
|
||||
// Call method to fetch access token and cache it
|
||||
}
|
||||
|
||||
// Fetch or refresh access token if needed
|
||||
public function getAccessToken()
|
||||
{
|
||||
// Check if the access token exists in cache
|
||||
if (Cache::has('calendly_access_token')) {
|
||||
return Cache::get('calendly_access_token');
|
||||
}
|
||||
|
||||
// If no token is available, return error or trigger refresh
|
||||
return response()->json(['error' => 'No valid access token. Please authenticate again.'], 401);
|
||||
}
|
||||
|
||||
// Exchange authorization code for access token and store it in cache
|
||||
private function getAccessTokenFromCode($authorizationCode)
|
||||
{
|
||||
$tokenUrl = 'https://auth.calendly.com/oauth/token';
|
||||
|
||||
// Use GuzzleHttp client to make the POST request
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
$response = $client->post($tokenUrl, [
|
||||
'form_params' => [
|
||||
'grant_type' => 'authorization_code',
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
'redirect_uri' => $this->redirectUri,
|
||||
'code' => $authorizationCode,
|
||||
],
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
],
|
||||
]);
|
||||
|
||||
// Decode the JSON response
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
// Store access token and refresh token in cache with an expiration
|
||||
//Cache::put('calendly_access_token', $data['access_token'], now()->addSeconds($data['expires_in']));
|
||||
//Cache::put('calendly_refresh_token', $data['refresh_token'], now()->addDays(30)); // Refresh tokens don't expire until used
|
||||
|
||||
return response()->json([
|
||||
'access_token' => $data['access_token'],
|
||||
'refresh_token' => $data['refresh_token'],
|
||||
'token_type' => $data['token_type'],
|
||||
'expires_in' => $data['expires_in']
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
// Handle errors
|
||||
return response()->json(['error' => 'Failed to fetch access token: ' . $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
// Use refresh token to get a new access token when expired
|
||||
private function refreshAccessToken()
|
||||
{
|
||||
if (!Cache::has('calendly_refresh_token')) {
|
||||
return response()->json(['error' => 'Refresh token not available.'], 401);
|
||||
}
|
||||
|
||||
$refreshToken = Cache::get('calendly_refresh_token');
|
||||
|
||||
$tokenUrl = 'https://auth.calendly.com/oauth/token';
|
||||
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
$response = $client->post($tokenUrl, [
|
||||
'form_params' => [
|
||||
'grant_type' => 'refresh_token',
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
'refresh_token' => $refreshToken,
|
||||
],
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
],
|
||||
]);
|
||||
|
||||
// Decode the response
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
|
||||
// Store the new access token and refresh token in cache
|
||||
Cache::put('calendly_access_token', $data['access_token'], now()->addSeconds($data['expires_in']));
|
||||
Cache::put('calendly_refresh_token', $data['refresh_token'], now()->addDays(30)); // New refresh token
|
||||
|
||||
return $data['access_token'];
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => 'Failed to refresh access token: ' . $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
function getCalendlyUserAndAvailability()
|
||||
{
|
||||
// Get the access token from cache
|
||||
$accessToken = Cache::get('calendly_access_token');
|
||||
|
||||
// If the token is not in cache, fetch a new one
|
||||
if (!$accessToken) {
|
||||
$accessToken = $this->fetchCalendlyAccessToken();
|
||||
}
|
||||
|
||||
if (!$accessToken) {
|
||||
return response()->json(['error' => 'Token Expired!'], 500);
|
||||
}
|
||||
|
||||
// 1. Call the /users/me API to get user information
|
||||
$client = new Client();
|
||||
try {
|
||||
$response = $client->request('GET', 'https://api.calendly.com/users/me', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
'Content-Type' => 'application/json',
|
||||
]
|
||||
]);
|
||||
|
||||
$data = json_decode($response->getBody(), true);
|
||||
$userUri = $data['resource']['uri'];
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => 'Failed to fetch user details: ' . $e->getMessage()], 500);
|
||||
}
|
||||
|
||||
// 2. Use the user URI to fetch availability schedules
|
||||
try {
|
||||
$availabilityResponse = $client->request('GET', 'https://api.calendly.com/user_availability_schedules', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'query' => [
|
||||
'user' => $userUri
|
||||
]
|
||||
]);
|
||||
|
||||
$availabilityData = json_decode($availabilityResponse->getBody(), true);
|
||||
// Get the rules from the availability data
|
||||
$rules = $availabilityData['collection'][0]['rules'];
|
||||
|
||||
// Map day of the week to the date in the current week
|
||||
$weekDates = $this->getCurrentWeekDates(); // Get this week's dates
|
||||
|
||||
// Add the corresponding date to each rule
|
||||
$updatedRules = array_map(function ($rule) use ($weekDates) {
|
||||
$wday = $rule['wday'];
|
||||
// Check if we have a corresponding date for this weekday
|
||||
if (isset($weekDates[$wday])) {
|
||||
$rule['date'] = $weekDates[$wday]; // Add date to the rule
|
||||
} else {
|
||||
$rule['date'] = null; // No availability on that day
|
||||
}
|
||||
return $rule;
|
||||
}, $rules);
|
||||
|
||||
// Add the updated rules with dates back to the response
|
||||
$availabilityData['collection'][0]['rules'] = $updatedRules; // Get the rules from the availability data
|
||||
$rules = $availabilityData['collection'][0]['rules'];
|
||||
|
||||
// Map day of the week to the date in the current week
|
||||
$weekDates = $this->getCurrentWeekDates(); // Get this week's dates
|
||||
|
||||
// Add the corresponding date to each rule
|
||||
$updatedRules = array_map(function ($rule) use ($weekDates) {
|
||||
$wday = $rule['wday'];
|
||||
// Check if we have a corresponding date for this weekday
|
||||
if (isset($weekDates[$wday])) {
|
||||
$rule['date'] = $weekDates[$wday]; // Add date to the rule
|
||||
} else {
|
||||
$rule['date'] = null; // No availability on that day
|
||||
}
|
||||
return $rule;
|
||||
}, $rules);
|
||||
|
||||
$filteredDates = array_values(array_filter(array_map(function ($rule) {
|
||||
return !empty($rule['intervals']) ? $rule['date'] : null;
|
||||
}, $updatedRules)));
|
||||
// Add the updated rules with dates back to the response
|
||||
$availabilityData['collection'][0]['rules'] = $updatedRules;
|
||||
return response()->json($availabilityData, 200);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => 'Failed to fetch availability: ' . $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
private function getCurrentWeekDates()
|
||||
{
|
||||
$weekDates = [];
|
||||
|
||||
// Start from Sunday as 0, loop through the week
|
||||
for ($day = 0; $day < 7; $day++) {
|
||||
$carbonDate = Carbon::now()->startOfWeek()->addDays($day); // Start on Sunday
|
||||
$weekday = strtolower($carbonDate->format('l')); // Get the day name (sunday, monday, etc.)
|
||||
$weekDates[$weekday] = $carbonDate->toDateString(); // Store the date for that day
|
||||
}
|
||||
|
||||
return $weekDates; // Return array of week dates
|
||||
}
|
||||
// Helper function to fetch access token
|
||||
function fetchCalendlyAccessToken()
|
||||
{
|
||||
$client = new Client();
|
||||
try {
|
||||
$response = $client->post('https://auth.calendly.com/oauth/token', [
|
||||
'form_params' => [
|
||||
'grant_type' => 'authorization_code',
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
'redirect_uri' => $this->redirectUri,
|
||||
'code' => request()->input('code'), // Get authorization code from request
|
||||
],
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
]
|
||||
]);
|
||||
|
||||
$data = json_decode($response->getBody(), true);
|
||||
$accessToken = $data['access_token'];
|
||||
|
||||
// Store access token in cache for 2 hours
|
||||
Cache::put('calendly_access_token', $accessToken, 120 * 60);
|
||||
|
||||
return $accessToken;
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public function getAvailableTimes(Request $request)
|
||||
{
|
||||
try {
|
||||
// Validate start_time and end_time input
|
||||
/* $validatedData = $request->validate([
|
||||
'start_time' => 'required|date_format:Y-m-d\TH:i:s\Z',
|
||||
'end_time' => 'required|date_format:Y-m-d\TH:i:s\Z',
|
||||
]); */
|
||||
|
||||
// Get the access token from cache
|
||||
$accessToken = Cache::get('calendly_access_token');
|
||||
|
||||
// If the token is not in cache, fetch a new one
|
||||
if (!$accessToken) {
|
||||
$accessToken = $this->fetchCalendlyAccessToken();
|
||||
}
|
||||
|
||||
if (!$accessToken) {
|
||||
return response()->json(['error' => 'Unable to retrieve access token'], 500);
|
||||
}
|
||||
|
||||
// 1. Call the /users/me API to get user information
|
||||
$client = new Client();
|
||||
$response = $client->request('GET', 'https://api.calendly.com/users/me', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
'Content-Type' => 'application/json',
|
||||
]
|
||||
]);
|
||||
|
||||
$data = json_decode($response->getBody(), true);
|
||||
$userUri = $data['resource']['uri'];
|
||||
|
||||
// 1. Call the /users/me API to get user information
|
||||
$client = new Client();
|
||||
$responseEvent = $client->request('GET', 'https://api.calendly.com/event_types?user=' . $userUri, [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
'Content-Type' => 'application/json',
|
||||
]
|
||||
]);
|
||||
|
||||
$dataEvent = json_decode($responseEvent->getBody(), true);
|
||||
$even_type_url = $dataEvent['collection'][0]['uri'];
|
||||
$userUri = $data['resource']['uri'];
|
||||
|
||||
|
||||
$client = new Client();
|
||||
|
||||
// Prepare API endpoint with the required parameters
|
||||
$eventTypeUrl = 'https://api.calendly.com/event_type_available_times';
|
||||
$queryParams = [
|
||||
'event_type' => $even_type_url, //'https://api.calendly.com/event_types/60992c14-2f0b-42c2-af7b-95062d065600', // Use your event_type URL
|
||||
'start_time' => $request->input('start_time'),
|
||||
'end_time' => $request->input('end_time')
|
||||
];
|
||||
$str = "event_type=" . urlencode($queryParams['event_type']) . "&" . "start_time=" . urlencode($queryParams['start_time']) . "&" . "end_time=" . urlencode($queryParams['end_time']);
|
||||
$eventTypeUrl = $eventTypeUrl . "?" . ($str);
|
||||
// Send the request to Calendly
|
||||
$response = $client->request('GET', $eventTypeUrl, [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
// 'query' => $queryParams
|
||||
]);
|
||||
|
||||
$data = json_decode($response->getBody(), true);
|
||||
$processedTimes = array_map(function ($item) {
|
||||
$dateTime = new DateTime($item['start_time']);
|
||||
$readableTime = $dateTime->format('Y-m-d H:i'); // Format: YYYY-MM-DD h:mm AM/PM
|
||||
|
||||
return [
|
||||
'status' => $item['status'],
|
||||
'start_time' => $readableTime,
|
||||
'invitees_remaining' => $item['invitees_remaining'],
|
||||
'scheduling_url' => $item['scheduling_url']
|
||||
];
|
||||
}, $data['collection']);
|
||||
|
||||
// Extract scheduling URLs from available time slots
|
||||
$availableTimes = array_map(function ($slot) {
|
||||
return $slot['scheduling_url'];
|
||||
}, $data['collection']);
|
||||
|
||||
return response()->json([
|
||||
'available_times' => $processedTimes
|
||||
], 200);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => 'Failed to fetch available times: ' . $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
}
|
352
app/Http/Controllers/Admin/Api/DashboardController.php
Normal file
352
app/Http/Controllers/Admin/Api/DashboardController.php
Normal file
@ -0,0 +1,352 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Admin;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Item;
|
||||
use App\Models\Lab;
|
||||
use App\Models\MedicalHistoryAnswer;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Models\Plan;
|
||||
use App\Models\PlanV1;
|
||||
use App\Models\ProfileAnswer;
|
||||
use App\Models\QuestionBuilder;
|
||||
use App\Models\Telemedpro;
|
||||
use App\Permissions\Permissions;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Ods\Settings;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function getStats()
|
||||
{
|
||||
|
||||
|
||||
$date = Carbon::now();
|
||||
$startOfWeek = $date->startOfWeek(Carbon::MONDAY)->format("Y-m-d");
|
||||
$endDate = Carbon::now()->format('Y-m-d');
|
||||
$newPatients = self::getNewPatients($startOfWeek, $endDate);
|
||||
$newProviders = self::getNewProviders($newPatients, $endDate);
|
||||
$analytics = self::getAnalytics();
|
||||
$upcomingMeetings = Appointment::where('appointment_date', '>=', $date->toDateString())->count();
|
||||
return response()->json([
|
||||
'upcoming_meetings' => $upcomingMeetings,
|
||||
'new_customers' => $newPatients,
|
||||
'new_providers' => $newProviders,
|
||||
'analytics' => $analytics
|
||||
]);
|
||||
}
|
||||
protected function getNewPatients($newPatients, $endOfWeek)
|
||||
{
|
||||
$upcomingMeetings = Patient::where('created_at', '>=', $newPatients)
|
||||
->where('created_at', '<=', $endOfWeek)
|
||||
->count();
|
||||
return $upcomingMeetings;
|
||||
}
|
||||
protected function getNewProviders($newPatients, $endOfWeek)
|
||||
{
|
||||
$upcomingMeetings = Telemedpro::where('created_at', '>=', $newPatients)
|
||||
->where('created_at', '<=', $endOfWeek)
|
||||
->count();
|
||||
return $upcomingMeetings;
|
||||
}
|
||||
protected function getAnalytics($filter = '12_months')
|
||||
{
|
||||
$currentMonth = Carbon::now();
|
||||
|
||||
// Filter logic
|
||||
switch ($filter) {
|
||||
case 'current_month':
|
||||
$startDate = $currentMonth->copy()->startOfMonth();
|
||||
break;
|
||||
case '1_month':
|
||||
$startDate = $currentMonth->copy()->subMonth()->startOfMonth();
|
||||
break;
|
||||
case '2_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(2)->startOfMonth();
|
||||
break;
|
||||
case '3_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(3)->startOfMonth();
|
||||
break;
|
||||
case '6_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(6)->startOfMonth();
|
||||
break;
|
||||
default: // Default to 12 months
|
||||
$startDate = $currentMonth->copy()->subMonths(12)->startOfMonth();
|
||||
}
|
||||
|
||||
$endDate = $currentMonth->endOfMonth();
|
||||
|
||||
|
||||
$appointments = Appointment::with('patient')
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
->get();
|
||||
|
||||
$totalSessions = $appointments->count();
|
||||
$totalCallTime = 10; // Assuming you have some logic to calculate this
|
||||
if ($totalSessions != 0) {
|
||||
$avgSessionTime = $totalCallTime / $totalSessions;
|
||||
$avgSessionTime = round(($avgSessionTime / 60), 2);
|
||||
} else
|
||||
$avgSessionTime = '';
|
||||
|
||||
|
||||
$monthlyData = [];
|
||||
|
||||
// Loop through each month in the last 12 months
|
||||
for ($date = $startDate->copy(); $date->lte($endDate); $date->addMonth()) {
|
||||
$monthStart = $date->startOfMonth()->format('Y-m-d');
|
||||
$monthEnd = $date->copy()->endOfMonth()->format('Y-m-d'); // Key change here!
|
||||
|
||||
$monthAppointments = Appointment::with('patient')
|
||||
->whereBetween('created_at', [$monthStart, $monthEnd])
|
||||
->get();
|
||||
|
||||
|
||||
// Calculate any metrics you need from $monthAppointments
|
||||
$monthlyData[] = [
|
||||
'month' => $date->format('M'), // Example: Jan 2024
|
||||
'appointment_count' => $monthAppointments->count()
|
||||
// Add other metrics as needed
|
||||
];
|
||||
}
|
||||
$monthsList = [];
|
||||
$monthlySessionCount = [];
|
||||
|
||||
foreach ($monthlyData as $dataPoint) {
|
||||
$monthsList[] = $dataPoint['month'];
|
||||
$monthlySessionCount[] = $dataPoint['appointment_count'];
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
// 'total_sessions' => $totalSessions,
|
||||
'total_call_time' => $totalCallTime,
|
||||
// 'avg_session_time' => $avgSessionTime,
|
||||
'data' => array_values($monthlySessionCount),
|
||||
'months_list' => $monthsList,
|
||||
];
|
||||
}
|
||||
public function getAdminDetails(Request $request)
|
||||
{
|
||||
$user = Auth::guard('admin')->user();
|
||||
$permissionManager = new Permissions($user->role->permissions);
|
||||
$permissions = $permissionManager->permissionsApi();
|
||||
if (isset($user->image_path))
|
||||
$user->image_path = $this->url->to('/storage/profile_pictures/' . $user->image_path);
|
||||
else
|
||||
$user->image_path = Null;
|
||||
return response()->json([
|
||||
'admin_details' => $user,
|
||||
'permissions'=>$permissions
|
||||
]);
|
||||
}
|
||||
public function updateAdminDetails(Request $request)
|
||||
{
|
||||
$userId = Auth::guard('admin')->user()->id;
|
||||
$user = Admin::find($userId);
|
||||
|
||||
if($request->get('image'))
|
||||
{
|
||||
$image = $request->get('image');
|
||||
$fileName = 'profile-' . time();
|
||||
|
||||
$logo = base64_decode($image);
|
||||
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
||||
|
||||
$imageName = $fileName . '.' . $ext;
|
||||
Storage::disk('local')->put("/public/profile_pictures/" . $imageName, $logo);
|
||||
}
|
||||
|
||||
$user->name = $request->get('first_name');
|
||||
$user->last_name = $request->get('last_name');
|
||||
$user->phone_no = $request->get('phone_no');
|
||||
if ($request->get('image'))
|
||||
$user->image_path = $imageName;
|
||||
$user->save();
|
||||
return response()->json([
|
||||
'admin_details' => $user
|
||||
]);
|
||||
}
|
||||
public function uploadImage($image, $fileName, $path)
|
||||
{
|
||||
$logo = base64_decode($image);
|
||||
$filename = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[0]);
|
||||
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
||||
$imageName = $fileName . '.' . $ext;
|
||||
$path = $path . $imageName;
|
||||
file_put_contents($path, $logo);
|
||||
return $imageName;
|
||||
}
|
||||
public function index(Request $request){
|
||||
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'DashboardData', new Admin);
|
||||
$start_date = $request->get('start_date');
|
||||
$end_date = $request->get('end_date');
|
||||
$totalPatients = $this->getTotals($start_date,$end_date);
|
||||
$graphData = $this->graphData($start_date,$end_date);
|
||||
$patientActivity = $this->patientActivit($start_date,$end_date);
|
||||
$ordersData = $this->ordersData($start_date,$end_date);
|
||||
$completedMeetings = $this->completedMeetings($start_date,$end_date);
|
||||
$orders = $this->productsData($start_date,$end_date);
|
||||
return response()->json([
|
||||
'totals' =>$totalPatients,
|
||||
'graph_data'=>$graphData,
|
||||
'patient_reg_activity'=>$patientActivity,
|
||||
'orders_data'=>$ordersData,
|
||||
'completed_meetings'=>$completedMeetings,
|
||||
'products'=>$orders
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function getTotals($start_date,$end_date)
|
||||
{
|
||||
$totalPatients = Patient::
|
||||
where('created_at', '>=', $start_date." 00:00:00")
|
||||
->where('created_at', '<=', $end_date." 23:59:59")
|
||||
->count();
|
||||
$totalOrders = Cart::select(
|
||||
DB::raw("count(carts.id) as total_sales"),
|
||||
DB::raw("sum(carts.total_amount ) as sales_amount"),
|
||||
DB::raw("count(items.id) as products_sold")
|
||||
)
|
||||
->leftJoin('items','items.cart_id','carts.id')
|
||||
->where('carts.created_at', '>=', $start_date." 00:00:00")
|
||||
->where('carts.created_at', '<=', $end_date." 23:59:59")
|
||||
->where('carts.status','completed')
|
||||
->first();
|
||||
|
||||
return [
|
||||
'total_patints'=>$totalPatients,
|
||||
'total_orders'=>$totalOrders->total_sales,
|
||||
'total_amount'=>$totalOrders->sales_amount,
|
||||
'total_products_sold'=>$totalOrders->products_sold
|
||||
];
|
||||
}
|
||||
public function graphData($start_date,$end_date)
|
||||
{
|
||||
$dates = [];
|
||||
$sales =[];
|
||||
$totalMeetingsData =[];
|
||||
$startDate = Carbon::parse($start_date);
|
||||
$endDate = Carbon::parse($end_date);
|
||||
for ($date = $startDate; $date->lte($endDate); $date->addDay()) {
|
||||
//get total sales data
|
||||
$values = Cart::select(
|
||||
DB::raw('DATE(created_at) as date'),
|
||||
DB::raw("SUM(case when carts.status = 'completed' then carts.total_amount else 0 end) as amount"))
|
||||
->where('carts.created_at', '>=', $date->format("Y-m-d")." 00:00:00")
|
||||
->where('carts.created_at', '<=', $date->format("Y-m-d")." 23:59:59")
|
||||
->groupBy(DB::raw('DATE(created_at)'));
|
||||
$graphsValues = $values->first();
|
||||
// get total meetings
|
||||
$totalMeetings = Appointment::
|
||||
where('start_time', '>=', $date->format("Y-m-d")." 00:00:00")
|
||||
->where('start_time', '<=', $date->format("Y-m-d")." 23:59:59")
|
||||
->where('status', 'completed')
|
||||
->count();
|
||||
$dates[] = $date->format("M d/y");
|
||||
if($graphsValues)
|
||||
$sales[] = round($graphsValues->amount,2);
|
||||
else
|
||||
$sales[] = 0.00;
|
||||
|
||||
$totalMeetingsData[] = round($totalMeetings,2);
|
||||
}
|
||||
return [
|
||||
'dates'=>$dates,
|
||||
'data'=>
|
||||
[
|
||||
'total_sales'=>$sales,
|
||||
'total_meetings'=>$totalMeetingsData
|
||||
]
|
||||
];
|
||||
}
|
||||
public function patientActivit($start_date,$end_date){
|
||||
$patientActivity = PatientRegActivity::
|
||||
where('created_at', '>=', $start_date." 00:00:00")
|
||||
->where('created_at', '<=', $end_date." 23:59:59")
|
||||
->get();
|
||||
|
||||
$activity = $patientActivity->map(function ($query,$key){
|
||||
$patient = Patient::find($query->patient_id);
|
||||
if($query->activity=='patient_registered')
|
||||
{
|
||||
$query->activity = $patient->first_name. " ". $patient->last_name. " Singed Up";
|
||||
}
|
||||
if($query->activity=='patient_appointment_booked')
|
||||
{
|
||||
$query->activity = $patient->first_name. " ". $patient->last_name. " Booked an appointment ";
|
||||
}
|
||||
return $query;
|
||||
|
||||
});
|
||||
|
||||
return $patientActivity;
|
||||
}
|
||||
public function ordersData($start_date,$end_date){
|
||||
return Cart::select('carts.id as order_id','carts.total_amount as amount',
|
||||
DB::raw("CONCAT(first_name,' ',last_name) as patient_name"),
|
||||
'created_at as date')
|
||||
->where('created_at', '>=', $start_date." 00:00:00")
|
||||
->where('created_at', '<=', $end_date." 23:59:59")
|
||||
->get();
|
||||
}
|
||||
public function completedMeetings($start_date,$end_date){
|
||||
return Appointment::select(
|
||||
'appointments.patient_id',
|
||||
'appointments.appointment_time',
|
||||
'appointments.appointment_date',
|
||||
'appointments.start_time',
|
||||
'appointments.end_time',
|
||||
'appointments.timezone',
|
||||
'telemed_pros.name as provider_name',
|
||||
'telemed_pros_id as provider_id',
|
||||
'carts.id as order_id',
|
||||
'appointments.patient_name'
|
||||
)
|
||||
->Join('telemed_pros', 'telemed_pros.id', 'appointments.telemed_pros_id')
|
||||
->Join("carts", "appointments.id","carts.appointment_id")
|
||||
->where('appointments.status', "completed")
|
||||
->where('appointments.end_time', '>=', $start_date." 00:00:00")
|
||||
->where('appointments.end_time', '<=', $end_date." 23:59:59")
|
||||
->get();
|
||||
}
|
||||
public function productsData($start_date,$end_date)
|
||||
{
|
||||
return Item::select(
|
||||
DB::raw("sum(case when items.status='delivered' then items.quantity else 0 end) as total_orders"),
|
||||
DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as total_amount"),
|
||||
'plans_v1.title as product_name',
|
||||
'items.plans_id as product_id'
|
||||
)
|
||||
->leftJoin('plans_v1','plans_v1.id','items.plans_id')
|
||||
->where('items.created_at', '>=', $start_date." 00:00:00")
|
||||
->where('items.created_at', '<=', $end_date." 23:59:59")
|
||||
->groupby('plans_v1.title', 'items.plans_id')
|
||||
->get();
|
||||
// dd(Constant::getFullSql($products));
|
||||
}
|
||||
}
|
415
app/Http/Controllers/Admin/Api/HomeController.php
Normal file
415
app/Http/Controllers/Admin/Api/HomeController.php
Normal file
@ -0,0 +1,415 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use Agence104\LiveKit\VideoGrant;
|
||||
use App\Classes\Constant;
|
||||
use App\Events\AppointmentBooked;
|
||||
use App\Events\PaymentProcessed;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Admin;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Item;
|
||||
use App\Models\ItemHistory;
|
||||
use App\Models\Lab;
|
||||
use App\Models\LabKit;
|
||||
use App\Models\LabkitOrderItem;
|
||||
use App\Models\LicenseNumberModel;
|
||||
use App\Models\MedicalHistoryAnswer;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPlan;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Models\Plan;
|
||||
use App\Models\PlanV1;
|
||||
use App\Models\Prescription;
|
||||
use App\Models\ProfileAnswer;
|
||||
use App\Models\ProfileCategory;
|
||||
use App\Models\QuestionBuilder;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Subscription;
|
||||
use App\Models\Telemedpro;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonTimeZone;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Error;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Yajra\DataTables\DataTables;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Agence104\LiveKit\AccessToken;
|
||||
use Agence104\LiveKit\AccessTokenOptions;
|
||||
use Agence104\LiveKit\RoomCreateOptions;
|
||||
use Agence104\LiveKit\RoomServiceClient;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function updateAdminProfile(Admin $admin, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'edit', new Admin);
|
||||
$admin->update($request->all());
|
||||
return response()->json([
|
||||
'message' => 'Admin updated successfully',
|
||||
'telemed' => $admin
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function product(PlanV1 $product)
|
||||
{
|
||||
return response()->json([
|
||||
'product' => $product
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function labsList()
|
||||
{
|
||||
$labs = Lab::all();
|
||||
return response()->json([
|
||||
'patients' => $labs
|
||||
]);
|
||||
}
|
||||
public function labs(Lab $lab)
|
||||
{
|
||||
return response()->json([
|
||||
'patient' => $lab
|
||||
]);
|
||||
}
|
||||
public function labsDelete(Lab $lab)
|
||||
{
|
||||
$lab->delete();
|
||||
return response()->json([
|
||||
'message' => "Deleted Successfully"
|
||||
]);
|
||||
}
|
||||
public function labsUpdate(Lab $lab, Request $request)
|
||||
{
|
||||
$lab->update($request->all());
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Lab updated successfully',
|
||||
'telemed' => $lab
|
||||
]);
|
||||
}
|
||||
|
||||
public function getQuestionBuilderStore(Patient $patient, Request $request)
|
||||
{
|
||||
|
||||
$questionBuilder = QuestionBuilder::select('key', 'value')->where("customer_id", $patient->id)->get();
|
||||
$jsonData = $questionBuilder->mapWithKeys(function ($item) {
|
||||
return [$item->key => $item->value];
|
||||
});
|
||||
// Store data
|
||||
return response()->json([
|
||||
'message' => 'Data Sent',
|
||||
'data' => $jsonData
|
||||
], 200);
|
||||
}
|
||||
public function getProducts()
|
||||
{
|
||||
return response()->json([
|
||||
'data' => PlanV1::select('plans_v1.*')->get()
|
||||
], 200);
|
||||
}
|
||||
public function storeOrderData(LabKit $labkit, Patient $patient, Request $request)
|
||||
{
|
||||
$user = $patient;
|
||||
$cart = new Cart();
|
||||
$cart->lab_kit_id = $labkit->id;
|
||||
$cart->first_name = $request->first_name;
|
||||
$cart->last_name = $request->last_name;
|
||||
/* $cart->appointment_id = $request->appointment_id; */
|
||||
$cart->email = $request->email;
|
||||
$cart->phone = $request->phone;
|
||||
$cart->status = "pending";
|
||||
$cart->prescription_status = "pending";
|
||||
|
||||
|
||||
|
||||
$cart->date_of_birth = $request->date_of_birth ?? null;
|
||||
|
||||
$cart->patient_id = $user->id;
|
||||
|
||||
$cart->shipping_address1 = $request->shipping_address1;
|
||||
$cart->shipping_address2 = $request->shipping_address2;
|
||||
$cart->shipping_city = $request->shipping_city;
|
||||
$cart->shipping_state = $request->shipping_state;
|
||||
$cart->shipping_zipcode = $request->shipping_zipcode;
|
||||
$cart->shipping_country = $request->shipping_country;
|
||||
|
||||
$cart->billing_address1 = $request->billing_address1;
|
||||
$cart->billing_address2 = $request->billing_address2;
|
||||
$cart->billing_city = $request->billing_city;
|
||||
$cart->billing_state = $request->billing_state;
|
||||
$cart->billing_zipcode = $request->billing_zipcode;
|
||||
$cart->billing_country = $request->billing_country;
|
||||
$cart->short_description = "Your order has been placed successfully";
|
||||
$cart->shipping_amount = $request->shipping_amount;
|
||||
$cart->total_amount = $request->total_amount;
|
||||
|
||||
$cart->save();
|
||||
|
||||
if ($request->has('items')) {
|
||||
foreach ($request->items as $itemData) {
|
||||
$item = new Item();
|
||||
$item->plans_id = $itemData['plans_id'];
|
||||
$item->quantity = $itemData['quantity'];
|
||||
|
||||
|
||||
$item->status = "pending";
|
||||
$item->labkit_delivery_status = "pending";
|
||||
$item->cart_id = $cart->id;
|
||||
$item->save();
|
||||
|
||||
$itemHistory = new ItemHistory();
|
||||
$itemHistory->note = "Order was placed (Order ID: #" . $cart->id . ")";
|
||||
$itemHistory->short_description = "Your order has been placed successfully";
|
||||
$itemHistory->cart_id = $cart->id;
|
||||
$itemHistory->status = "pending";
|
||||
$itemHistory->item_id = $item->id;
|
||||
if (isset($itemData['subscription']) && $itemData['subscription'] == true && $itemData['onetime'] == false) {
|
||||
$subscription = new Subscription();
|
||||
$subscription->subscription_start_date = Carbon::now();
|
||||
$subscription->subscription_renewal_date = Carbon::now()->addDays(30);
|
||||
$subscription->subscription_status = "Active";
|
||||
$subscription->cart_id = $cart->id;
|
||||
/* $subscription->status = "active"; */
|
||||
|
||||
$subscription->item_id = $item->id;
|
||||
$subscription->patient_id = $user->id;
|
||||
|
||||
$subscription->save();
|
||||
}
|
||||
|
||||
$itemHistory->save();
|
||||
|
||||
$plan = PlanV1::find($itemData['plans_id']);
|
||||
if ($plan->is_prescription_required == true)
|
||||
$labkitOrderItem = LabkitOrderItem::create([
|
||||
'cart_id' => $cart->id,
|
||||
'item_id' => $item->id,
|
||||
'lab_kit_id' => 1,
|
||||
/* 'result' => $request['result'], */
|
||||
'status' => "Ordered",
|
||||
]);
|
||||
}
|
||||
}
|
||||
return response()->json(['status' => 'Success', 'cart' => $cart], 200);
|
||||
}
|
||||
public function editOrderData(Cart $cart, Request $request)
|
||||
{
|
||||
// Validate the request data
|
||||
$validatedData = $request->validate([
|
||||
'first_name' => 'sometimes|string|max:255',
|
||||
'last_name' => 'sometimes|string|max:255',
|
||||
'email' => 'sometimes|email|max:255',
|
||||
'phone' => 'sometimes|string|max:20',
|
||||
'date_of_birth' => 'sometimes|date|nullable',
|
||||
'shipping_address1' => 'sometimes|string|max:255',
|
||||
'shipping_address2' => 'sometimes|string|max:255|nullable',
|
||||
'shipping_city' => 'sometimes|string|max:255',
|
||||
'shipping_state' => 'sometimes|string|max:255',
|
||||
'shipping_zipcode' => 'sometimes|string|max:20',
|
||||
'shipping_country' => 'sometimes|string|max:255',
|
||||
'patient_id' => 'sometimes',
|
||||
/* 'billing_address1' => 'sometimes|string|max:255',
|
||||
'billing_address2' => 'sometimes|string|max:255|nullable',
|
||||
'billing_city' => 'sometimes|string|max:255',
|
||||
'billing_state' => 'sometimes|string|max:255',
|
||||
'billing_zipcode' => 'sometimes|string|max:20',
|
||||
'billing_country' => 'sometimes|string|max:255', */
|
||||
'shipping_amount' => 'sometimes|numeric',
|
||||
'total_amount' => 'sometimes|numeric',
|
||||
'items' => 'sometimes|array',
|
||||
/* 'items.*.plans_id' => 'required_with:items|exists:plans,id',
|
||||
'items.*.quantity' => 'required_with:items|integer|min:1',
|
||||
'items.*.subscription' => 'sometimes|boolean',
|
||||
'items.*.onetime' => 'sometimes|boolean', */
|
||||
]);
|
||||
|
||||
// Update the cart with validated data
|
||||
$cart->fill($validatedData);
|
||||
$cart->save();
|
||||
|
||||
// Update or create items
|
||||
if ($request->has('items')) {
|
||||
foreach ($request->items as $itemData) {
|
||||
$item = Item::updateOrCreate(
|
||||
['cart_id' => $cart->id, 'plans_id' => $itemData['plans_id']],
|
||||
[
|
||||
'quantity' => $itemData['quantity'],
|
||||
'status' => 'pending',
|
||||
'labkit_delivery_status' => 'pending',
|
||||
]
|
||||
);
|
||||
|
||||
// Update or create subscription
|
||||
if (isset($itemData['subscription']) && $itemData['subscription'] == true && $itemData['onetime'] == false) {
|
||||
Subscription::updateOrCreate(
|
||||
['cart_id' => $cart->id, 'item_id' => $item->id],
|
||||
[
|
||||
'subscription_start_date' => $item->created_at,
|
||||
'subscription_renewal_date' => $item->created_at->addDays(30),
|
||||
'subscription_status' => 'Active',
|
||||
'patient_id' => $cart->patient_id,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
// Remove subscription if it exists and is no longer needed
|
||||
Subscription::where('cart_id', $cart->id)
|
||||
->where('item_id', $item->id)
|
||||
->delete();
|
||||
}
|
||||
|
||||
// Update or create LabkitOrderItem
|
||||
$plan = PlanV1::find($itemData['plans_id']);
|
||||
if ($plan->is_prescription_required) {
|
||||
LabkitOrderItem::updateOrCreate(
|
||||
['cart_id' => $cart->id, 'item_id' => $item->id],
|
||||
[
|
||||
'lab_kit_id' => 1,
|
||||
'status' => 'Ordered',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove items that are no longer in the request
|
||||
/* if ($request->has('items')) {
|
||||
$currentItemIds = collect($request->items)->pluck('plans_id')->toArray();
|
||||
ItemHistory::where('cart_id', $cart->id)
|
||||
//->whereNotIn('plans_id', $currentItemIds)
|
||||
->delete();
|
||||
Item::where('cart_id', $cart->id)
|
||||
->whereNotIn('plans_id', $currentItemIds)
|
||||
->delete();
|
||||
} */
|
||||
|
||||
// Refresh the cart to get the updated data
|
||||
$cart->refresh();
|
||||
|
||||
return response()->json(['status' => 'Success', 'cart' => $cart], 200);
|
||||
}
|
||||
|
||||
|
||||
public function getPrescription()
|
||||
{
|
||||
$prescriptions = Prescription::query();
|
||||
|
||||
return DataTables::of($prescriptions)->make(true);
|
||||
}
|
||||
public function processPayment(Patient $patient, Request $request)
|
||||
{
|
||||
//event(new PaymentProcessed($patient));
|
||||
return response()->json(['status' => 'Success'], 200);
|
||||
}
|
||||
|
||||
|
||||
public function questionBuilderStore(Patient $patient, $category, Request $request)
|
||||
{
|
||||
$data = $request->all();
|
||||
|
||||
$questionBuilderData = [];
|
||||
$category = ProfileCategory::where("category_link", $category)->first();
|
||||
if (!$category)
|
||||
return response()->json([
|
||||
'message' => 'Invalid Category Link',
|
||||
'data' => ''
|
||||
], 200);
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$value = serialize($value);
|
||||
}
|
||||
if (!empty($value)) {
|
||||
$questionBuilderData[] = [
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
'profile_category_id' => $category->id,
|
||||
'customer_id' => $patient->id
|
||||
];
|
||||
}
|
||||
}
|
||||
// dd($questionBuilderData);
|
||||
$questionBuilder = QuestionBuilder::insert($questionBuilderData);
|
||||
|
||||
$questionBuilder = QuestionBuilder::select('key', 'value')->get();
|
||||
|
||||
// Convert the data to a key-value JSON format
|
||||
$jsonData = $questionBuilder->mapWithKeys(function ($item) {
|
||||
return [$item->key => $item->value];
|
||||
});
|
||||
// Store data+
|
||||
return response()->json([
|
||||
'message' => 'Data Inserted',
|
||||
'data' => $jsonData
|
||||
], 200);
|
||||
}
|
||||
public function getMedicalHistoryQuestion(Patient $patient, Request $request)
|
||||
{
|
||||
$answers = MedicalHistoryAnswer::where('patient_id', $patient->id)->get();
|
||||
|
||||
return response()->json([
|
||||
'status' => 'Success',
|
||||
'answers' => $answers
|
||||
], 200);
|
||||
}
|
||||
public function postMedicalHistoryQuestion(Patient $patient, Request $request)
|
||||
{
|
||||
|
||||
foreach ($request->answers as $answer) {
|
||||
$existing = MedicalHistoryAnswer::where("patient_id", $patient->id)->where('question_key', $answer['question_key'])->first();
|
||||
|
||||
if ($existing) {
|
||||
$existing->answer = $answer['answer'];
|
||||
$existing->patient_id = $patient->id;
|
||||
$existing->type = $answer['type'];
|
||||
$existing->save();
|
||||
} else {
|
||||
$newAnswer = new MedicalHistoryAnswer();
|
||||
$newAnswer->question_key = $answer['question_key'];
|
||||
$newAnswer->patient_id = $patient->id;
|
||||
$newAnswer->answer = $answer['answer'];
|
||||
$newAnswer->type = $answer['type'];
|
||||
$newAnswer->save();
|
||||
}
|
||||
}
|
||||
|
||||
PatientRegActivity::create([
|
||||
'patient_id' => $patient->id,
|
||||
'activity' => 'patient_medical_question_entered'
|
||||
]);
|
||||
|
||||
return response()->json(['status' => 'Success'], 200);
|
||||
}
|
||||
}
|
66
app/Http/Controllers/Admin/Api/LoginController.php
Normal file
66
app/Http/Controllers/Admin/Api/LoginController.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Tymon\JWTAuth\Facades\JWTAuth;
|
||||
use App\Models\Admin;
|
||||
use App\Permissions\Permissions;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
public function loginApi(Request $request)
|
||||
{
|
||||
$credentials = $request->only('email', 'password');
|
||||
|
||||
// Validate the request
|
||||
$validator = Validator::make($credentials, [
|
||||
'email' => 'required|email',
|
||||
'password' => 'required|string',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json($validator->errors(), 422);
|
||||
}
|
||||
|
||||
// Find the user by email
|
||||
$admin = Admin::where('email', $credentials['email'])->first();
|
||||
|
||||
if (!$admin || !Auth::guard('admin')->validate($credentials)) {
|
||||
return response()->json(['error' => 'Invalid email or password'], 401);
|
||||
}
|
||||
|
||||
// Gen$admin->role;erate the JWT token
|
||||
$token = JWTAuth::fromUser($admin);
|
||||
$permissionManager = new Permissions($admin->role->permissions);
|
||||
$permissions = $permissionManager->permissionsApi();
|
||||
|
||||
// Construct user data
|
||||
$userData = [
|
||||
'id' => $admin->id,
|
||||
'fullName' => $admin->name, // Assuming 'name' field contains the full name
|
||||
'username' => $admin->username, // Assuming you have a 'username' field
|
||||
'avatar' => '/images/avatars/avatar-1.png', // Static for example; replace with dynamic if available
|
||||
'email' => $admin->email,
|
||||
'role' => strtolower($admin->role->role_name), // Assuming the role is 'admin',
|
||||
|
||||
];
|
||||
// Construct the response
|
||||
return response()->json([
|
||||
'userAbilityRules' => [
|
||||
[
|
||||
'action' => 'manage',
|
||||
'subject' =>'all'
|
||||
]
|
||||
],
|
||||
'accessToken' => $token,
|
||||
'userData' => $userData,
|
||||
'permissions'=>$permissions
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
}
|
240
app/Http/Controllers/Admin/Api/MedicineController.php
Normal file
240
app/Http/Controllers/Admin/Api/MedicineController.php
Normal file
@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Lab;
|
||||
use App\Models\LabKit;
|
||||
use App\Models\MedicalHistoryAnswer;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Models\Plan;
|
||||
use App\Models\PlanV1;
|
||||
use App\Models\ProfileAnswer;
|
||||
use App\Models\QuestionBuilder;
|
||||
use App\Models\Telemedpro;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Yajra\DataTables\DataTables;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
|
||||
class MedicineController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function getMedList()
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'list', new PlanV1);
|
||||
$medicines = PlanV1::query();
|
||||
return Datatables::of($medicines)
|
||||
->addColumn('image_url', function ($med) {
|
||||
return URL::to("product/" . $med->image_url);
|
||||
})
|
||||
->toJson();
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function SaveMed(Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'add', new PlanV1);
|
||||
$slug = self::createSlug($request->get('slug'));
|
||||
if ($request->get('image')) {
|
||||
//upload website logo
|
||||
$fileName = $slug;
|
||||
$filePath = public_path() . '/product/';
|
||||
$fileName = $this->uploadImage($request->get('image'), $fileName, $filePath);
|
||||
////////////////
|
||||
}
|
||||
|
||||
PlanV1::create([
|
||||
'title' => $request->get('title'),
|
||||
'currency' => $request->get('currency'),
|
||||
'price' => $request->get('price'),
|
||||
'list_one_title' => $request->get('list_one_title'),
|
||||
'list_two_title' => $request->get('list_two_title'),
|
||||
'list_sub_title' => $request->get('list_sub_title'),
|
||||
'image_url' => $fileName,
|
||||
'slug' => $slug,
|
||||
'domain' => $request->get('domain'),
|
||||
'product_file_path' => null
|
||||
]);
|
||||
return response()->json([
|
||||
'message' => "success"
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function uploadImage($image, $fileName, $path)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new PlanV1);
|
||||
$logo = base64_decode($image);
|
||||
$filename = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[0]);
|
||||
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
||||
$imageName = $fileName . '.' . $ext;
|
||||
$path = $path . $imageName;
|
||||
file_put_contents($path, $logo);
|
||||
return $imageName;
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function EditMed($id, Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new PlanV1);
|
||||
$medicine = PlanV1::find($id);
|
||||
$slug = self::createSlug($request->get('slug'));
|
||||
$fileName = null;
|
||||
if ($request->get('image')) {
|
||||
//upload website logo
|
||||
$fileName = $slug;
|
||||
$filePath = public_path() . '/product/';
|
||||
$fileName = $this->uploadImage($request->get('image'), $fileName, $filePath);
|
||||
////////////////
|
||||
}
|
||||
$medicine->title = $request->get('title');
|
||||
$medicine->currency = $request->get('currency');
|
||||
$medicine->price = $request->get('price');
|
||||
$medicine->list_one_title = $request->get('list_one_title');
|
||||
$medicine->list_two_title = $request->get('list_two_title');
|
||||
$medicine->list_sub_title = $request->get('list_sub_title');
|
||||
$medicine->image_url = $fileName;
|
||||
$medicine->slug = $slug;
|
||||
$medicine->domain = $request->get('domain');
|
||||
$medicine->save();
|
||||
return response()->json([
|
||||
'message' => "success"
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function DeleteMed($id, Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new PlanV1);
|
||||
$medicine = PlanV1::where("id", $id)->delete();
|
||||
return response()->json([
|
||||
'message' => "success"
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
private function createSlug($string)
|
||||
{
|
||||
$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
|
||||
|
||||
return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
|
||||
}
|
||||
private function storeFile($file, $destinationPath)
|
||||
{
|
||||
//Display File Name
|
||||
$file->getClientOriginalName();
|
||||
$file->getClientOriginalExtension();
|
||||
$file->getRealPath();
|
||||
$file->getSize();
|
||||
$file->getMimeType();
|
||||
//Move Uploaded File
|
||||
|
||||
$file->move($destinationPath, $file->getClientOriginalName() . '.' . $file->getClientOriginalExtension());
|
||||
}
|
||||
public function getFileList()
|
||||
{
|
||||
$files = PlanV1::select('product_file_path')->groupBy('product_file_path')->get();
|
||||
return response()->json([
|
||||
'medicines' => $files
|
||||
]);
|
||||
}
|
||||
public function updateStatusPatientPrescription(PatientPrescription $PatientPrescription, Request $request)
|
||||
{
|
||||
$PatientPrescription->status = $request->input("status");
|
||||
$PatientPrescription->save();
|
||||
return response()->json([
|
||||
'status' => 'updated to ' . $request->input("status")
|
||||
]);
|
||||
}
|
||||
public function updateStatusLabkit(Cart $cart, Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new LabKit);
|
||||
$cart->status = $request->input("status");
|
||||
$cart->save();
|
||||
return response()->json([
|
||||
'status' => 'updated to ' . $request->input("status")
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function labkitList()
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new LabKit);
|
||||
$labkit = LabKit::all();
|
||||
return response()->json([
|
||||
'labkit' => $labkit
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function labsKitDelete(LabKit $labkit)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'delete', new LabKit);
|
||||
$labkit->delete();
|
||||
return response()->json([
|
||||
'message' => "Deleted Successfully"
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function labskitUpdate(LabKit $labkit, Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new LabKit);
|
||||
$labkit->update($request->all());
|
||||
return response()->json([
|
||||
'message' => 'Labkit updated successfully',
|
||||
'telemed' => $labkit
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function labskitCreate(LabKit $labkit, Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'add', new LabKit);
|
||||
$labkit->create($request->all());
|
||||
return response()->json([
|
||||
'message' => 'Labkit created successfully',
|
||||
'telemed' => $labkit
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function getPatientLabKitOrders(Patient $patient, Request $request)
|
||||
{
|
||||
$cart = Cart::with("patient")->where("patient_id", $patient->id)->get();
|
||||
return response()->json(['cart' => $cart], 200);
|
||||
}
|
||||
}
|
538
app/Http/Controllers/Admin/Api/OrderController.php
Normal file
538
app/Http/Controllers/Admin/Api/OrderController.php
Normal file
@ -0,0 +1,538 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Item;
|
||||
use App\Models\ItemHistory;
|
||||
use App\Models\LabkitOrderItem;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Permission;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Subscription;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Yajra\DataTables\DataTables;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class OrderController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function orderList(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'view', new Cart);
|
||||
$fromDate = $request->get('from_date');
|
||||
$toDate = $request->get('to_date');
|
||||
$status = $request->get('status');
|
||||
$orderList = Cart::select(
|
||||
"appointments.*",
|
||||
'appointments.id as appointment_id',
|
||||
'carts.*',
|
||||
'carts.id as order_id',
|
||||
DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name")
|
||||
)
|
||||
->leftJoin('appointments', 'appointments.id', 'carts.appointment_id');
|
||||
|
||||
|
||||
if ($fromDate != "all") {
|
||||
$from_date = Carbon::createFromFormat('m-d-Y', $fromDate)->format('Y-m-d');
|
||||
$orderList->where('carts.created_at', ">=", $from_date . " 00:00:00");
|
||||
}
|
||||
if ($toDate != "all") {
|
||||
$to_date = Carbon::createFromFormat('m-d-Y', $toDate)->format('Y-m-d');
|
||||
$orderList->where('carts.created_at', "<=", $to_date . " 23:59:59");
|
||||
}
|
||||
if ($status != "all") {
|
||||
$orderList->where('carts.status', $status);
|
||||
}
|
||||
// dd(Constant::getFullSql($orderList));
|
||||
return Datatables::of($orderList)
|
||||
->addColumn('order_total_amount', function ($order) {
|
||||
$items = Item::where('cart_id', $order->id)->get();
|
||||
return $items->sum(function ($item) {
|
||||
return $item->quantity * $item->price;
|
||||
});
|
||||
})
|
||||
->addColumn('order_total_shipping', function ($order) {
|
||||
$items = Item::where('cart_id', $order->id)->get();
|
||||
return $items->sum('shipping_cost');
|
||||
})
|
||||
->addColumn('appointment_status', function ($order) {
|
||||
$appointment = Appointment::find($order->appointment_id);
|
||||
return $appointment ? $appointment->status : 'null';
|
||||
})
|
||||
->addColumn('total_items', function ($order) {
|
||||
return Item::where('cart_id', $order->id)->sum('quantity');
|
||||
})
|
||||
->addColumn('order_items', function ($order) {
|
||||
$items = Item::with('plansV1')
|
||||
->where('cart_id', $order->id)
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
$planV1 = $item->plansV1;
|
||||
if ($planV1) {
|
||||
$planV1->qty = $item->quantity;
|
||||
$planV1->status = $item->status;
|
||||
}
|
||||
return $planV1;
|
||||
});
|
||||
return $items;
|
||||
})
|
||||
->make(true);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function orderListbyPatient(Patient $patient, Request $request)
|
||||
{
|
||||
|
||||
$fromDate = $request->get('from_date');
|
||||
$toDate = $request->get('to_date');
|
||||
$orderList = Cart::where('carts.patient_id', $patient->id);
|
||||
if ($fromDate != "") {
|
||||
$from_date = Carbon::createFromFormat('m-d-Y', $fromDate)->format('Y-m-d');
|
||||
$orderList->where('created_at', ">=", $from_date . " 00:00:00");
|
||||
}
|
||||
if ($toDate != "") {
|
||||
$to_date = Carbon::createFromFormat('m-d-Y', $toDate)->format('Y-m-d');
|
||||
$orderList->where('created_at', "<=", $to_date . " 23:59:59");
|
||||
}
|
||||
|
||||
$orderListData = $orderList->get();
|
||||
$totalPrice = 0;
|
||||
$totalShippingCost = 0;
|
||||
foreach ($orderListData as $order) {
|
||||
$totalPrice = 0;
|
||||
$total_products = 0;
|
||||
$quantity = [];
|
||||
$totalShippingCost = 0;
|
||||
$order->order_total_amount = $totalPrice;
|
||||
$order->order_total_shipping = $totalShippingCost;
|
||||
$items = Item::leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id')
|
||||
->where('cart_id', $order->id)
|
||||
->get();
|
||||
//$order->appointment_status = Appointment::where('id', $order->appointment_id)->first()->status;
|
||||
|
||||
$orderItems = [];
|
||||
foreach ($items as $item) {
|
||||
array_push($orderItems, $item->plansV1);
|
||||
$totalShippingCost += $item->shipping_cost;
|
||||
$item->total_price = $item->quantity * $item->price;
|
||||
$totalPrice += $item->total_price;
|
||||
$order->order_total_amount = $totalPrice;
|
||||
$order->order_total_shipping = $totalShippingCost;
|
||||
$item->plansV1->qty = $item->quantity;
|
||||
}
|
||||
|
||||
$order->total_items = $total_products;
|
||||
$order->order_items = $orderItems;
|
||||
}
|
||||
return response()
|
||||
->json([
|
||||
'order_data' => $orderListData
|
||||
]);
|
||||
}
|
||||
public function orderDetails($id)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'details', new Cart);
|
||||
|
||||
$orderItems = $this->getOrderItems($id);
|
||||
$orderDetails = Cart::find($id);
|
||||
$items = Item::where('cart_id', $orderDetails->id)->get();
|
||||
$appointments = Appointment::select(
|
||||
'appointments.*',
|
||||
'telemed_pros.name as provider_name',
|
||||
'telemed_pros.email as provider_email',
|
||||
'telemed_pros.phone_number as provider_phone',
|
||||
'carts.total_amount',
|
||||
'carts.shipping_amount'
|
||||
)
|
||||
->leftJoin('telemed_pros', 'telemed_pros.id', 'appointments.telemed_pros_id')
|
||||
->leftJoin('carts', 'carts.appointment_id', 'appointments.id')
|
||||
|
||||
->where('appointments.id', $orderDetails->appointment_id)
|
||||
->first();
|
||||
if (Gate::forUser($this->user)->allows('prescriptions', new Cart)) {
|
||||
$prescription = PatientPrescription::select(
|
||||
'patient_prescription.id as patient_prescription_id',
|
||||
'patient_prescription.id',
|
||||
'patient_prescription.created_by_id',
|
||||
'patient_prescription.created_by_type',
|
||||
'patient_prescription.direction_quantity',
|
||||
'patient_prescription.refill_quantity',
|
||||
'patient_prescription.dosage',
|
||||
'patient_prescription.status',
|
||||
'patient_prescription.direction_one',
|
||||
'patient_prescription.direction_two',
|
||||
'patient_prescription.dont_substitute',
|
||||
'patient_prescription.comments',
|
||||
'patient_prescription.brand',
|
||||
'patient_prescription.from',
|
||||
'patient_prescription.quantity',
|
||||
'patient_prescription.created_at as prescription_date',
|
||||
'prescriptions.name as prescription_name',
|
||||
'patient_prescription.prescription_id',
|
||||
'telemed_pros.name as provide_name',
|
||||
'telemed_pros.id as provider_id',
|
||||
)
|
||||
->where("appointment_id", $orderDetails->appointment_id)
|
||||
->leftJoin('appointments', 'appointments.id', 'patient_prescription.appointment_id')
|
||||
->leftJoin('prescriptions', 'prescriptions.id', 'patient_prescription.prescription_id')
|
||||
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', 'telemed_pros.id')
|
||||
->get();
|
||||
} else {
|
||||
$prescription = ['error' => "Access Denied!"];
|
||||
}
|
||||
if (Gate::forUser($this->user)->allows('detail_notes', new Cart)) {
|
||||
$patientNotes = PatientNote::where("appointment_id", $orderDetails->appointment_id)->get();
|
||||
} else {
|
||||
$patientNotes = ['error' => "Access Denied!"];
|
||||
}
|
||||
|
||||
if ($appointments)
|
||||
$appointments->provider_id = $appointments->telemed_pros_id;
|
||||
$patient = $orderDetails->patient;
|
||||
$patient->profile_picture = $this->url->to("storage/profile_pictures/" . $patient->profile_picture);
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'order_details' => $orderDetails,
|
||||
'order_items' => $orderItems,
|
||||
'patient_details' => $patient,
|
||||
'appointment_details' => $appointments,
|
||||
'items_activity' => $this->getShippingActivity($id),
|
||||
'appointment_notes' => $patientNotes,
|
||||
'prescription' => $prescription
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function getOrderItems($id)
|
||||
{
|
||||
$items = Item::select('plans_v1.*', 'items.*', 'items.id as item_id', 'plans_v1.id as plans_id')
|
||||
->leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id')
|
||||
->where('cart_id', $id)
|
||||
->get();
|
||||
|
||||
$totalPrice = 0;
|
||||
$totalShippingCost = 0;
|
||||
$total_products = 0;
|
||||
|
||||
$itemsWithFlags = $items->map(function ($item) {
|
||||
$subscription = Subscription::where('item_id', $item->item_id)->first();
|
||||
|
||||
$item->subscription = $subscription ? true : false;
|
||||
$item->onetime = $subscription ? true : false;
|
||||
|
||||
$item->total_price = $item->quantity * $item->price;
|
||||
$item->image_url = $this->url->to("product/" . $item->image_url);
|
||||
|
||||
return $item;
|
||||
});
|
||||
|
||||
foreach ($itemsWithFlags as $item) {
|
||||
$totalShippingCost += $item->shipping_cost;
|
||||
$totalPrice += $item->total_price;
|
||||
$total_products += $item->quantity;
|
||||
}
|
||||
|
||||
return [
|
||||
'items' => $itemsWithFlags,
|
||||
'total_amount' => $totalPrice,
|
||||
'total_shipping_cost' => $totalShippingCost,
|
||||
'total_products' => $total_products,
|
||||
'total' => $totalPrice + $totalShippingCost
|
||||
];
|
||||
}
|
||||
public function getShippingActivity($id)
|
||||
{
|
||||
$itemsHistory = ItemHistory::select('items_history.*', 'plans_v1.title as item_name')
|
||||
->where('items_history.cart_id', $id)
|
||||
->leftJoin('items', 'items.id', 'items_history.item_id')
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->get();
|
||||
return $itemsHistory;
|
||||
}
|
||||
public function getPaymentDetail($id)
|
||||
{
|
||||
|
||||
$orderDetails = Cart::find($id);
|
||||
$payment = Payment::where('order_id', $orderDetails->id)->first();
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'payment' => $payment
|
||||
]);
|
||||
}
|
||||
public function labkitOrderItemGet(Request $request)
|
||||
{
|
||||
$labkitOrderItems = LabkitOrderItem::where('labkit_order_items.cart_id', $request->input('cart_id'))
|
||||
->leftJoin(
|
||||
'lab_kit',
|
||||
'labkit_order_items.lab_kit_id',
|
||||
'=',
|
||||
'lab_kit.id'
|
||||
)
|
||||
->leftJoin(
|
||||
'items',
|
||||
'items.id',
|
||||
'labkit_order_items.item_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'plans_v1',
|
||||
'plans_v1.id',
|
||||
'items.plans_id'
|
||||
)
|
||||
->select(
|
||||
'labkit_order_items.id',
|
||||
'labkit_order_items.status',
|
||||
'labkit_order_items.result',
|
||||
'lab_kit.name as lab_kit_name',
|
||||
'plans_v1.title as item_name'
|
||||
)
|
||||
->get();
|
||||
foreach ($labkitOrderItems as $labKit) {
|
||||
|
||||
if ($labKit->result != "")
|
||||
$labKit->result = $this->url->to('storage/lab_results/' . $labKit->result);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'data' => $labkitOrderItems,
|
||||
]);
|
||||
}
|
||||
public function orderCount(Request $request)
|
||||
{
|
||||
|
||||
$fromDate = $request->get('from_date');
|
||||
$toDate = $request->get('to_date');
|
||||
$total_order = Cart::select(
|
||||
"appointments.*",
|
||||
'appointments.id as appointment_id',
|
||||
'carts.*',
|
||||
'carts.id as order_id',
|
||||
DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name"),
|
||||
)->leftJoin('appointments', 'appointments.id', 'carts.appointment_id');
|
||||
$total_order = $total_order->count();
|
||||
|
||||
$total_appointment_order = Cart::select(
|
||||
"appointments.*",
|
||||
'appointments.id as appointment_id',
|
||||
'carts.*',
|
||||
'carts.id as order_id',
|
||||
DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name"),
|
||||
)->join('appointments', 'appointments.id', 'carts.appointment_id')
|
||||
->whereNotNull("appointments.id");
|
||||
$total_appointment_order = $total_appointment_order->count();
|
||||
|
||||
$total_appointment_order_without = Cart::select(
|
||||
"appointments.*",
|
||||
'appointments.id as appointment_id',
|
||||
'carts.*',
|
||||
'carts.id as order_id',
|
||||
DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name"),
|
||||
)->leftJoin('appointments', 'appointments.id', 'carts.appointment_id')
|
||||
->whereNull("appointments.id");
|
||||
$total_appointment_order_without = $total_appointment_order_without->count();
|
||||
|
||||
$upcomingMeetings = Cart::select(
|
||||
'carts.id as order_id',
|
||||
'appointments.id',
|
||||
'appointments.patient_id',
|
||||
'appointments.appointment_time',
|
||||
'appointments.appointment_date',
|
||||
DB::raw(
|
||||
'CONCAT(patients.first_name, " " , patients.last_name) as patient_name'
|
||||
)
|
||||
)
|
||||
->join('appointments', 'appointments.id', 'carts.appointment_id')
|
||||
->leftJoin('patients', 'patients.id', 'appointments.patient_id')
|
||||
->where('appointments.appointment_date', ">=", Carbon::now()->format("Y-m-d"))
|
||||
->where('appointments.start_time', null)
|
||||
->count();
|
||||
|
||||
$completedMeetings = Cart::select(
|
||||
'carts.id as order_id',
|
||||
'appointments.patient_id',
|
||||
'appointments.appointment_time',
|
||||
'appointments.appointment_date',
|
||||
'appointments.start_time',
|
||||
'appointments.end_time',
|
||||
'telemed_pros.name as provider_name',
|
||||
'appointments.telemed_pros_id as provider_id',
|
||||
|
||||
DB::raw(
|
||||
'CONCAT(patients.first_name, " " , patients.last_name) as patient_name'
|
||||
)
|
||||
)
|
||||
->join('appointments', 'appointments.id', 'carts.appointment_id')
|
||||
->leftJoin('patients', 'patients.id', 'appointments.patient_id')
|
||||
->leftJoin('telemed_pros', 'telemed_pros.id', 'appointments.telemed_pros_id')
|
||||
->where('appointments.start_time', "!=", null)
|
||||
->where('appointments.end_time', "!=", null)
|
||||
->count();
|
||||
|
||||
|
||||
$prescribeOrderList = Cart::select(
|
||||
"appointments.*",
|
||||
'appointments.id as appointment_id',
|
||||
'carts.*',
|
||||
'carts.id as order_id',
|
||||
DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name"),
|
||||
)
|
||||
->leftJoin('appointments', 'appointments.id', 'carts.appointment_id');
|
||||
|
||||
|
||||
$prescribeOrderCount = $prescribeOrderList->where("prescription_status", 1)->count();
|
||||
return response()
|
||||
->json([
|
||||
'total_appointment_order' => $total_appointment_order,
|
||||
'total_order' => $total_order,
|
||||
'total_appointment_order_without' => $total_appointment_order_without,
|
||||
'upcomingMeetings' => $upcomingMeetings,
|
||||
'completedMeetings' => $completedMeetings,
|
||||
'prescribeOrderCount' => $prescribeOrderCount,
|
||||
]);
|
||||
}
|
||||
public function updateItemStatus($id, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'edit', new Cart);
|
||||
Item::where('id', $id)
|
||||
->update([
|
||||
'status' => $request->get('status')
|
||||
]);
|
||||
$itemsCount = Item::where('cart_id', $request->get('order_id'));
|
||||
$statusNeeded = $itemsCount->where('status', '!=', 'pending')
|
||||
->where('status', '!=', 'canceled')
|
||||
->where('status', '!=', 'failed')
|
||||
->where('status', '!=', 'refunded')
|
||||
->where('status', '!=', 'processing')
|
||||
->count();
|
||||
|
||||
if ($itemsCount->count() == $statusNeeded) {
|
||||
Cart::where('id', $request->get('order_id'))->update([
|
||||
'status' => 'completed'
|
||||
]);
|
||||
}
|
||||
return response()
|
||||
->json([
|
||||
'success' => "Updated !"
|
||||
], 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function addNotePatient(Cart $cart, Request $request)
|
||||
{
|
||||
|
||||
//$user = Auth::user();
|
||||
$appointment = Appointment::find($cart->appointment_id);
|
||||
$addNotePatient = PatientNote::create([
|
||||
'note' => $request->input('note'),
|
||||
'note_type' => $request->input('note_type'),
|
||||
'patient_id' => $cart->patient_id,
|
||||
'appointment_id' => $cart->appointment_id,
|
||||
'telemed_pros_id' => $appointment->telemed_pros_id ?? null,
|
||||
'admin_id' => Auth::guard('admin')->user()->id
|
||||
|
||||
]);
|
||||
$addNotePatient->file_url = "";
|
||||
if ($request->hasFile('file')) {
|
||||
$file = $request->file('file');
|
||||
|
||||
$filename = $addNotePatient->id . '.' . $file->getClientOriginalExtension();
|
||||
|
||||
$file->move(public_path('assets/files'), $filename);
|
||||
|
||||
$addNotePatient->file_url = "assets/files" . $addNotePatient->id . '.' . $file->getClientOriginalExtension();
|
||||
}
|
||||
$patient = $addNotePatient->patient;
|
||||
$setting = Setting::find(1);
|
||||
/* Mail::send('emails.noteAdded', ['patient' => $patient, 'agent' => $user, 'setting' => $setting], function ($message) use ($patient, $user) {
|
||||
$message->to($patient->email, $patient->first_name)
|
||||
->subject('You Have a New Note from ' . $user->name);
|
||||
}); */
|
||||
return response()->json([
|
||||
'message' => 'Note created',
|
||||
'data' => $addNotePatient
|
||||
], 200);
|
||||
}
|
||||
public function editNotePatient($id, Request $request)
|
||||
{
|
||||
$note = PatientNote::findOrFail($id);
|
||||
$note->update([
|
||||
'note' => $request->input('note'),
|
||||
'note_type' => $request->input('note_type'),
|
||||
'admin_id' => Auth::guard('admin')->user()->id
|
||||
]);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
// Delete old file if it exists
|
||||
if ($note->file_url) {
|
||||
$oldFilePath = public_path($note->file_url);
|
||||
if (file_exists($oldFilePath)) {
|
||||
unlink($oldFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
$file = $request->file('file');
|
||||
$filename = $note->id . '.' . $file->getClientOriginalExtension();
|
||||
$file->move(public_path('assets/files'), $filename);
|
||||
$note->file_url = "assets/files" . $note->id . '.' . $file->getClientOriginalExtension();
|
||||
$note->save();
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Note updated',
|
||||
'data' => $note
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function deleteNotePatient($id)
|
||||
{
|
||||
$note = PatientNote::findOrFail($id);
|
||||
|
||||
// Delete associated file if it exists
|
||||
if ($note->file_url) {
|
||||
$filePath = public_path($note->file_url);
|
||||
if (file_exists($filePath)) {
|
||||
unlink($filePath);
|
||||
}
|
||||
}
|
||||
|
||||
$note->delete();
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Note deleted'
|
||||
], 200);
|
||||
}
|
||||
public function getNotePatient($id)
|
||||
{
|
||||
$note = PatientNote::with(['admin'])->findOrFail($id);
|
||||
|
||||
return response()->json([
|
||||
'note' => $note
|
||||
], 200);
|
||||
}
|
||||
}
|
550
app/Http/Controllers/Admin/Api/PatientController.php
Normal file
550
app/Http/Controllers/Admin/Api/PatientController.php
Normal file
@ -0,0 +1,550 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Events\PatientRegistered;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Item;
|
||||
use App\Models\ItemHistory;
|
||||
use App\Models\LabkitOrderItem;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Models\Setting;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
|
||||
use Agence104\LiveKit\VideoGrant;
|
||||
use App\Events\AppointmentBooked;
|
||||
use App\Events\PaymentProcessed;
|
||||
use App\Models\Admin;
|
||||
use App\Models\Lab;
|
||||
use App\Models\LabKit;
|
||||
use App\Models\LicenseNumberModel;
|
||||
use App\Models\MedicalHistoryAnswer;
|
||||
use App\Models\PatientPlan;
|
||||
use App\Models\Plan;
|
||||
use App\Models\PlanV1;
|
||||
use App\Models\Prescription;
|
||||
use App\Models\ProfileAnswer;
|
||||
use App\Models\ProfileCategory;
|
||||
use App\Models\QuestionBuilder;
|
||||
use App\Models\Subscription;
|
||||
use App\Models\Telemedpro;
|
||||
use Carbon\CarbonTimeZone;
|
||||
use DateTimeZone;
|
||||
use Error;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Yajra\DataTables\DataTables;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Agence104\LiveKit\AccessToken;
|
||||
use Agence104\LiveKit\AccessTokenOptions;
|
||||
use Agence104\LiveKit\RoomCreateOptions;
|
||||
use Agence104\LiveKit\RoomServiceClient;
|
||||
|
||||
class PatientController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function newPatient(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'add', new Patient);
|
||||
$validatedData = $request->validate([
|
||||
'first_name' => 'required|string|max:255',
|
||||
'last_name' => 'required|string|max:255',
|
||||
'email' => 'required|string|email|max:255|unique:patients',
|
||||
'password' => 'required',
|
||||
'dob' => 'required|date_format:Y-m-d',
|
||||
'phone_no' => 'required'
|
||||
]);
|
||||
$patient = Patient::create([
|
||||
'first_name' => $request->input('first_name'),
|
||||
'last_name' => $request->input('last_name'),
|
||||
'phone_no' => $request->input('phone_no'),
|
||||
'email' => $request->input('email'),
|
||||
'password' => Hash::make($request->input('password')),
|
||||
'dob' => $request->input('dob'),
|
||||
'gender' => $request->input('gender') ?? "",
|
||||
]);
|
||||
|
||||
$patient->address = $request->input('address');
|
||||
$patient->state = $request->input('state');
|
||||
$patient->city = $request->input('city');
|
||||
$patient->country = $request->input('country');
|
||||
|
||||
$patient->zip_code = $request->input('zip');
|
||||
|
||||
$patient->shipping_address = $request->input('address');
|
||||
$patient->shipping_state = $request->input('state');
|
||||
$patient->shipping_city = $request->input('city');
|
||||
$patient->shipping_zipcode = $request->input('zip');
|
||||
|
||||
|
||||
$image = $request->get('profile_pic');
|
||||
$fileName = 'profile-' . time();
|
||||
|
||||
$logo = base64_decode($image);
|
||||
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
||||
|
||||
$imageName = $fileName . '.' . $ext;
|
||||
Storage::disk('local')->put("public/profile_pictures/" . $imageName, $logo);
|
||||
$patient->profile_picture = $imageName;
|
||||
$patient->save();
|
||||
|
||||
|
||||
if ($patient->dob) {
|
||||
$birthDate = new DateTime($patient->dob);
|
||||
$today = new DateTime(date('Y-m-d'));
|
||||
$age = $today->diff($birthDate)->y;
|
||||
$patient->age = $age;
|
||||
} else {
|
||||
$patient->age = 0;
|
||||
}
|
||||
PatientRegActivity::create([
|
||||
'patient_id' => $patient->id,
|
||||
'activity' => 'patient_registered'
|
||||
]);
|
||||
$setting = Setting::find(1);
|
||||
event(new PatientRegistered($patient, $validatedData));
|
||||
return response()
|
||||
->json([
|
||||
'data' => $patient
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function patientShippingAddress($id, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'edit', new Patient);
|
||||
$patient = Patient::find($id);
|
||||
$patient->shipping_address = $request->input('address');
|
||||
$patient->shipping_state = $request->input('state');
|
||||
$patient->shipping_city = $request->input('city');
|
||||
$patient->shipping_zipcode = $request->input('zip');
|
||||
$patient->save();
|
||||
return response()
|
||||
->json([
|
||||
'data' => $patient
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function patientList(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Patient);
|
||||
$patients = Patient::query();
|
||||
|
||||
// Filter by state
|
||||
if ($request->input('state') != "all") {
|
||||
$patients->where('patients.state', $request->input('state'));
|
||||
}
|
||||
|
||||
// Filter by gender
|
||||
if ($request->input('gender') != "all") {
|
||||
$patients->where('patients.gender', $request->input('gender'));
|
||||
}
|
||||
|
||||
// Filter by plan (assuming you have a plan field or relation)
|
||||
if ($request->input('plan') != "all") {
|
||||
$planNames = $request->input('plan');
|
||||
|
||||
$patients->leftJoin('patient_plan', 'patients.id', '=', 'patient_plan.patient_id')
|
||||
->leftJoin('plans_v1', 'patient_plan.plan_id', '=', 'plans_v1.id')
|
||||
->where('plans_v1.slug', $planNames);
|
||||
}
|
||||
|
||||
// Join with the carts table to get order details
|
||||
$patients->leftJoin('carts', 'patients.id', '=', 'carts.patient_id')
|
||||
->select('patients.*')
|
||||
->addSelect([
|
||||
'last_order_date' => Cart::selectRaw('MAX(created_at)')
|
||||
->whereColumn('patient_id', 'patients.id'),
|
||||
'total_orders' => Cart::selectRaw('COUNT(*)')
|
||||
->whereColumn('patient_id', 'patients.id'),
|
||||
'total_subscriptions' => Cart::selectRaw('COUNT(DISTINCT start_subscription)')
|
||||
->whereColumn('patient_id', 'patients.id'),
|
||||
]);
|
||||
|
||||
Log::info('PatientList Datatable:', [
|
||||
'sql' => $patients->toSql(),
|
||||
'bindings' => $patients->getBindings()
|
||||
]);
|
||||
|
||||
// Use DataTables to process the query
|
||||
return DataTables::of($patients)->make(true);
|
||||
} catch (\Exception | Error $e) {
|
||||
// Log the error
|
||||
Log::error('Error in patientList: ' . $e->getMessage());
|
||||
// Return an error response
|
||||
return response()->json([
|
||||
'error' => 'An error occurred while processing the request.',
|
||||
'message' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
public function patientFullDetail(Patient $patient)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'edit', new Patient);
|
||||
$patient->first_name = $patient->first_name . " " . $patient->last_name;
|
||||
$plans = PatientPlan::join('plans_v1', 'patient_plan.plan_id', '=', 'plans_v1.id')
|
||||
->leftJoin('medication_categories', 'plans_v1.medication_category_id', '=', 'medication_categories.id')
|
||||
->where('patient_plan.patient_id', $patient->id)
|
||||
->select('plans_v1.*', 'medication_categories.category_name')
|
||||
->orderBy('plans_v1.created_at', 'desc')
|
||||
->first();
|
||||
$upcomingMeetings = Appointment::select(
|
||||
'appointments.patient_id',
|
||||
'appointments.timezone',
|
||||
'appointments.appointment_time',
|
||||
'appointments.appointment_date',
|
||||
'carts.id as order_id'
|
||||
)
|
||||
->leftJoin("carts", "carts.appointment_id", "appointments.id")
|
||||
->where("appointments.patient_id", $patient->id)
|
||||
// dd(Constant::getFullSql($upcomingMeetings));
|
||||
->get();
|
||||
$completedMeetings = Appointment::select(
|
||||
'appointments.patient_id',
|
||||
'appointments.appointment_time',
|
||||
'appointments.appointment_date',
|
||||
'appointments.start_time',
|
||||
'appointments.end_time',
|
||||
'appointments.timezone',
|
||||
'telemed_pros.name as provider_name',
|
||||
'telemed_pros_id as provider_id',
|
||||
'carts.id as order_id'
|
||||
)
|
||||
->leftJoin('telemed_pros', 'telemed_pros.id', 'appointments.telemed_pros_id')
|
||||
->leftJoin("carts", "carts.appointment_id", "appointments.id")
|
||||
->where("appointments.patient_id", $patient->id)
|
||||
->where('appointments.start_time', "!=", null)
|
||||
->where('appointments.end_time', "!=", null)
|
||||
->get();
|
||||
$patientNotes = PatientNote::select(
|
||||
'patient_notes.id',
|
||||
'patient_notes.note',
|
||||
'patient_notes.note_type',
|
||||
'telemed_pros.name as provider_name',
|
||||
'telemed_pros.id as provider_id',
|
||||
'patient_notes.created_at',
|
||||
'patient_notes.patient_id',
|
||||
'carts.id as order_id',
|
||||
'patient_notes.created_by_id',
|
||||
'patient_notes.created_by_type'
|
||||
)
|
||||
->leftJoin('telemed_pros', 'patient_notes.telemed_pros_id', 'telemed_pros.id')
|
||||
->leftJoin("carts", "carts.appointment_id", "patient_notes.appointment_id")
|
||||
->where("patient_notes.patient_id", $patient->id)
|
||||
->get();
|
||||
|
||||
foreach ($patientNotes as $notes) {
|
||||
if ($notes->note_type != 'Notes')
|
||||
$notes->note = $this->url->to("assets/files/" . $notes->patient_id . ".png");
|
||||
else
|
||||
$notes->note = $notes->note;
|
||||
}
|
||||
$patientPrescription = PatientPrescription::select(
|
||||
'patient_prescription.*',
|
||||
'telemed_pros.name as provider_name',
|
||||
'prescriptions.*',
|
||||
'carts.id as order_id'
|
||||
)
|
||||
->leftJoin('appointments', 'patient_prescription.appointment_id', 'appointments.id')
|
||||
->leftJoin("carts", "carts.appointment_id", "appointments.id")
|
||||
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', 'telemed_pros.id')
|
||||
->leftJoin('prescriptions', 'prescriptions.id', 'patient_prescription.prescription_id')
|
||||
->where('patient_prescription.patient_id', $patient->id)->get();
|
||||
$patient->profile_completion_Percentage = $patient->profile_completion_Percentage;
|
||||
$labkits = LabkitOrderItem::leftJoin(
|
||||
'lab_kit',
|
||||
'labkit_order_items.lab_kit_id',
|
||||
'lab_kit.id'
|
||||
)
|
||||
->leftJoin(
|
||||
'items',
|
||||
'items.id',
|
||||
'labkit_order_items.item_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'plans_v1',
|
||||
'plans_v1.id',
|
||||
'items.plans_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'carts',
|
||||
'carts.id',
|
||||
'labkit_order_items.cart_id'
|
||||
)
|
||||
->where('carts.patient_id', $patient->id)
|
||||
->select(
|
||||
'labkit_order_items.id',
|
||||
'labkit_order_items.status',
|
||||
'labkit_order_items.result',
|
||||
'lab_kit.name as lab_kit_name',
|
||||
'plans_v1.id as product_id',
|
||||
'plans_v1.title as product_name'
|
||||
)
|
||||
->get();
|
||||
$orderList = Cart::select("appointments.*", 'appointments.id as appointment_id', 'carts.*', 'carts.id as order_id', 'telemed_pros.name as agent_name', 'telemed_pros.email as agent_email')
|
||||
->leftJoin('appointments', 'appointments.id', 'carts.appointment_id')
|
||||
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', '=', 'telemed_pros.id')
|
||||
->where('appointments.patient_id', $patient->id);
|
||||
|
||||
$orderListData = $orderList->get();
|
||||
return response()->json([
|
||||
'patient' => $patient,
|
||||
'plans' => $plans,
|
||||
'upcomingMeetings' => $upcomingMeetings,
|
||||
'completed_meetings' => $completedMeetings,
|
||||
'patientNotes' => $patientNotes,
|
||||
'prescriptionData' => $patientPrescription,
|
||||
'labkit' => $labkits,
|
||||
'orderListData' => $orderListData,
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function patientDelete(Patient $patient)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'delete', new Patient);
|
||||
Patient::where("id", $patient->id)->delete();
|
||||
return response()->json([
|
||||
'patient' => "Deleted Successfully"
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function patientUpdate(Patient $patient, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'edit', new Patient);
|
||||
$patient->first_name = $request->input('first_name');
|
||||
$patient->last_name = $request->input('last_name');
|
||||
$patient->phone_no = $request->input('phone_no');
|
||||
$patient->shipping_address = $request->input('gender');
|
||||
$patient->shipping_address = $request->input('dob');
|
||||
if ($request->input('password')) {
|
||||
$patient->password = Hash::make($request->input('password'));
|
||||
}
|
||||
$patient->shipping_address = $request->input('address');
|
||||
$patient->shipping_state = $request->input('state');
|
||||
$patient->shipping_city = $request->input('city');
|
||||
$patient->shipping_zipcode = $request->input('zip');
|
||||
$patient->shipping_country = $request->input('country');
|
||||
|
||||
$patient->save();
|
||||
return response()->json([
|
||||
'message' => 'Patient updated successfully',
|
||||
'telemed' => $patient
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function getNotePatient(Patient $patient, Appointment $appointment, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'patient_notes', new Patient);
|
||||
$patientNotes = PatientNote::where("patient_id", $patient->id)
|
||||
->where("appointment_id", $appointment->id)
|
||||
->with('appointment')
|
||||
->get();
|
||||
|
||||
$data = $patientNotes->map(function ($patientNote) {
|
||||
$fileUrl = "/assets/files/{$patientNote->id}.png";
|
||||
$filePath = public_path($fileUrl);
|
||||
|
||||
if (File::exists($filePath)) {
|
||||
$fileUrl = "/assets/files/{$patientNote->id}.png";
|
||||
} else {
|
||||
$fileUrl = null;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $patientNote->id,
|
||||
'note' => $patientNote->note,
|
||||
'note_type' => $patientNote->note_type,
|
||||
'created_at' => $patientNote->created_at,
|
||||
'patient_id' => $patientNote->patient_id,
|
||||
'appointment' => $patientNote->appointment,
|
||||
'telemedPro' => $patientNote->telemedPro,
|
||||
'file_url' => $fileUrl,
|
||||
'telemedPro' => $patientNote->appointment?->telemedPro
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Patient notes retrieved',
|
||||
'data' => $data
|
||||
], 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function patient(Patient $patient)
|
||||
{
|
||||
return response()->json([
|
||||
'data' => $patient
|
||||
], 200);
|
||||
}
|
||||
public function getPatientPrescription($patient_id, $appointment_id)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'patinet_prescriptions', new Patient);
|
||||
$patientPrescription = PatientPrescription::with('prescription')
|
||||
->where('patient_id', $patient_id)
|
||||
->where('appointment_id', $appointment_id)
|
||||
->get();
|
||||
|
||||
$prescriptionData = [];
|
||||
foreach ($patientPrescription as $prescription) {
|
||||
$prescriptionData[] = [
|
||||
'patient' => $prescription->patient,
|
||||
'prescription' => $prescription->prescription,
|
||||
'created_at' => $prescription->created_at,
|
||||
'updated_at' => $prescription->updated_at,
|
||||
'direction_one' => $prescription->direction_one,
|
||||
'direction_two' => $prescription->direction_two,
|
||||
'dont_substitute' => $prescription->dont_substitute,
|
||||
'comments' => $prescription->comments,
|
||||
'appointment_id' => $prescription->appointment_id,
|
||||
'status' => $prescription->status,
|
||||
'appointment' => $prescription->appointment,
|
||||
'telemedPro' => $prescription->appointment->telemedPro,
|
||||
'licenseNumber' => LicenseNumberModel::where("provider_id", $patient_id)->orderBy('id', 'DESC')->first()
|
||||
];
|
||||
}
|
||||
if (!$patientPrescription->isEmpty()) {
|
||||
return response()->json($prescriptionData);
|
||||
} else {
|
||||
return response()->json(['message' => 'Prescription not found'], 404);
|
||||
}
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function storePatientPrescription(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'patinet_prescriptions', new Patient);
|
||||
$cart = Cart::find($request->input("order_id"));
|
||||
$prescription = PatientPrescription::create($request->all());
|
||||
$prescription->appointment_id = $cart->appointment_id;
|
||||
$prescription->status = "pending";
|
||||
$prescription->save();
|
||||
$patient = $prescription->patient;
|
||||
$setting = Setting::find(1);
|
||||
/* Mail::send('emails.prescriptionAdd', ['patient' => $patient, 'prescription' => $prescription, 'setting' => $setting], function ($message) use ($patient, $user) {
|
||||
$message->to($patient->email, $patient->first_name)
|
||||
->subject('New Prescription Details from ' . $user->name);
|
||||
}); */
|
||||
return response()->json($prescription, 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function updateStatusPrescription($patient_prescription_id, Request $request)
|
||||
{
|
||||
//
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'patinet_prescriptions_edit', new Patient);
|
||||
$status = $request->input("status");
|
||||
$prescription = PatientPrescription::find($patient_prescription_id);
|
||||
$prescription->status = $status;
|
||||
$prescription->save();
|
||||
$patient = $prescription->patient;
|
||||
$setting = Setting::find(1);
|
||||
/* Mail::send('emails.prescriptionUpdated', ['patient' => $patient, 'setting' => $setting], function ($message) use ($patient) {
|
||||
$message->to($patient->email, $patient->first_name)
|
||||
->subject('Prescription updated.');
|
||||
}); */
|
||||
return response()->json($prescription, 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function getStatusPrescription($patient_prescription_id)
|
||||
{
|
||||
$prescription = PatientPrescription::with(['prescription'])
|
||||
->findOrFail($patient_prescription_id);
|
||||
return response()->json($prescription, 200);
|
||||
}
|
||||
public function updatePatientPrescription($id, Request $request)
|
||||
{
|
||||
try {
|
||||
$prescription = PatientPrescription::findOrFail($id);
|
||||
$prescription->update($request->all());
|
||||
|
||||
if ($request->has('status')) {
|
||||
$prescription->status = $request->input('status');
|
||||
}
|
||||
|
||||
$prescription->save();
|
||||
|
||||
$patient = $prescription->patient;
|
||||
$setting = Setting::find(1);
|
||||
|
||||
// You might want to add email notification here if needed
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Prescription updated successfully',
|
||||
'data' => $prescription
|
||||
], 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'message' => 'An error occurred while updating the prescription',
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function deletePatientPrescription($id)
|
||||
{
|
||||
try {
|
||||
$prescription = PatientPrescription::findOrFail($id);
|
||||
$prescription->delete();
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Prescription deleted successfully'
|
||||
], 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'message' => 'An error occurred while deleting the prescription',
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
126
app/Http/Controllers/Admin/Api/PermissionsController.php
Normal file
126
app/Http/Controllers/Admin/Api/PermissionsController.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Permission;
|
||||
use App\Permissions\Permissions;
|
||||
use Illuminate\Http\Request;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels;
|
||||
use Yajra\DataTables\DataTables;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
class PermissionsController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'list', new Permission);
|
||||
$roleList = Permission::all();
|
||||
return Datatables::of($roleList)
|
||||
->toJson();
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
public function storeRole(Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'add', new Permission);
|
||||
Permission::create(
|
||||
[
|
||||
'role_name' => $request->input('role_name'),
|
||||
'role_guard' => $request->input('role_guard')
|
||||
]
|
||||
);
|
||||
return response()->json([
|
||||
'success' => 'Data Saved!'
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function editRoles($id)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new Permission);
|
||||
return response()->json([
|
||||
'data' => Permission::find($id)
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function updateRoles($id,Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new Permission);
|
||||
$permission = Permission::find($id);
|
||||
$permission->role_name = $request->input('role_name');
|
||||
$permission->role_guard = $request->input('role_guard');
|
||||
$permission->save();
|
||||
return response()->json([
|
||||
'data' => Permission::find($id)
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function deleteRoles($id){
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'delete', new Permission);
|
||||
Permission::find($id)->delete();
|
||||
return response()->json([
|
||||
'success' => 'role Deleted Successfully !'
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function updatePermissions($id,Request $request)
|
||||
{
|
||||
$permission = Permission::find($id);
|
||||
}
|
||||
public function getPermissions($id)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'list', new Permission);
|
||||
$role = Permission::find($id);
|
||||
$rolePermissions = $role->permissions;
|
||||
$permissionManager = new Permissions($rolePermissions);
|
||||
$permissions = $permissionManager->getPermissions();
|
||||
// $permissions = $permissionManager->permissionsApi();
|
||||
return response()->json([
|
||||
'data' => $permissions
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function savePermissions($id,Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new Permission);
|
||||
// $permissions = 'DASHBOARD_,DASHBOARD_FILTERS,DASHBOARD_DATA,PRODUCT_,PRODUCT_VIEW,PRODUCT_ADD,PRODUCT_EDIT,PRODUCT_DELETE,PROVIDER_,PROVIDER_VIEW,PROVIDER_ADD,PROVIDER_EDIT,PROVIDER_DELETE,ADMIN_,ADMIN_VIEW,ADMIN_ADD,ADMIN_EDIT,ADMIN_DELETE,ADMIN_SITE_SETTINGS,ADMIN_SECURITY';
|
||||
$permissions = $request->input('permisssions');
|
||||
$permissionsArray = explode(',',$permissions);
|
||||
|
||||
$permissionsData = Permission::find($id);
|
||||
$permissionsData->permissions = $permissionsArray;
|
||||
$permissionsData->save();
|
||||
return response()->json([
|
||||
'success' => "permissions saved !"
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
97
app/Http/Controllers/Admin/Api/PrescriptionController.php
Normal file
97
app/Http/Controllers/Admin/Api/PrescriptionController.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Prescription;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
class PrescriptionController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function index(){}
|
||||
public function create(Request $request){
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'add', new Prescription);
|
||||
$data = [
|
||||
'name'=>$request->input('name'),
|
||||
'brand'=>$request->input('brand'),
|
||||
'from'=>$request->input('from'),
|
||||
'dosage'=>$request->input('dosage'),
|
||||
'quantity'=>$request->input('quantity'),
|
||||
'direction_quantity'=>$request->input('direction_quantity'),
|
||||
'refill_quantity'=>$request->input('refill_quantity')
|
||||
];
|
||||
Prescription::create($data);
|
||||
return response()
|
||||
->json([
|
||||
'success' => "Data Saved !"
|
||||
], 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function update($id,Request $request){
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new Prescription);
|
||||
$prescription = $this->details($id);
|
||||
$prescription->name =$request->input('name');
|
||||
$prescription->brand =$request->input('brand');
|
||||
$prescription->from = $request->input('from');
|
||||
$prescription->dosage = $request->input('dosage');
|
||||
$prescription->quantity = $request->input('quantity');
|
||||
$prescription->direction_quantity = $request->input('direction_quantity');
|
||||
$prescription->refill_quantity = $request->input('refill_quantity');
|
||||
$prescription->save();
|
||||
return response()
|
||||
->json([
|
||||
'success' => "Data Updated !"
|
||||
], 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function details($id){
|
||||
try{
|
||||
// $this->authorizeForUser($this->user,'view', new Prescription);
|
||||
return Prescription::find($id);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function edit($id)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new Prescription);
|
||||
return response()
|
||||
->json([
|
||||
'data' => $this->details($id)
|
||||
], 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function delete($id)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'delete', new Prescription);
|
||||
Prescription::find($id)->delete();
|
||||
return response()
|
||||
->json([
|
||||
'success' => "Entry Deleted !"
|
||||
], 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
584
app/Http/Controllers/Admin/Api/ReportsController.php
Normal file
584
app/Http/Controllers/Admin/Api/ReportsController.php
Normal file
@ -0,0 +1,584 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Admin;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Item;
|
||||
use App\Models\ItemHistory;
|
||||
use App\Models\LabkitOrderItem;
|
||||
use App\Models\LicenseNumberModel;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\ProfileQuestion;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Telemedpro;
|
||||
use DateInterval;
|
||||
use DatePeriod;
|
||||
use DateTime;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use PhpParser\Node\Stmt\Const_;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
|
||||
class ReportsController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function providerReportFilters()
|
||||
{
|
||||
$providers = Telemedpro::select(
|
||||
DB::raw("CONCAT(license_numbers.license_number,',',license_numbers.state) as provider_license_number"),
|
||||
'appointments.patient_name',
|
||||
'appointments.appointment_date',
|
||||
'appointments.appointment_time',
|
||||
'appointments.timezone',
|
||||
'start_time',
|
||||
'end_time',
|
||||
'duration',
|
||||
DB::raw("CONCAT(patients.first_name,',',patients.last_name) as patient_name"),
|
||||
'patients.phone_no',
|
||||
'patients.email',
|
||||
'patients.address',
|
||||
'patients.city',
|
||||
'patients.state',
|
||||
'patients.zip_code',
|
||||
'patients.country',
|
||||
'patients.gender',
|
||||
'patients.dob',
|
||||
'patients.height',
|
||||
'patients.weight'
|
||||
)
|
||||
->LeftJoin('license_numbers', 'provider_id', 'telemed_pros.id')
|
||||
->LeftJoin('appointments', 'appointments.telemed_pros_id', 'telemed_pros.id')
|
||||
->leftJoin('patients', 'appointments.patient_id', 'patients.id')
|
||||
->whereNotNull('appointments.start_time')
|
||||
->whereNotNull('appointments.end_time')
|
||||
->get();
|
||||
|
||||
foreach ($providers as $provider) {
|
||||
$start_datetime = new DateTime($provider->start_time);
|
||||
$diff = $start_datetime->diff(new DateTime($provider->end_time));
|
||||
$duration = $diff->h . " hours " . $diff->i . " Min";
|
||||
// dd($providers->duration,$duration);
|
||||
$provider->duration = $duration;
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'provider_list' => $providers,
|
||||
]);
|
||||
}
|
||||
public function providerReportPost(Request $request)
|
||||
{
|
||||
return response()->json([
|
||||
'provider_list' => ''
|
||||
]);
|
||||
}
|
||||
public function overviewReport(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'overview_analytics', new ProfileQuestion);
|
||||
$start_date = $request->get('start_date');
|
||||
$end_date = $request->get('end_date');
|
||||
$totalOrdersStats = Cart::select(
|
||||
DB::raw("sum(case when carts.status = 'completed' then 1 else 0 end) as total_sales"),
|
||||
DB::raw("sum(case when carts.status = 'completed' then carts.total_amount else 0 end) as sales_amount"),
|
||||
DB::raw("count(items.id) as products_sold")
|
||||
)
|
||||
->Join('items', 'items.cart_id', 'carts.id')
|
||||
->where('carts.created_at', '>=', $start_date . " 00:00:00")
|
||||
->where('carts.created_at', '<=', $end_date . " 23:59:59")
|
||||
->where('carts.status', '=', 'completed')
|
||||
->get();
|
||||
$orderCollection = Cart::select(
|
||||
'carts.id as order_id',
|
||||
'carts.status',
|
||||
'carts.email',
|
||||
'carts.total_amount',
|
||||
'carts.created_at as date',
|
||||
DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name")
|
||||
)
|
||||
->where('carts.created_at', '>=', $start_date . " 00:00:00")
|
||||
->where('carts.created_at', '<=', $end_date . " 23:59:59")
|
||||
->where('carts.status', '=', 'completed')
|
||||
->get();
|
||||
$orderData = $orderCollection->map(function ($query, $key) {
|
||||
$patientType = $query->where('email', $query->email)->count();
|
||||
$itemSold = Item::select(DB::raw("GROUP_CONCAT(title SEPARATOR ', ') as items"))
|
||||
->where('cart_id', $query->order_id)
|
||||
->leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id');
|
||||
$itemCount = $itemSold->count();
|
||||
$products = $itemSold->first();
|
||||
if ($patientType > 1)
|
||||
$query->customer_type = 'returning';
|
||||
else
|
||||
$query->customer_type = 'new';
|
||||
|
||||
$query->products = $products->items ?? null;
|
||||
$query->item_sold = $itemCount ?? 0;
|
||||
|
||||
$query->attribution = 'direct';
|
||||
|
||||
return $query;
|
||||
});
|
||||
$dates = [];
|
||||
$sales = [];
|
||||
$startDate = Carbon::parse($start_date);
|
||||
$endDate = Carbon::parse($end_date);
|
||||
for ($date = $startDate; $date->lte($endDate); $date->addDay()) {
|
||||
$values = Cart::select(
|
||||
DB::raw('DATE(created_at) as date'),
|
||||
DB::raw("SUM(case when carts.status = 'completed' then carts.total_amount else 0 end) as amount")
|
||||
)
|
||||
->where('carts.created_at', '>=', $date->format("Y-m-d") . " 00:00:00")
|
||||
->where('carts.created_at', '<=', $date->format("Y-m-d") . " 23:59:59")
|
||||
->groupBy(DB::raw('DATE(created_at)'));
|
||||
$graphsValues = $values->first();
|
||||
|
||||
$dates[] = $date->format("M d/y");
|
||||
if ($graphsValues)
|
||||
$sales[] = $graphsValues->amount;
|
||||
else
|
||||
$sales[] = 0;
|
||||
}
|
||||
$newUser = 0;
|
||||
$returnUser = 0;
|
||||
$newUsers = [];
|
||||
$returningUsers = [];
|
||||
//getting here unique rows for patient stats
|
||||
$uniqueKeys = array_map(function ($item) {
|
||||
return $item['email'];
|
||||
}, $orderCollection->toArray());
|
||||
|
||||
$uniqueRecords = array_intersect_key($orderCollection->toArray(), array_unique($uniqueKeys));
|
||||
$uniqueRecords = array_values($uniqueRecords);
|
||||
|
||||
foreach ($orderCollection as $userStats) {
|
||||
$userStatus = Cart::where('email', $userStats->email)->count();
|
||||
if ($userStatus > 1) {
|
||||
$returnUser++;
|
||||
$returningUsers[] = $userStats;
|
||||
} else {
|
||||
$newUser++;
|
||||
$newUsers[] = $userStats;
|
||||
}
|
||||
};
|
||||
|
||||
$percentageReturning = 0;
|
||||
$percentageNewuser = 0;
|
||||
if ($returnUser > 0 || $newUser > 0) {
|
||||
$percentageReturning = ($returnUser / ($returnUser + $newUser)) * 100;
|
||||
$percentageNewuser = ($newUser / ($returnUser + $newUser)) * 100;
|
||||
}
|
||||
|
||||
//check here users engagement
|
||||
|
||||
$newUserEngagement = $this->calculateEngagement($newUsers);
|
||||
$returningUserEngagement = $this->calculateEngagement($returningUsers);
|
||||
return response()->json([
|
||||
'totals' => $totalOrdersStats,
|
||||
'orders' => $orderData,
|
||||
'chart' => [
|
||||
'chart_dates' => $dates,
|
||||
'chart_data' => $sales
|
||||
],
|
||||
'patient_stats' =>
|
||||
[
|
||||
'returning_users' => [$returnUser, round($percentageReturning, 0) . "%"],
|
||||
'new_users' => [$newUser, round($percentageNewuser, 0) . "%"]
|
||||
]
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function ordersFilters()
|
||||
{
|
||||
$patient = Patient::select('id', DB::raw("CONCAT(first_name,' ',last_name) as patient_name"))->get();
|
||||
return response()->json([
|
||||
'patients' => $patient
|
||||
|
||||
]);
|
||||
}
|
||||
public function initialPatients()
|
||||
{
|
||||
$patients = Patient::select('id', DB::raw("CONCAT(first_name,' ',last_name) as patient_name"))
|
||||
->limit(100)
|
||||
->orderBy('patient_name', 'asc')
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'patients' => $patients
|
||||
]);
|
||||
}
|
||||
|
||||
public function searchPatients(Request $request)
|
||||
{
|
||||
$searchTerm = $request->input('term');
|
||||
|
||||
$patients = Patient::select('id', DB::raw("CONCAT(first_name,' ',last_name) as patient_name"))
|
||||
->where(DB::raw("CONCAT(first_name,' ',last_name)"), 'LIKE', "%{$searchTerm}%")
|
||||
->limit(500)
|
||||
->orderBy('patient_name', 'asc')
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'patients' => $patients
|
||||
]);
|
||||
}
|
||||
|
||||
// Function to calculate engagement metrics
|
||||
function calculateEngagement($users)
|
||||
{
|
||||
$totalUsers = count($users);
|
||||
$completedOrders = 0;
|
||||
$totalAmount = 0;
|
||||
|
||||
foreach ($users as $user) {
|
||||
if ($user['status'] === 'delivered') {
|
||||
$completedOrders++;
|
||||
}
|
||||
$totalAmount += floatval($user['total_amount']);
|
||||
}
|
||||
|
||||
$orderCompletionRate = $totalUsers > 0 ? ($completedOrders / $totalUsers) * 100 : 0;
|
||||
$averageOrderValue = $totalUsers > 0 ? $totalAmount / $totalUsers : 0;
|
||||
|
||||
return [
|
||||
'total_users' => $totalUsers,
|
||||
'completed_orders' => $completedOrders,
|
||||
'order_completion_rate' => $orderCompletionRate,
|
||||
'average_order_value' => $averageOrderValue
|
||||
];
|
||||
}
|
||||
public function ordersReport(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'orders_analytics', new ProfileQuestion);
|
||||
$start_date = $request->get('start_date');
|
||||
$end_date = $request->get('end_date');
|
||||
$status = $request->get('status');
|
||||
$patient = $request->get('patient');
|
||||
$query = Cart::select(
|
||||
'carts.id as order_id',
|
||||
'carts.status',
|
||||
'carts.email',
|
||||
'carts.total_amount',
|
||||
'carts.created_at as date',
|
||||
DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name")
|
||||
)
|
||||
->where('carts.created_at', '>=', $start_date . " 00:00:00")
|
||||
->where('carts.created_at', '<=', $end_date . " 23:59:59");
|
||||
|
||||
// Apply filters
|
||||
if ($status != 'all') {
|
||||
$query->where('carts.status', $status);
|
||||
}
|
||||
|
||||
if ($patient != 'all') {
|
||||
$query->where('carts.patient_id', $patient);
|
||||
}
|
||||
$dates = [];
|
||||
$sales = [];
|
||||
$startDate = Carbon::parse($start_date);
|
||||
$endDate = Carbon::parse($end_date);
|
||||
for ($date = $startDate; $date->lte($endDate); $date->addDay()) {
|
||||
$values = Cart::select(
|
||||
DB::raw('DATE(created_at) as date'),
|
||||
DB::raw("SUM(carts.total_amount) as amount")
|
||||
)
|
||||
->where('carts.created_at', '>=', $date->format("Y-m-d") . " 00:00:00")
|
||||
->where('carts.created_at', '<=', $date->format("Y-m-d") . " 23:59:59")
|
||||
->groupBy(DB::raw('DATE(created_at)'));
|
||||
if ($status != 'all') {
|
||||
$values->where('carts.status', $status);
|
||||
}
|
||||
|
||||
if ($patient != 'all') {
|
||||
$values->where('carts.patient_id', $patient);
|
||||
}
|
||||
$graphsValues = $values->first();
|
||||
|
||||
$dates[] = $date->format("M d/y");
|
||||
if ($graphsValues)
|
||||
$sales[] = $graphsValues->amount;
|
||||
else
|
||||
$sales[] = 0;
|
||||
}
|
||||
// dd(Constant::getFullSql($query));
|
||||
$orderCollection = $query->get();
|
||||
$orderData = $orderCollection->map(function ($cart) {
|
||||
$patientType = Cart::where('email', $cart->email)->count();
|
||||
|
||||
$itemSold = Item::select(DB::raw("GROUP_CONCAT(plans_v1.title SEPARATOR ', ') as items"))
|
||||
->where('cart_id', $cart->order_id)
|
||||
->leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id');
|
||||
$itemCount = $itemSold->count();
|
||||
$products = $itemSold->first();
|
||||
|
||||
$cart->customer_type = $patientType > 1 ? 'returning' : 'new';
|
||||
$cart->products = $products->items ?? null;
|
||||
$cart->item_sold = $itemCount ?? null;
|
||||
$cart->attribution = 'direct';
|
||||
|
||||
return $cart;
|
||||
});
|
||||
$totalOrdersStats = Cart::select(
|
||||
// DB::raw("sum(case when carts.status = 'delivered' then 1 else 0 end) as total_sales"),
|
||||
DB::raw("count(carts.id) as total_sales"),
|
||||
DB::raw("sum(carts.total_amount ) as sales_amount"),
|
||||
DB::raw("count(items.id) as products_sold")
|
||||
)
|
||||
->Join('items', 'items.cart_id', 'carts.id')
|
||||
->where('carts.created_at', '>=', $start_date . " 00:00:00")
|
||||
->where('carts.created_at', '<=', $end_date . " 23:59:59");
|
||||
|
||||
if ($status != 'all') {
|
||||
|
||||
$totalOrdersStats->where('carts.status', $status);
|
||||
}
|
||||
|
||||
if ($patient != 'all') {
|
||||
$totalOrdersStats->where('carts.patient_id', $patient);
|
||||
}
|
||||
$totals = $totalOrdersStats->get();
|
||||
return response()->json([
|
||||
'orders' => $orderData,
|
||||
'totals' => $totals,
|
||||
'chart' => [
|
||||
'chart_dates' => $dates,
|
||||
'chart_data' => $sales
|
||||
]
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function productAnalytics(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'orders_analytics', new ProfileQuestion);
|
||||
$start_date = $request->get('start_date');
|
||||
$end_date = $request->get('end_date');
|
||||
$singleProduct = $request->get('single_product');
|
||||
$patient = $request->get('patient');
|
||||
$query = Item::select(
|
||||
DB::raw("sum(case when items.status='delivered' then items.quantity else 0 end) as total_item_sold"),
|
||||
DB::raw("sum(case when items.status='delivered' then 1 else 0 end) as total_orders"),
|
||||
DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as total_amount"),
|
||||
'plans_v1.title as product_name',
|
||||
'items.plans_id as product_id'
|
||||
)
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->where('items.created_at', '>=', $start_date . " 00:00:00")
|
||||
->where('items.created_at', '<=', $end_date . " 23:59:59")
|
||||
->where('items.status', 'delivered')
|
||||
->groupby('plans_v1.title', 'items.plans_id');
|
||||
// Apply filters
|
||||
if ($singleProduct != 'all') {
|
||||
$query->where('items.plans_id', $singleProduct);
|
||||
}
|
||||
|
||||
$dates = [];
|
||||
$sales = [];
|
||||
$startDate = Carbon::parse($start_date);
|
||||
$endDate = Carbon::parse($end_date);
|
||||
for ($date = $startDate; $date->lte($endDate); $date->addDay()) {
|
||||
$graphsValues = Item::select(
|
||||
DB::raw("sum(case when items.status='delivered' then 1 else 0 end) as total_orders"),
|
||||
DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as total_amount"),
|
||||
)
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->where('items.created_at', '>=', $date->format("Y-m-d") . " 00:00:00")
|
||||
->where('items.created_at', '<=', $date->format("Y-m-d") . " 23:59:59")
|
||||
->where('items.status', 'delivered')
|
||||
->groupby('plans_v1.title', 'items.plans_id');
|
||||
|
||||
if ($singleProduct != 'all') {
|
||||
$graphsValues->where('items.plans_id', $singleProduct);
|
||||
}
|
||||
|
||||
$graphVal = $graphsValues->first();
|
||||
|
||||
$dates[] = $date->format("M d/y");
|
||||
if ($graphVal)
|
||||
$sales[] = $graphVal->total_amount;
|
||||
else
|
||||
$sales[] = 0;
|
||||
}
|
||||
$orderData = $query->get();
|
||||
$totalOrdersStats = Item::select(
|
||||
DB::raw("count(items.id) as total_orders"),
|
||||
DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as sales_amount"),
|
||||
DB::raw("sum(case when items.status='delivered' then items.quantity else 0 end) as products_sold")
|
||||
)
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->where('items.created_at', '>=', $start_date . " 00:00:00")
|
||||
->where('items.created_at', '<=', $end_date . " 23:59:59")
|
||||
->where('items.status', 'delivered');
|
||||
|
||||
if ($singleProduct != 'all') {
|
||||
$totalOrdersStats->where('items.plans_id', $singleProduct);
|
||||
}
|
||||
$totals = $totalOrdersStats->get();
|
||||
return response()->json([
|
||||
'orders' => $orderData,
|
||||
'totals' => $totals,
|
||||
'chart' => [
|
||||
'chart_dates' => $dates,
|
||||
'chart_data' => $sales
|
||||
]
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function totalSales()
|
||||
{
|
||||
$start_date = request()->input('start_date');
|
||||
$end_date = request()->input('end_date');
|
||||
$startDate = Carbon::parse($start_date);
|
||||
$endDate = Carbon::parse($end_date);
|
||||
$sales = [];
|
||||
for ($date = $startDate; $date->lte($endDate); $date->addDay()) {
|
||||
$graphsValues = Item::select(
|
||||
DB::raw("sum(case when items.status='delivered' then 1 else 0 end) as total_orders"),
|
||||
DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as total_amount"),
|
||||
)
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->where('items.created_at', '>=', $date->format("Y-m-d") . " 00:00:00")
|
||||
->where('items.created_at', '<=', $date->format("Y-m-d") . " 23:59:59")
|
||||
->where('items.status', 'delivered')
|
||||
->groupby('plans_v1.title', 'items.plans_id');
|
||||
|
||||
$graphVal = $graphsValues->first();
|
||||
|
||||
$dates[] = $date->format("M d/y");
|
||||
if ($graphVal) {
|
||||
$sales[$date->format("Y-m-d")] = ["total_amount" => $graphVal->total_amount, "order_count" => $graphVal->total_orders];
|
||||
} else {
|
||||
$sales[$date->format("Y-m-d")] = ["total_amount" => 0, "order_count" => 0];
|
||||
}
|
||||
}
|
||||
dd($dates, $sales);
|
||||
}
|
||||
public function ordersAnalytics(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'orders_analytics', new ProfileQuestion);
|
||||
$start_date = $request->get('start_date');
|
||||
$end_date = $request->get('end_date');
|
||||
$singleProduct = $request->get('single_product');
|
||||
$query = Cart::select(
|
||||
'carts.id as order_id',
|
||||
"carts.status as order_status",
|
||||
"carts.created_at as order_date",
|
||||
DB::raw("GROUP_CONCAT(plans_v1.title SEPARATOR ', ') as items"),
|
||||
DB::raw("CONCAT(carts.first_name,' ',carts.last_name) as patient_name"),
|
||||
"carts.total_amount",
|
||||
DB::raw("sum(case when carts.status='completed' then 1 else 0 end) as item_sold")
|
||||
)
|
||||
->leftJoin('items', 'items.cart_id', 'carts.id')
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->where('carts.created_at', '>=', $start_date . " 00:00:00")
|
||||
->where('carts.created_at', '<=', $end_date . " 23:59:59")
|
||||
->where('carts.status', 'completed')
|
||||
->groupby('carts.id',
|
||||
'carts.status',
|
||||
'carts.created_at',
|
||||
DB::raw("CONCAT(carts.first_name,' ',carts.last_name)"),
|
||||
"carts.total_amount");
|
||||
|
||||
$dates = [];
|
||||
$sales = [];
|
||||
$singleMonth = [];
|
||||
$current_month = null;
|
||||
$graphDates = null;
|
||||
$startDate = Carbon::parse($start_date);
|
||||
$endDate = Carbon::parse($end_date);
|
||||
for ($date = $startDate; $date->lte($endDate); $date->addDay())
|
||||
{
|
||||
$graphsValues = Cart::select(
|
||||
DB::raw('DATE(created_at) as date'),
|
||||
DB::raw("SUM(carts.total_amount) as amount")
|
||||
)
|
||||
->where('carts.created_at', '>=', $date->format("Y-m-d") . " 00:00:00")
|
||||
->where('carts.created_at', '<=', $date->format("Y-m-d") . " 23:59:59")
|
||||
->where('carts.status', 'completed')
|
||||
->groupBy(DB::raw('DATE(created_at)'));
|
||||
$graphVal = $graphsValues->first();
|
||||
|
||||
$month = $date->format('F Y');
|
||||
|
||||
if ($month != $current_month)
|
||||
{
|
||||
// Month has changed or it's the first iteration, echo the first day of the month
|
||||
$dates[] = $month;
|
||||
$current_month = $month;
|
||||
} else {
|
||||
|
||||
$dates[] = " ";
|
||||
}
|
||||
|
||||
$singleMonth[] = $date->format("M d/y");
|
||||
|
||||
if ($graphVal)
|
||||
$sales[] = $graphVal->amount;
|
||||
else
|
||||
$sales[] = 0;
|
||||
}
|
||||
// count if user select more then one month
|
||||
$dateIterate = $this->monthItrator($start_date, $end_date);
|
||||
if ($dateIterate == 1)
|
||||
$graphDates = $singleMonth;
|
||||
else
|
||||
$graphDates = $dates;
|
||||
|
||||
$orderData = $query->get();
|
||||
$totalOrdersStats = Item::select(
|
||||
DB::raw("count(items.id) as total_orders"),
|
||||
DB::raw("sum(case when items.status='delivered' then (items.quantity*plans_v1.price) else 0 end) as sales_amount"),
|
||||
DB::raw("sum(case when items.status='delivered' then items.quantity else 0 end) as products_sold")
|
||||
)
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->where('items.created_at', '>=', $start_date . " 00:00:00")
|
||||
->where('items.created_at', '<=', $end_date . " 23:59:59")
|
||||
->where('items.status', 'delivered');
|
||||
|
||||
$totals = $totalOrdersStats->get();
|
||||
return response()->json([
|
||||
'orders' => $orderData,
|
||||
'totals' => $totals,
|
||||
'chart' => [
|
||||
'chart_dates' => $graphDates,
|
||||
'chart_data' => $sales
|
||||
]
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function monthItrator($start_date, $end_date)
|
||||
{
|
||||
|
||||
$start = (clone Carbon::parse($start_date))->modify('first day of this month');
|
||||
$end = (clone Carbon::parse($end_date))->modify('first day of next month');
|
||||
|
||||
$interval = DateInterval::createFromDateString('1 month');
|
||||
$period = new DatePeriod($start, $interval, $end);
|
||||
return iterator_count($period);
|
||||
}
|
||||
}
|
105
app/Http/Controllers/Admin/Api/SiteSettingsController.php
Normal file
105
app/Http/Controllers/Admin/Api/SiteSettingsController.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Admin;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
class SiteSettingsController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function getSiteSettings(Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'list', new Setting);
|
||||
$settings = Setting::first();
|
||||
$favicon = $this->url->to("/" . $settings->favicon);
|
||||
$logo = $this->url->to("/assets/logo/" . $settings->logo);
|
||||
$settings['favicon'] = $favicon;
|
||||
$settings['logo'] = $logo;
|
||||
return response()->json([
|
||||
'settings_data' => $settings
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function updateSettings($id, Request $request)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new Setting);
|
||||
$settings = Setting::find($id);
|
||||
//upload website logo
|
||||
$fileName = 'logo-' . time();
|
||||
$logoPath = public_path() . '/assets/logo/';
|
||||
$imageName = $this->uploadImage($request->get('logo'), $fileName, $logoPath);
|
||||
////////////////
|
||||
//upload favicon
|
||||
$fileName = 'favicon-' . time();
|
||||
$faviconPath = public_path('/');
|
||||
$faviconImageName = $this->uploadImage($request->get('favicon'), $fileName, $faviconPath);
|
||||
/////////////////////////////
|
||||
$settings->plan_main_title = $request->get('plan_main_title');
|
||||
$settings->plan_description = $request->get('plan_description');
|
||||
$settings->plan_description_pargraph = $request->get('plan_description_pargraph');
|
||||
if ($request->get('logo'))
|
||||
$settings->logo = $imageName;
|
||||
$settings->footer_text = $request->get('footer_text');
|
||||
if ($request->get('favicon'))
|
||||
$settings->favicon = $faviconImageName;
|
||||
$settings->header_title = $request->get('header_title');
|
||||
$settings->domain_name = $request->get('domain_name');
|
||||
$settings->save();
|
||||
return response()->json([
|
||||
'msg' => "Settings updated "
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function uploadImage($image, $fileName, $path)
|
||||
{
|
||||
try{
|
||||
$this->authorizeForUser($this->user,'edit', new Setting);
|
||||
$logo = base64_decode($image);
|
||||
$filename = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[0]);
|
||||
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
||||
$imageName = $fileName . '.' . $ext;
|
||||
$path = $path . $imageName;
|
||||
file_put_contents($path, $logo);
|
||||
return $imageName;
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function passwordReset(Request $request)
|
||||
{
|
||||
$userId = Auth::guard('admin')->user()->id;
|
||||
$user = Admin::find($userId);
|
||||
if (Hash::check($request->get('password'), $user->password)) {
|
||||
$password = $request->get('new_password');
|
||||
$user->password = bcrypt($password);
|
||||
$user->save();
|
||||
return response()->json([
|
||||
'msg' => "Password updated"
|
||||
]);
|
||||
} else {
|
||||
return response()->json([
|
||||
'msg' => "Password does not match",
|
||||
'status' => 'error'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
225
app/Http/Controllers/Admin/Api/SubscriptionController.php
Normal file
225
app/Http/Controllers/Admin/Api/SubscriptionController.php
Normal file
@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use Agence104\LiveKit\VideoGrant;
|
||||
use App\Classes\Constant;
|
||||
use App\Events\AppointmentBooked;
|
||||
use App\Events\PaymentProcessed;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Admin;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Item;
|
||||
use App\Models\ItemHistory;
|
||||
use App\Models\Lab;
|
||||
use App\Models\LabKit;
|
||||
use App\Models\LabkitOrderItem;
|
||||
use App\Models\LicenseNumberModel;
|
||||
use App\Models\MedicalHistoryAnswer;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPlan;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\PatientRegActivity;
|
||||
use App\Models\Plan;
|
||||
use App\Models\PlanV1;
|
||||
use App\Models\Prescription;
|
||||
use App\Models\ProfileAnswer;
|
||||
use App\Models\ProfileCategory;
|
||||
use App\Models\QuestionBuilder;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Subscription;
|
||||
use App\Models\Telemedpro;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonTimeZone;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Error;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Yajra\DataTables\DataTables;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Agence104\LiveKit\AccessToken;
|
||||
use Agence104\LiveKit\AccessTokenOptions;
|
||||
use Agence104\LiveKit\RoomCreateOptions;
|
||||
use Agence104\LiveKit\RoomServiceClient;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
|
||||
class SubscriptionController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
|
||||
public function getSubscriptionList()
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Subscription);
|
||||
|
||||
$subscriptions = Subscription::with(['cart', 'item.plansV1', 'patient'])
|
||||
->join('patients', 'subscription.patient_id', '=', 'patients.id') // Join with the patient table
|
||||
->join('items', 'subscription.item_id', '=', 'items.id') // Join with the plansV1 table
|
||||
->join('plans_v1', 'items.plans_id', '=', 'plans_v1.id') // Join with the plansV1 table
|
||||
|
||||
->select([
|
||||
'subscription.*',
|
||||
'patients.first_name',
|
||||
'patients.last_name',
|
||||
'plans_v1.title as product_title',
|
||||
'plans_v1.price as price'
|
||||
]); // Select necessary columns
|
||||
|
||||
return DataTables::of($subscriptions)
|
||||
->addColumn('product_title', function ($subscription) {
|
||||
return $subscription->item?->plansV1?->title ?? 'N/A';
|
||||
})
|
||||
->addColumn('price', function ($subscription) {
|
||||
return $subscription->item?->plansV1?->price ?? 'N/A';
|
||||
})
|
||||
->addColumn('currency', function ($subscription) {
|
||||
$plan = $subscription->item?->plansV1;
|
||||
return $plan ? $plan->currency : 'N/A';
|
||||
})
|
||||
->addColumn('first_name', function ($subscription) {
|
||||
return $subscription->first_name ?? 'N/A';
|
||||
})
|
||||
->addColumn('last_name', function ($subscription) {
|
||||
return $subscription->last_name ?? 'N/A';
|
||||
})
|
||||
->filterColumn('first_name', function ($query, $keyword) {
|
||||
$query->where('patients.first_name', 'like', "%{$keyword}%");
|
||||
})
|
||||
->filterColumn('last_name', function ($query, $keyword) {
|
||||
$query->where('patients.last_name', 'like', "%{$keyword}%");
|
||||
})
|
||||
->filterColumn('product_title', function ($query, $keyword) {
|
||||
$query->where('plans_v1.title', 'like', "%{$keyword}%");
|
||||
})
|
||||
->filterColumn('product_price', function ($query, $keyword) {
|
||||
$query->where('plans_v1.price', 'like', "%{$keyword}%");
|
||||
})
|
||||
->make(true);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function updateSubscription(Request $request, $subid)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'edit', new Subscription);
|
||||
// Find the subscription
|
||||
$subscription = Subscription::find($subid);
|
||||
if (!$subscription) {
|
||||
return response()->json(['message' => 'Subscription not found'], 404);
|
||||
}
|
||||
// Define the fillable fields
|
||||
$fillable = [
|
||||
'subscription_start_date',
|
||||
'subscription_renewal_date',
|
||||
'subscription_status',
|
||||
'cart_id',
|
||||
'item_id',
|
||||
'patient_id',
|
||||
'status'
|
||||
];
|
||||
// Filter the request data to only include fillable fields that are present
|
||||
$dataToUpdate = array_filter(
|
||||
$request->only($fillable),
|
||||
function ($value) {
|
||||
return $value !== null;
|
||||
}
|
||||
);
|
||||
|
||||
// Validate the filtered data
|
||||
$validator = Validator::make($dataToUpdate, [
|
||||
'subscription_start_date' => 'required',
|
||||
'subscription_renewal_date' => 'required',
|
||||
'subscription_status' => 'string',
|
||||
'cart_id' => 'exists:carts,id',
|
||||
'item_id' => 'exists:items,id',
|
||||
'patient_id' => 'exists:patients,id',
|
||||
'status' => 'string',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(['errors' => $validator->errors()], 422);
|
||||
}
|
||||
// Update the subscription
|
||||
$subscription->update($dataToUpdate);
|
||||
|
||||
return response()->json(['message' => 'Subscription updated successfully', 'data' => $subscription], 200);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function CreateSubscription(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'add', new Subscription);
|
||||
// Validate the incoming request data
|
||||
$validator = Validator::make($request->all(), [
|
||||
'subscription_start_date' => 'required',
|
||||
'subscription_renewal_date' => 'required',
|
||||
'subscription_status' => 'required',
|
||||
'cart_id' => 'required|exists:carts,id',
|
||||
'item_id' => 'required|exists:items,id',
|
||||
'patient_id' => 'required|exists:patients,id',
|
||||
//'status' => 'required'
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(['errors' => $validator->errors()], 422);
|
||||
}
|
||||
|
||||
// Create the subscription
|
||||
$subscription = Subscription::create($request->all());
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Subscription created successfully',
|
||||
'data' => $subscription
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function getSubscription(Subscription $subscription, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Subscription);
|
||||
return response()->json([
|
||||
'data' => $subscription
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function deleteSubscription(Subscription $subscription, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'delete', new Subscription);
|
||||
$subscription->delete();
|
||||
return response()->json([
|
||||
'status' => 'deleted',
|
||||
'message' => 'subscription deleted'
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
425
app/Http/Controllers/Admin/Api/TelemedProAgentController.php
Normal file
425
app/Http/Controllers/Admin/Api/TelemedProAgentController.php
Normal file
@ -0,0 +1,425 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Api;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Telemedpro;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\Subscription;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Yajra\DataTables\DataTables;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
|
||||
class TelemedProAgentController extends Controller
|
||||
{
|
||||
protected $url;
|
||||
protected $user;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->user = Auth::guard('admin')->user();
|
||||
}
|
||||
public function register(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'add', new Telemedpro);
|
||||
// Validate the request data
|
||||
$validator = Validator::make($request->all(), [
|
||||
'first_name' => ['required', 'string', 'max:255'],
|
||||
'last_name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:telemed_pros'],
|
||||
'password' => ['required', 'string', 'min:8'],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
|
||||
$first_name = $request->input('first_name');
|
||||
$last_name = $request->input('last_name');
|
||||
$email = $request->input('email');
|
||||
$digits = 4;
|
||||
$code = rand(pow(10, $digits - 1), pow(10, $digits) - 1);
|
||||
|
||||
// Prepare data for creating a new Telemedpro user
|
||||
$userData = [
|
||||
'name' => $first_name . " " . $last_name,
|
||||
'first_name' => $first_name,
|
||||
'last_name' => $last_name,
|
||||
'email' => $email,
|
||||
'password' => Hash::make($request->input('password')),
|
||||
'status' => 1,
|
||||
'email_verification' => $code,
|
||||
'home_address' => $request->input('home_address'),
|
||||
'city' => $request->input('city'),
|
||||
'state' => $request->input('state'),
|
||||
'zip_code' => $request->input('zip_code'),
|
||||
'medical_license_number' => json_encode($request->input('medical_license_number')), // Convert to JSON string
|
||||
'years_of_experience' => $request->input('years_of_experience'),
|
||||
'specialty' => $request->input('specialty'),
|
||||
'gender' => $request->input('gender'),
|
||||
'practice_state' => json_encode($request->input('practice_state')), // Convert to JSON string
|
||||
'phone_number' => $request->input('phone'),
|
||||
'availability_from' => $request->input('availabilityFrom'),
|
||||
'availability_to' => $request->input('availabilityTo'),
|
||||
];
|
||||
|
||||
// Create the new user
|
||||
$user = Telemedpro::create($userData);
|
||||
|
||||
// Create an auth token
|
||||
$token = $user->createToken('auth_token')->plainTextToken;
|
||||
|
||||
return response()->json([
|
||||
'user' => $user,
|
||||
'token' => $token,
|
||||
'message' => 'User registered successfully',
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function details($id)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'view', new Telemedpro);
|
||||
return response()->json([
|
||||
'provider' => Telemedpro::find($id)
|
||||
|
||||
], 201);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function telemedProFullDetail(Telemedpro $telemed)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'view', new Telemedpro);
|
||||
$upcomingMeetings = Cart::select(
|
||||
'carts.id as order_id',
|
||||
'appointments.id',
|
||||
'appointments.patient_id',
|
||||
'appointments.appointment_time',
|
||||
'appointments.appointment_date',
|
||||
DB::raw(
|
||||
'CONCAT(patients.first_name, " " , patients.last_name) as patient_name'
|
||||
)
|
||||
)
|
||||
->join('appointments', 'appointments.id', 'carts.appointment_id')
|
||||
->leftJoin('patients', 'patients.id', 'appointments.patient_id')
|
||||
->where("appointments.telemed_pros_id", $telemed->id)
|
||||
->where('appointments.appointment_date', ">=", Carbon::now()->format("Y-m-d"))
|
||||
->get();
|
||||
$completedMeetings = Cart::select(
|
||||
'carts.id as order_id',
|
||||
'appointments.patient_id',
|
||||
'appointments.appointment_time',
|
||||
'appointments.appointment_date',
|
||||
'appointments.start_time',
|
||||
'appointments.end_time',
|
||||
'telemed_pros.name as provider_name',
|
||||
'appointments.telemed_pros_id as provider_id',
|
||||
|
||||
DB::raw(
|
||||
'CONCAT(patients.first_name, " " , patients.last_name) as patient_name'
|
||||
)
|
||||
)
|
||||
->join('appointments', 'appointments.id', 'carts.appointment_id')
|
||||
->leftJoin('patients', 'patients.id', 'appointments.patient_id')
|
||||
->leftJoin('telemed_pros', 'telemed_pros.id', 'appointments.telemed_pros_id')
|
||||
//->leftJoin('carts', 'appointments.id', 'carts.appointment_id')
|
||||
->where("appointments.telemed_pros_id", $telemed->id)
|
||||
->where('appointments.start_time', "!=", null)
|
||||
->where('appointments.end_time', "!=", null)
|
||||
->get();
|
||||
$patientNotes = PatientNote::select(
|
||||
'patient_notes.note',
|
||||
'patient_notes.note_type',
|
||||
'telemed_pros.name as provider_name',
|
||||
'telemed_pros.id as provider_id',
|
||||
'patient_notes.created_at',
|
||||
'carts.id as order_id',
|
||||
'patient_notes.created_by_id',
|
||||
'patient_notes.created_by_type'
|
||||
)
|
||||
->leftJoin('telemed_pros', 'patient_notes.telemed_pros_id', 'telemed_pros.id')
|
||||
->leftJoin('appointments', 'patient_notes.appointment_id', 'appointments.id')
|
||||
->leftJoin('carts', 'appointments.id', 'carts.appointment_id')
|
||||
->where("appointments.telemed_pros_id", $telemed->id)
|
||||
->get();
|
||||
|
||||
foreach ($patientNotes as $notes) {
|
||||
if ($notes->note_type != 'Notes')
|
||||
$notes->note = $this->url->to("assets/files/" . $notes->patient_id . ".png");
|
||||
else
|
||||
$notes->note = $notes->note;
|
||||
}
|
||||
$patientPrescription = PatientPrescription::select(
|
||||
'patient_prescription.*',
|
||||
'telemed_pros.name as provider_name',
|
||||
'prescriptions.*',
|
||||
'carts.id as order_id'
|
||||
)
|
||||
->leftJoin('appointments', 'patient_prescription.appointment_id', 'appointments.id')
|
||||
->leftJoin('carts', 'appointments.id', 'carts.appointment_id')
|
||||
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', 'telemed_pros.id')
|
||||
->leftJoin('prescriptions', 'prescriptions.id', 'patient_prescription.prescription_id')
|
||||
->where('appointments.telemed_pros_id', $telemed->id)->get();
|
||||
return response()->json([
|
||||
'telemed' => $telemed,
|
||||
'upcomingMeetings' => $upcomingMeetings,
|
||||
'completed_meetings' => $completedMeetings,
|
||||
'notes' => $patientNotes,
|
||||
'prescriptions' => $patientPrescription,
|
||||
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function telemedList(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'list', new Telemedpro);
|
||||
// Get filter inputs from the request
|
||||
$practiceState = $request->input('practice_state');
|
||||
$gender = $request->input('gender');
|
||||
$specialty = $request->input('specialty');
|
||||
$state = $request->input('state');
|
||||
$search = $request->input('search');
|
||||
$availabilityFrom = $request->input('availability_from');
|
||||
$availabilityTo = $request->input('availability_to');
|
||||
|
||||
// Build the query with optional filters and join
|
||||
$query = Telemedpro::query()
|
||||
->leftJoin('appointments', 'telemed_pros.id', '=', 'appointments.telemed_pros_id')
|
||||
->leftJoin('carts', 'appointments.id', '=', 'carts.appointment_id')
|
||||
->select(
|
||||
'telemed_pros.id',
|
||||
'telemed_pros.name',
|
||||
'telemed_pros.first_name',
|
||||
'telemed_pros.last_name',
|
||||
'telemed_pros.email',
|
||||
'telemed_pros.is_busy',
|
||||
'telemed_pros.recording_switch',
|
||||
'telemed_pros.ai_switch',
|
||||
'telemed_pros.status',
|
||||
'telemed_pros.practice_state',
|
||||
'telemed_pros.phone_number',
|
||||
'telemed_pros.gender',
|
||||
'telemed_pros.specialty',
|
||||
'telemed_pros.home_address',
|
||||
'telemed_pros.medical_license_number',
|
||||
'telemed_pros.years_of_experience',
|
||||
'telemed_pros.email_verification',
|
||||
'telemed_pros.city',
|
||||
'telemed_pros.state',
|
||||
'telemed_pros.zip_code',
|
||||
'telemed_pros.availability_to',
|
||||
'telemed_pros.availability_from'
|
||||
)
|
||||
->selectRaw('COUNT(DISTINCT carts.id) as meeting_count')
|
||||
->groupBy(
|
||||
'telemed_pros.id',
|
||||
'telemed_pros.name',
|
||||
'telemed_pros.first_name',
|
||||
'telemed_pros.last_name',
|
||||
'telemed_pros.email',
|
||||
'telemed_pros.is_busy',
|
||||
'telemed_pros.recording_switch',
|
||||
'telemed_pros.ai_switch',
|
||||
'telemed_pros.status',
|
||||
'telemed_pros.practice_state',
|
||||
'telemed_pros.phone_number',
|
||||
'telemed_pros.gender',
|
||||
'telemed_pros.specialty',
|
||||
'telemed_pros.home_address',
|
||||
'telemed_pros.medical_license_number',
|
||||
'telemed_pros.years_of_experience',
|
||||
'telemed_pros.email_verification',
|
||||
'telemed_pros.city',
|
||||
'telemed_pros.state',
|
||||
'telemed_pros.zip_code',
|
||||
'telemed_pros.availability_to',
|
||||
'telemed_pros.availability_from'
|
||||
);
|
||||
|
||||
if ($practiceState && $practiceState !== 'All') {
|
||||
$query->where('telemed_pros.practice_state', $practiceState);
|
||||
}
|
||||
if ($gender && $gender !== 'All') {
|
||||
$query->where('telemed_pros.gender', $gender);
|
||||
}
|
||||
if ($specialty && $specialty !== 'All') {
|
||||
$query->where('telemed_pros.specialty', $specialty);
|
||||
}
|
||||
if ($state && $state !== 'All') {
|
||||
$query->where('telemed_pros.state', $state);
|
||||
}
|
||||
if ($availabilityFrom && $availabilityFrom !== 'All') {
|
||||
$query->where('telemed_pros.availability_from', '<=', $availabilityFrom);
|
||||
}
|
||||
if ($availabilityTo && $availabilityTo !== 'All') {
|
||||
$query->where('telemed_pros.availability_to', '>=', $availabilityTo);
|
||||
}
|
||||
return DataTables::of($query)
|
||||
->addColumn('availability_from', function ($telemedpro) {
|
||||
return $telemedpro->availability_from;
|
||||
})
|
||||
->addColumn('availability_to', function ($telemedpro) {
|
||||
return $telemedpro->availability_to;
|
||||
})
|
||||
->addColumn('specialty', function ($telemedpro) {
|
||||
return $telemedpro->specialty;
|
||||
})
|
||||
->addColumn('meeting_count', function ($telemedpro) {
|
||||
return $telemedpro->meeting_count;
|
||||
})
|
||||
->make(true);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function telemed(Telemedpro $telemed)
|
||||
{
|
||||
return response()->json([
|
||||
'patient' => $telemed
|
||||
]);
|
||||
}
|
||||
public function telemedDelete(Telemedpro $telemed)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'delete', new Telemedpro);
|
||||
$telemed->delete();
|
||||
return response()->json([
|
||||
'message' => "Deleted Successfully"
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function telemedUpdate(Telemedpro $telemed, Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'delete', new Subscription);
|
||||
$first_name = $request->input('first_name');
|
||||
$last_name = $request->input('last_name');
|
||||
$email = $request->input('email');
|
||||
|
||||
|
||||
$telemed->name = $first_name . " " . $last_name;
|
||||
$telemed->first_name = $first_name;
|
||||
$telemed->last_name = $last_name;
|
||||
$telemed->email = $email;
|
||||
$telemed->password = Hash::make($request->input('password'));
|
||||
$telemed->status = 1;
|
||||
$telemed->home_address = $request->input('home_address');
|
||||
$telemed->city = $request->input('city');
|
||||
$telemed->state = $request->input('state');
|
||||
$telemed->zip_code = $request->input('zip_code');
|
||||
$telemed->medical_license_number = json_encode($request->input('medical_license_number')); // Convert to JSON string
|
||||
$telemed->years_of_experience = $request->input('years_of_experience');
|
||||
$telemed->specialty = $request->input('specialty');
|
||||
$telemed->gender = $request->input('gender');
|
||||
$telemed->practice_state = json_encode($request->input('practice_state')); // Convert to JSON string
|
||||
$telemed->phone_number = $request->input('phone');
|
||||
$telemed->availability_from = $request->input('availabilityFrom');
|
||||
$telemed->availability_to = $request->input('availabilityTo');
|
||||
$telemed->save();
|
||||
return response()->json([
|
||||
'message' => 'Telemedpro updated successfully',
|
||||
'telemed' => $telemed
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function getMeetingHistoryTelemedpro(Telemedpro $telemedpro, $filter = '12_months')
|
||||
{
|
||||
try {
|
||||
$this->authorizeForUser($this->user, 'meeting_history', new Telemedpro);
|
||||
$currentMonth = Carbon::now();
|
||||
// Filter logic
|
||||
switch ($filter) {
|
||||
case 'current_month':
|
||||
$startDate = $currentMonth->copy()->startOfMonth();
|
||||
break;
|
||||
case '1_month':
|
||||
$startDate = $currentMonth->copy()->subMonth()->startOfMonth();
|
||||
break;
|
||||
case '2_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(2)->startOfMonth();
|
||||
break;
|
||||
case '3_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(3)->startOfMonth();
|
||||
break;
|
||||
case '6_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(6)->startOfMonth();
|
||||
break;
|
||||
default: // Default to 12 months
|
||||
$startDate = $currentMonth->copy()->subMonths(12)->startOfMonth();
|
||||
}
|
||||
$endDate = $currentMonth->endOfMonth();
|
||||
// Fetch patient names and appointment counts directly from the database
|
||||
$monthlyData = Appointment::select(
|
||||
'patient_id',
|
||||
'telemed_pros_id',
|
||||
'appointment_time',
|
||||
'appointment_date',
|
||||
'start_time',
|
||||
'end_time',
|
||||
'duration',
|
||||
'id'
|
||||
)
|
||||
->where("telemed_pros_id", $telemedpro->id)
|
||||
->whereNotNull("end_time")
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
->get();
|
||||
$patients = [];
|
||||
foreach ($monthlyData as $dataPoint) {
|
||||
$patientName = $dataPoint->patient->first_name . " " . $dataPoint->patient->last_name; // Assuming 'name' is the field representing patient names
|
||||
/* $appointmentCount = $dataPoint->appointment_count; */
|
||||
$start_time = $dataPoint->start_time;
|
||||
$end_time = $dataPoint->end_time;
|
||||
$duration = $dataPoint->duration;
|
||||
$appointment_time = $dataPoint->appointment_time;
|
||||
$appointment_date = $dataPoint->appointment_date;
|
||||
$patient_id = $dataPoint->patient_id;
|
||||
$id = $dataPoint->id;
|
||||
|
||||
$patients[] = [
|
||||
'patient_name' => $patientName,
|
||||
'appointment_time' => $appointment_time,
|
||||
'appointment_date' => $appointment_date,
|
||||
/* 'appointment_count' => $appointmentCount, */
|
||||
'start_time' => $start_time,
|
||||
'end_time' => $end_time,
|
||||
'duration' => $duration,
|
||||
'id' => $id,
|
||||
'patient_id' => $patient_id,
|
||||
];
|
||||
}
|
||||
return response()->json([
|
||||
'patients' => $patients,
|
||||
]);
|
||||
} catch (AuthorizationException $e) {
|
||||
return $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Confirm Password Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password confirmations and
|
||||
| uses a simple trait to include the behavior. You're free to explore
|
||||
| this trait and override any functions that require customization.
|
||||
|
|
||||
*/
|
||||
|
||||
use ConfirmsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users when the intended url fails.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
}
|
22
app/Http/Controllers/Admin/Auth/ForgotPasswordController.php
Normal file
22
app/Http/Controllers/Admin/Auth/ForgotPasswordController.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
|
||||
use SendsPasswordResetEmails;
|
||||
}
|
67
app/Http/Controllers/Admin/Auth/LoginController.php
Normal file
67
app/Http/Controllers/Admin/Auth/LoginController.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\admin\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Admin;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles authenticating users for the application and
|
||||
| redirecting them to your home screen. The controller uses a trait
|
||||
| to conveniently provide its functionality to your applications.
|
||||
|
|
||||
*/
|
||||
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/admin';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('admin.auth.login');
|
||||
}
|
||||
|
||||
protected function login(Request $request)
|
||||
{
|
||||
$credentials = $request->only('email', 'password');
|
||||
|
||||
$user = Admin::where($this->username(), $credentials['email'])->first();
|
||||
|
||||
if ($user && Hash::check($credentials['password'], $user->password)) {
|
||||
Auth::guard('admin')->login($user, $request->has('remember'));
|
||||
return redirect($this->redirectTo);
|
||||
}
|
||||
|
||||
return back()->withErrors(['email' => 'Invalid credentials']);
|
||||
}
|
||||
|
||||
public function redirectPath() {
|
||||
return "/admin";
|
||||
}
|
||||
}
|
80
app/Http/Controllers/Admin/Auth/RegisterController.php
Normal file
80
app/Http/Controllers/Admin/Auth/RegisterController.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\admin\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Admin;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles the registration of new users as well as their
|
||||
| validation and creation. By default this controller uses a trait to
|
||||
| provide this functionality without requiring any additional code.
|
||||
|
|
||||
*/
|
||||
|
||||
use RegistersUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after registration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
public function showRegisterForm()
|
||||
{
|
||||
return view('admin.auth.register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\Models\Admin
|
||||
*/
|
||||
protected function register(Request $request)
|
||||
{
|
||||
Admin::create([
|
||||
'name' => $request->input('name'),
|
||||
'email' => $request->input('email'),
|
||||
'password' => bcrypt($request->input('password')),
|
||||
]);
|
||||
return back();
|
||||
}
|
||||
}
|
30
app/Http/Controllers/Admin/Auth/ResetPasswordController.php
Normal file
30
app/Http/Controllers/Admin/Auth/ResetPasswordController.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
}
|
42
app/Http/Controllers/Admin/Auth/VerificationController.php
Normal file
42
app/Http/Controllers/Admin/Auth/VerificationController.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email Verification Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling email verification for any
|
||||
| user that recently registered with the application. Emails may also
|
||||
| be re-sent if the user didn't receive the original email message.
|
||||
|
|
||||
*/
|
||||
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Where to redirect users after verification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
}
|
70
app/Http/Controllers/Admin/DoctorController.php
Normal file
70
app/Http/Controllers/Admin/DoctorController.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Doctor;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class DoctorController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$doctors = Doctor::all();
|
||||
return view('admin.doctors.index', ['doctors' => $doctors]);
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
return view('admin.doctors.add');
|
||||
}
|
||||
|
||||
public function save(Request $request)
|
||||
{
|
||||
$doctor = Doctor::where('email',$request->input('email'))->first();
|
||||
if($doctor)
|
||||
{
|
||||
$request->session()->flash('error', 'The email has already been taken.');
|
||||
return redirect()->back();
|
||||
}
|
||||
Doctor::create([
|
||||
'name' => $request->input('name'),
|
||||
'email' => $request->input('email'),
|
||||
'password' => bcrypt($request->input('password')),
|
||||
]);
|
||||
$request->session()->flash('message', 'Doctor created successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$doctor = Doctor::where('id',$id)->first();
|
||||
return view('admin.doctors.edit', ['doctor' => $doctor]);
|
||||
}
|
||||
|
||||
public function update($id,Request $request)
|
||||
{
|
||||
$doctor = Doctor::where('id',$id)->first();
|
||||
$request->validate([
|
||||
'name' => 'required',
|
||||
'email' => 'required|email|unique:doctors,email,' . $id,
|
||||
// Other validation rules...
|
||||
]);
|
||||
$doctor->name = $request->input('name');
|
||||
$doctor->email = $request->input('email');
|
||||
if($request->input('password'))
|
||||
$doctor->password = $request->input('password');
|
||||
$doctor->save();
|
||||
|
||||
$request->session()->flash('message', 'Doctor updated successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function delete($id,Request $request)
|
||||
{
|
||||
Doctor::where('id',$id)->delete();
|
||||
$request->session()->flash('message', 'Doctor deleted successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
14
app/Http/Controllers/Admin/HomeController.php
Normal file
14
app/Http/Controllers/Admin/HomeController.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('admin.home');
|
||||
}
|
||||
}
|
73
app/Http/Controllers/Admin/LabsController.php
Normal file
73
app/Http/Controllers/Admin/LabsController.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Lab;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class LabsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$labs = Lab::all();
|
||||
return view('admin.labs.index', ['labs' => $labs]);
|
||||
}
|
||||
public function create()
|
||||
{
|
||||
return view('admin.labs.create');
|
||||
}
|
||||
public function save(Request $request)
|
||||
{
|
||||
Lab::create([
|
||||
'name' => $request->name,
|
||||
'address' => $request->address,
|
||||
'city' => $request->city,
|
||||
'state' => $request->state,
|
||||
'zip_code' => $request->zip
|
||||
]);
|
||||
return redirect('admin/labs');
|
||||
}
|
||||
public function edit($id)
|
||||
{
|
||||
$labEdit = Lab::find($id);
|
||||
return view('admin.labs.edit', ['labEdit' => $labEdit]);
|
||||
}
|
||||
public function update($id, Request $request)
|
||||
{
|
||||
$labEdit = Lab::find($id);
|
||||
$labEdit->name = $request->name;
|
||||
$labEdit->address = $request->address;
|
||||
$labEdit->city = $request->city;
|
||||
$labEdit->state = $request->state;
|
||||
$labEdit->zip_code = $request->zip;
|
||||
$labEdit->save();
|
||||
return redirect('admin/labs');
|
||||
}
|
||||
public function getOrderData(Request $request)
|
||||
{
|
||||
$perPage = $request->get('per_page', 20); // Items per page (default 10)
|
||||
|
||||
// Get carts with patient data and order count
|
||||
$carts = Cart::with('patient')
|
||||
->select('patient_id', DB::raw('COUNT(*) as cart_count'))
|
||||
->groupBy('patient_id')
|
||||
->paginate($perPage);
|
||||
|
||||
// Manually create paginator instance (due to aggregation)
|
||||
$paginator = new LengthAwarePaginator(
|
||||
$carts->items(),
|
||||
$carts->total(),
|
||||
$perPage,
|
||||
$carts->currentPage()
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'status' => 'Success',
|
||||
'orderData' => $paginator
|
||||
], 200);
|
||||
}
|
||||
}
|
24
app/Http/Controllers/Admin/PatientController.php
Normal file
24
app/Http/Controllers/Admin/PatientController.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Patient;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class PatientController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$patients = Patient::all();
|
||||
return view('admin.patients.index', ['patients' => $patients]);
|
||||
}
|
||||
|
||||
public function delete($id,Request $request)
|
||||
{
|
||||
Patient::where('id',$id)->delete();
|
||||
$request->session()->flash('message', 'Patient deleted successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
913
app/Http/Controllers/Agent/AppointmentController.php
Normal file
913
app/Http/Controllers/Agent/AppointmentController.php
Normal file
@ -0,0 +1,913 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Agent;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Events\DeviceCurrentStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Doctor;
|
||||
use App\Models\DoctorAppointment;
|
||||
use App\Models\Item;
|
||||
use App\Models\ItemHistory;
|
||||
use App\Models\Lab;
|
||||
use App\Models\LabKit;
|
||||
use App\Models\LicenseNumberModel;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientAnswer;
|
||||
use App\Models\PatientLab;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\PatientTask;
|
||||
use App\Models\Prescription;
|
||||
use App\Models\Question;
|
||||
use App\Models\QuestionBuilder;
|
||||
use App\Models\QuestionGroup;
|
||||
use App\Models\Telemedpro;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Laravel\Prompts\Note;
|
||||
|
||||
class AppointmentController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$user = Auth::user();
|
||||
$data = [];
|
||||
$appointments = Appointment::where('telemed_pros_id', $user->id)->get();
|
||||
foreach ($appointments as $appointment) {
|
||||
$patient = Patient::where('id', $appointment->patient_id)->first();
|
||||
array_push($data, [
|
||||
'id' => $appointment->id,
|
||||
'patient_name' => $patient->first_name . " " . $patient->last_name,
|
||||
'patient_id' => $appointment->patient_id,
|
||||
'telemed_pros_id ' => $appointment->telemed_pros_id,
|
||||
'appointment_time' => $appointment->appointment_time,
|
||||
'meeting_id' => $appointment->meeting_id,
|
||||
'created_at' => $appointment->created_at,
|
||||
'updated_at' => $appointment->updated_at,
|
||||
'in_call' => $appointment->in_call
|
||||
]);
|
||||
}
|
||||
// dd($data);
|
||||
return view('agent.appointments.index', ['appointments' => $data]);
|
||||
}
|
||||
|
||||
public function profile(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
return response()->json(['profile' => $user], 200);
|
||||
}
|
||||
public function profileImageUpload(Patient $patient, Request $request)
|
||||
{
|
||||
$user = $patient;
|
||||
$image = $request->get('image');
|
||||
$fileName = 'profile-' . time();
|
||||
|
||||
$logo = base64_decode($image);
|
||||
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
||||
|
||||
$imageName = $fileName . '.' . $ext;
|
||||
Storage::disk('local')->put("public/profile_pictures/" . $imageName, $logo);
|
||||
$user->profile_picture = $imageName;
|
||||
$user->save();
|
||||
return response()->json(['profile' => $user], 200);
|
||||
}
|
||||
|
||||
public function delete($id, Request $request)
|
||||
{
|
||||
Appointment::where('id', $id)->delete();
|
||||
$request->session()->flash('message', 'Appointment deleted successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function patientDetails($id)
|
||||
{
|
||||
$appointment = Appointment::where('id', $id)->first();
|
||||
$patient = Patient::where('id', $appointment->patient_id)->first();
|
||||
return view('agent.appointments.patient-details', ['patient' => $patient, 'appointment_id' => $appointment->id]);
|
||||
}
|
||||
public function patientProfileDetails(Patient $patient)
|
||||
{
|
||||
return response()->json(['patient' => $patient], 200);
|
||||
}
|
||||
|
||||
|
||||
public function patientAddress($id)
|
||||
{
|
||||
$patient = Patient::where('id', $id)->first();
|
||||
return view('agent.appointments.patient-address', ['patient' => $patient]);
|
||||
}
|
||||
|
||||
public function savePatientAddress($id, Request $request)
|
||||
{
|
||||
$appointment = Appointment::where('id', $id)->first();
|
||||
$patient = Patient::where('id', $appointment->patient_id)->first();
|
||||
|
||||
$address = $request->input('address');
|
||||
$city = $request->input('city');
|
||||
$state = $request->input('state');
|
||||
$zip_code = $request->input('zip_code');
|
||||
|
||||
$patient->address = $address;
|
||||
$patient->city = $city;
|
||||
$patient->state = $state;
|
||||
$patient->zip_code = $zip_code;
|
||||
$patient->save();
|
||||
|
||||
$request->session()->flash('message', 'Address saved successfully');
|
||||
|
||||
|
||||
return view('agent.appointments.patient-details', ['patient' => $patient, 'appointment_id' => $appointment->id]);
|
||||
}
|
||||
|
||||
public function patientLabs($id)
|
||||
{
|
||||
$patient = Patient::where('id', $id)->first();
|
||||
$labs = Lab::where('city', 'like', '%' . $patient->city . '%')
|
||||
->orWhere('state', 'like', '%' . $patient->state . '%')
|
||||
->orWhere('zip_code', 'like', '%' . $patient->zip_code . '%')
|
||||
->get();
|
||||
return view('agent.appointments.patient-labs', ['patient' => $patient, 'labs' => $labs]);
|
||||
}
|
||||
|
||||
public function patientBookLab(Appointment $appointment, Request $request)
|
||||
{
|
||||
|
||||
$lab = new Lab();
|
||||
$lab->address = $request->input('lab_address');
|
||||
$lab->name = $request->input('lab_name');
|
||||
$lab->city = $request->input('lab_city');
|
||||
$lab->state = $request->input('lab_state');
|
||||
$lab->distance = $request->input('lab_distance');
|
||||
$lab->contact_no = $request->input('lab_contact_no');
|
||||
$lab->lang = $request->input('lab_lang');
|
||||
$lab->lat = $request->input('lab_lat');
|
||||
|
||||
$lab->slot_date = $request->input('slot_date');
|
||||
$lab->slot_time = $request->input('slot_time');
|
||||
$lab->booking_time = Carbon::now()->format('Y-m-d H:i:s');
|
||||
|
||||
$lab->appointment_id = $appointment->id;
|
||||
$lab->save();
|
||||
|
||||
return ['message' => 'Lab booked successfully'];
|
||||
}
|
||||
public function patientBookLabGet(Appointment $appointment)
|
||||
{
|
||||
$lab = Lab::where("appointment_id", $appointment->id)->first();
|
||||
return response()->json([
|
||||
'lab_name' => $lab->name,
|
||||
'lab_address' => $lab->address,
|
||||
'lab_city' => $lab->city,
|
||||
'lab_state' => $lab->state,
|
||||
'lab_distance' => $lab->distance,
|
||||
'lab_contact_no' => $lab->contact_no,
|
||||
'lab_lang' => $lab->lang,
|
||||
'lab_lat' => $lab->lat,
|
||||
'slot_date' => $lab->slot_date,
|
||||
'slot_time' => $lab->slot_time,
|
||||
'booking_time' => $lab->booking_time,
|
||||
]);
|
||||
}
|
||||
|
||||
public function doctorAppointment($id)
|
||||
{
|
||||
$appointment = Appointment::where('id', $id)->first();
|
||||
$patient = Patient::where('id', $appointment->patient_id)->first();
|
||||
$doctors = Doctor::all();
|
||||
return view('agent.appointments.doctor-appointment', ['patient' => $patient, 'doctors' => $doctors, 'appointment' => $appointment]);
|
||||
}
|
||||
public function pendingAppointmentDetail()
|
||||
{
|
||||
|
||||
$appointments = Appointment::whereNull('end_time')
|
||||
->where(function ($query) {
|
||||
$startTimeM = Carbon::now()->subHours(12)->format('Y-m-d');
|
||||
$endTimeM = Carbon::now()->addHours(12)->format('Y-m-d');
|
||||
$startTime = Carbon::now()->subHours(12)->format('H:i:s');
|
||||
$endTime = Carbon::now()->addHours(12)->format('H:i:s');
|
||||
$query //->where('appointment_time', '>=', $startTime)
|
||||
//->where('appointment_time', '<=', $endTime)
|
||||
->where('appointment_date', '>=', $startTimeM)
|
||||
->where('appointment_date', '<=', $endTimeM);
|
||||
})
|
||||
->with('patient:id,first_name,last_name,address,city,state,zip_code,country')
|
||||
->get([
|
||||
'id',
|
||||
'patient_id',
|
||||
'appointment_time',
|
||||
'appointment_date',
|
||||
'start_time',
|
||||
'end_time',
|
||||
'duration',
|
||||
'timezone'
|
||||
])
|
||||
->groupBy('patient_id', 'appointment_time', 'appointment_date', 'start_time')
|
||||
->map(function ($group) {
|
||||
$patient = $group->first()->patient;
|
||||
$appointments = $group->sortByDesc('id');
|
||||
$array = [];
|
||||
foreach ($appointments as $appointment) {
|
||||
$filePath = public_path("assets/profiles/{$patient->id}.png");
|
||||
|
||||
if (File::exists($filePath)) {
|
||||
$patient->url = "/assets/profiles/{$patient->id}.png";
|
||||
} else {
|
||||
$patient->url = null;
|
||||
}
|
||||
$cart = Cart::where("appointment_id", $appointment->id)->first();
|
||||
$array[] = [
|
||||
'id' => $patient->id,
|
||||
'patient_timezone' => $patient->timezone,
|
||||
'appointment_timezone' => $appointment->timezone,
|
||||
'name' => $patient->first_name . ' ' . $patient->last_name,
|
||||
'address' => $patient->address,
|
||||
'city' => $patient->city,
|
||||
'state' => $patient->state,
|
||||
'zip_code' => $patient->zip_code,
|
||||
'url' => $patient->url,
|
||||
'country' => $patient->country,
|
||||
'time' => time(),
|
||||
'order_id' => $cart->id ?? "",
|
||||
'appointment' => [
|
||||
'id' => $appointment->id,
|
||||
'appointment_time' => $appointment->appointment_time,
|
||||
'appointment_date' => $appointment->appointment_date,
|
||||
'start_time' => $appointment->start_time,
|
||||
'end_time' => $appointment->end_time,
|
||||
'duration' => $appointment->duration,
|
||||
'timezone' => $appointment->timezone
|
||||
|
||||
]
|
||||
];
|
||||
}
|
||||
return $array;
|
||||
})->flatten(1);
|
||||
|
||||
return response()->json($appointments, 200);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function doctorAppointmentSave($id, Request $request)
|
||||
{
|
||||
$appointment_date = $request->input('appointment_date');
|
||||
$appointment_time = $request->input('appointment_time');
|
||||
$appointment_date = new DateTime($appointment_date);
|
||||
$appointment_date = $appointment_date->format('Y-m-d');
|
||||
$doctor_id = $request->input('doctor_id');
|
||||
|
||||
$appointment = Appointment::where('id', $id)->first();
|
||||
|
||||
$doctorAppointment = DoctorAppointment::where('patient_id', $appointment->patient_id)
|
||||
->where('doctor_id', $doctor_id)
|
||||
->where('appointment_id', $id)
|
||||
->where('appointment_date', $appointment_date)
|
||||
->where('appointment_time', $appointment_time)
|
||||
->first();
|
||||
|
||||
if (empty($doctorAppointment)) {
|
||||
DoctorAppointment::create([
|
||||
'patient_id' => $appointment->patient_id,
|
||||
'doctor_id' => $doctor_id,
|
||||
'appointment_id' => $id,
|
||||
'appointment_date' => $appointment_date,
|
||||
'appointment_time' => $appointment_time
|
||||
]);
|
||||
|
||||
|
||||
return response()->json(['message' => 'Doctor appointment booked'], 200);
|
||||
} else {
|
||||
return response()->json(['message' => 'Error in booking Appointment!'], 200);
|
||||
}
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function patientTasks($id)
|
||||
{
|
||||
$appointment = Appointment::where('id', $id)->first();
|
||||
$patient = Patient::where('id', $appointment->patient_id)->first();
|
||||
$patientTasks = PatientTask::where('patient_id', $appointment->patient_id)->get();
|
||||
return view('agent.appointments.patient-tasks', ['patient' => $patient, 'appointment' => $appointment, 'patientTasks' => $patientTasks]);
|
||||
}
|
||||
|
||||
public function patientTasksSave($id, Request $request)
|
||||
{
|
||||
$description = $request->input('description');
|
||||
|
||||
PatientTask::create([
|
||||
'patient_id' => $id,
|
||||
'description' => $description,
|
||||
]);
|
||||
|
||||
$request->session()->flash('message', 'Task saved successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function patientTaskDelete($id, Request $request)
|
||||
{
|
||||
PatientTask::where('id', $id)->delete();
|
||||
$request->session()->flash('message', 'Task deleted successfully');
|
||||
return redirect()->back();
|
||||
}
|
||||
public function questions()
|
||||
{
|
||||
return 'ddd';
|
||||
}
|
||||
public function questionsList()
|
||||
{
|
||||
$questionsData = [];
|
||||
$groups = QuestionGroup::all();
|
||||
foreach ($groups as $group) {
|
||||
$questions = Question::where('group_id', $group->id)->get()->toArray();
|
||||
$questionsData[$group->title] = $questions;
|
||||
}
|
||||
return response()->json(
|
||||
$questionsData
|
||||
);
|
||||
}
|
||||
public function questionsAnswers($patient_id, $appointment_id)
|
||||
{
|
||||
$questionsData = [];
|
||||
$answers = [];
|
||||
$groups = QuestionGroup::all();
|
||||
foreach ($groups as $group) {
|
||||
$questions = Question::where('group_id', $group->id)->get();
|
||||
foreach ($questions as $question) {
|
||||
|
||||
$answer = PatientAnswer::where('question_id', $question->id)->where('patient_id', $patient_id)->where('appointment_id', $appointment_id)->first();
|
||||
if (isset($answer->answer))
|
||||
$question['answer'] = $answer->answer;
|
||||
else
|
||||
$question['answer'] = null;
|
||||
}
|
||||
$questionsData[$group->title] = $questions;
|
||||
}
|
||||
return response()->json(
|
||||
$questionsData
|
||||
);
|
||||
}
|
||||
|
||||
public function storeAnswers(Patient $patient, Appointment $appointment, Request $request)
|
||||
{
|
||||
|
||||
$data = $request->input("data");
|
||||
|
||||
foreach ($data as $row) {
|
||||
if (isset($row['answer']))
|
||||
PatientAnswer::create([
|
||||
'patient_id' => $patient->id,
|
||||
'appointment_id' => $appointment->id,
|
||||
'question_id' => $row['question_id'],
|
||||
'answer' => $row['answer']
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Answers stored successfully'
|
||||
]);
|
||||
}
|
||||
public function getQuestions(Patient $patient, Appointment $appointment, Request $request)
|
||||
{
|
||||
$questions = PatientAnswer::select('questions.*', 'patient_answers.answer')
|
||||
->leftJoin('questions', 'questions.id', '=', 'patient_answers.question_id')
|
||||
->where('patient_answers.patient_id', $patient->id)
|
||||
->where('patient_answers.appointment_id', $appointment->id)
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'questions' => $questions
|
||||
]);
|
||||
}
|
||||
public function switchButton(Telemedpro $agent, $switch)
|
||||
{
|
||||
if ($switch == 1)
|
||||
$agent->recording_switch = $switch;
|
||||
else
|
||||
$agent->recording_switch = 0;
|
||||
$agent->save();
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Recording Switched: ' . $switch
|
||||
]);
|
||||
}
|
||||
public function switchButtonGet(Telemedpro $agent)
|
||||
{
|
||||
return response()->json([
|
||||
'recording_switch' => $agent->recording_switch,
|
||||
]);
|
||||
}
|
||||
public function switchAiButton(Telemedpro $agent, $switch)
|
||||
{
|
||||
if ($switch == 1)
|
||||
$agent->ai_switch = $switch;
|
||||
else
|
||||
$agent->ai_switch = 0;
|
||||
$agent->save();
|
||||
|
||||
return response()->json([
|
||||
'message' => 'AI Switched: ' . $switch
|
||||
]);
|
||||
}
|
||||
public function switchAiButtonGet(Telemedpro $agent)
|
||||
{
|
||||
return response()->json([
|
||||
'ai_switch' => $agent->ai_switch,
|
||||
]);
|
||||
}
|
||||
public function getProfile(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
return response()->json([
|
||||
'ai_switch' => $user,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function questionsListV1()
|
||||
{
|
||||
$questionGroups = QuestionGroup::with('questions')->get();
|
||||
|
||||
$formattedGroups = [];
|
||||
|
||||
foreach ($questionGroups as $group) {
|
||||
$formattedGroups[$group->title] = [];
|
||||
foreach ($group->questions as $question) {
|
||||
$formattedGroups[$group->title][$question->question] = [$question->type => unserialize($question->options)];
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json($formattedGroups);
|
||||
}
|
||||
public function DeviceCurrentStatus(Request $request)
|
||||
{
|
||||
/* $patient = Patient::where("id", $patient_id)->firstOrFail(); */
|
||||
$micStatus = $request->input('micStatus');
|
||||
$camStatus = $request->input('camStatus');
|
||||
event(new DeviceCurrentStatus($micStatus, $camStatus));
|
||||
|
||||
return true;
|
||||
}
|
||||
public function getAnalytics($filter = '12_months')
|
||||
{
|
||||
$currentMonth = Carbon::now();
|
||||
|
||||
// Filter logic
|
||||
switch ($filter) {
|
||||
case 'current_month':
|
||||
$startDate = $currentMonth->copy()->startOfMonth();
|
||||
break;
|
||||
case '1_month':
|
||||
$startDate = $currentMonth->copy()->subMonth()->startOfMonth();
|
||||
break;
|
||||
case '2_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(2)->startOfMonth();
|
||||
break;
|
||||
case '3_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(3)->startOfMonth();
|
||||
break;
|
||||
case '6_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(6)->startOfMonth();
|
||||
break;
|
||||
default: // Default to 12 months
|
||||
$startDate = $currentMonth->copy()->subMonths(12)->startOfMonth();
|
||||
}
|
||||
|
||||
$endDate = $currentMonth->endOfMonth();
|
||||
|
||||
|
||||
$appointments = Appointment::with('patient')
|
||||
->where("telemed_pros_id", Auth::user()->id)
|
||||
->whereBetween('created_at', [$startDate, $endDate])
|
||||
->get();
|
||||
|
||||
$totalSessions = $appointments->count();
|
||||
$totalCallTime = 10; // Assuming you have some logic to calculate this
|
||||
if ($totalSessions != 0) {
|
||||
$avgSessionTime = $totalCallTime / $totalSessions;
|
||||
$avgSessionTime = round(($avgSessionTime / 60), 2);
|
||||
} else
|
||||
$avgSessionTime = '';
|
||||
|
||||
|
||||
$monthlyData = [];
|
||||
|
||||
// Loop through each month in the last 12 months
|
||||
for ($date = $startDate->copy(); $date->lte($endDate); $date->addMonth()) {
|
||||
$monthStart = $date->startOfMonth()->format('Y-m-d');
|
||||
$monthEnd = $date->copy()->endOfMonth()->format('Y-m-d'); // Key change here!
|
||||
|
||||
$monthAppointments = Appointment::with('patient')
|
||||
->where("telemed_pros_id", Auth::user()->id)
|
||||
->whereBetween('created_at', [$monthStart, $monthEnd])
|
||||
->get();
|
||||
|
||||
|
||||
// Calculate any metrics you need from $monthAppointments
|
||||
$monthlyData[] = [
|
||||
'month' => $date->format('M'), // Example: Jan 2024
|
||||
'appointment_count' => $monthAppointments->count()
|
||||
// Add other metrics as needed
|
||||
];
|
||||
}
|
||||
$monthsList = [];
|
||||
$monthlySessionCount = [];
|
||||
|
||||
foreach ($monthlyData as $dataPoint) {
|
||||
$monthsList[] = $dataPoint['month'];
|
||||
$monthlySessionCount[] = $dataPoint['appointment_count'];
|
||||
}
|
||||
|
||||
|
||||
return response()->json([
|
||||
'total_sessions' => $totalSessions,
|
||||
'total_call_time' => $totalCallTime,
|
||||
'avg_session_time' => $avgSessionTime,
|
||||
'data' => array_values($monthlySessionCount), // Ensure consistent order
|
||||
'months_list' => $monthsList,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMeetingHistory($filter = '12_months')
|
||||
{
|
||||
$currentMonth = Carbon::now();
|
||||
|
||||
// Filter logic
|
||||
switch ($filter) {
|
||||
case 'current_month':
|
||||
$startDate = $currentMonth->copy()->startOfMonth();
|
||||
break;
|
||||
case '1_month':
|
||||
$startDate = $currentMonth->copy()->subMonth()->startOfMonth();
|
||||
break;
|
||||
case '2_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(2)->startOfMonth();
|
||||
break;
|
||||
case '3_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(3)->startOfMonth();
|
||||
break;
|
||||
case '6_months':
|
||||
$startDate = $currentMonth->copy()->subMonths(6)->startOfMonth();
|
||||
break;
|
||||
default: // Default to 12 months
|
||||
$startDate = $currentMonth->copy()->subMonths(12)->startOfMonth();
|
||||
}
|
||||
|
||||
$endDate = $currentMonth->endOfMonth();
|
||||
|
||||
// Fetch patient names and appointment counts directly from the database
|
||||
$monthlyData = Appointment::select(
|
||||
'appointments.patient_id',
|
||||
/* DB::raw('COUNT(*) as appointment_count'), */
|
||||
'appointment_time',
|
||||
'appointment_date',
|
||||
'start_time',
|
||||
'end_time',
|
||||
'duration',
|
||||
'appointments.id as appointment_id',
|
||||
'carts.id as order_id'
|
||||
)
|
||||
->leftJoin('carts', 'carts.appointment_id', 'appointments.id')
|
||||
->where("appointments.telemed_pros_id", Auth::user()->id)
|
||||
->whereBetween('appointments.created_at', [$startDate, $endDate])
|
||||
|
||||
->get();
|
||||
|
||||
$patients = [];
|
||||
|
||||
foreach ($monthlyData as $dataPoint) {
|
||||
$patient = $dataPoint->patient;
|
||||
/* $appointmentCount = $dataPoint->appointment_count; */
|
||||
$start_time = $dataPoint->start_time;
|
||||
$end_time = $dataPoint->end_time;
|
||||
$duration = $dataPoint->duration;
|
||||
$appointment_time = $dataPoint->appointment_time;
|
||||
$appointment_date = $dataPoint->appointment_date;
|
||||
$appointment_id = $dataPoint->appointment_id;
|
||||
$order_id = $dataPoint->order_id;
|
||||
|
||||
$patients[] = [
|
||||
'patient' => $patient,
|
||||
'appointment_time' => $appointment_time,
|
||||
'appointment_date' => $appointment_date,
|
||||
/* 'appointment_count' => $appointmentCount, */
|
||||
'start_time' => $start_time,
|
||||
'end_time' => $end_time,
|
||||
'duration' => $duration,
|
||||
'appointment_id' => $appointment_id,
|
||||
'order_id' => $order_id
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'patients' => $patients,
|
||||
]);
|
||||
}
|
||||
public function sessionHistory(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
// Assuming user can be either telemedPro or patient
|
||||
$history = Appointment::select(
|
||||
'appointments.*',
|
||||
'appointments.patient_id',
|
||||
'patients.first_name as patient_name',
|
||||
'carts.id as order_id'
|
||||
)
|
||||
->leftJoin('patients', 'appointments.patient_id', '=', 'patients.id')
|
||||
->leftJoin('carts', 'carts.appointment_id', '=', 'appointments.id')
|
||||
->where(function ($query) use ($user) {
|
||||
$query->where('appointments.telemed_pros_id', $user->id);
|
||||
})
|
||||
->whereNotNull("appointments.end_time")
|
||||
->orderBy('appointments.appointment_date', 'desc')
|
||||
->get();
|
||||
|
||||
return response()->json(['history' => $history]);
|
||||
|
||||
return response()->json(['history' => $history]);
|
||||
}
|
||||
public function getAppointmentByid($patient, $appointment, Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
// Assuming user can be either telemedPro or patient
|
||||
$data = Appointment::select(
|
||||
'appointments.*',
|
||||
'telemed_pros.name as agent_name',
|
||||
)
|
||||
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', '=', 'telemed_pros.id')
|
||||
->where('appointments.telemed_pros_id', $user->id)
|
||||
->where('appointments.patient_id', $patient)
|
||||
->where('appointments.id', $appointment)
|
||||
->first();
|
||||
$order = Cart::where('appointment_id', $data->id)->first();
|
||||
$orderItems = Item::leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->where('cart_id', $order->id)->get();
|
||||
$data->order = $order;
|
||||
$data->telemedPro;
|
||||
// $data->order_items = $orderItems;
|
||||
$totalPrice = 0;
|
||||
$total_products = 0;
|
||||
$quantity = [];
|
||||
$totalShippingCost = 0;
|
||||
$data->order_notes = PatientNote::where('appointment_id', $appointment)->get();
|
||||
foreach ($orderItems as $item) {
|
||||
$totalShippingCost += $item->shipping_cost;
|
||||
$item->total_price = $item->quantity * $item->price;
|
||||
$totalPrice += $item->total_price;
|
||||
$order->order_total_amount = $totalPrice;
|
||||
$order->order_total_shipping = $totalShippingCost;
|
||||
$item->plansV1->qty = $item->quantity;
|
||||
}
|
||||
$data->order_items = $orderItems;
|
||||
|
||||
$data->shipping_activity = ItemHistory::where('cart_id', $order->id)->get();
|
||||
return response()->json(['data' => $data]);
|
||||
}
|
||||
public function addNotePatient(Patient $patient, Appointment $appointment, Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$addNotePatient = PatientNote::create([
|
||||
'note' => $request->input('note'),
|
||||
'note_type' => $request->input('note_type'),
|
||||
'patient_id' => $patient->id,
|
||||
'appointment_id' => $appointment->id,
|
||||
'telemed_pros_id' => $user->id
|
||||
]);
|
||||
$addNotePatient->file_url = "";
|
||||
if ($request->hasFile('file')) {
|
||||
$file = $request->file('file');
|
||||
|
||||
$filename = $addNotePatient->id . '.' . $file->getClientOriginalExtension();
|
||||
|
||||
$file->move(public_path('assets/files'), $filename);
|
||||
|
||||
$addNotePatient->file_url = "assets/files" . $addNotePatient->id . '.' . $file->getClientOriginalExtension();
|
||||
}
|
||||
$patient = $addNotePatient->patient;
|
||||
$setting = Setting::find(1);
|
||||
Mail::send('emails.noteAdded', ['patient' => $patient, 'agent' => $user, 'setting' => $setting], function ($message) use ($patient, $user) {
|
||||
$message->to($patient->email, $patient->first_name)
|
||||
->subject('You Have a New Note from ' . $user->name);
|
||||
});
|
||||
return response()->json([
|
||||
'message' => 'Note created',
|
||||
'data' => $addNotePatient
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function getNotePatient(Patient $patient, Appointment $appointment, Request $request)
|
||||
{
|
||||
$patientNotes = PatientNote::where("patient_id", $patient->id)
|
||||
->where("appointment_id", $appointment->id)
|
||||
->with('appointment')
|
||||
->get();
|
||||
|
||||
$data = $patientNotes->map(function ($patientNote) {
|
||||
$fileUrl = "/assets/files/{$patientNote->id}.png";
|
||||
$filePath = public_path($fileUrl);
|
||||
|
||||
if (File::exists($filePath)) {
|
||||
$fileUrl = "/assets/files/{$patientNote->id}.png";
|
||||
} else {
|
||||
$fileUrl = null;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $patientNote->id,
|
||||
'note' => $patientNote->note,
|
||||
'note_type' => $patientNote->note_type,
|
||||
'created_at' => $patientNote->created_at,
|
||||
'patient_id' => $patientNote->patient_id,
|
||||
'appointment' => $patientNote->appointment,
|
||||
'telemedPro' => $patientNote->telemedPro,
|
||||
'file_url' => $fileUrl,
|
||||
'telemedPro' => $patientNote->appointment?->telemedPro
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Patient notes retrieved',
|
||||
'data' => $data
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function getQuestionBuilderStore(Patient $patient, Request $request)
|
||||
{
|
||||
|
||||
$questionBuilder = QuestionBuilder::select('key', 'value')->where("customer_id", $patient->id)->get();
|
||||
$jsonData = $questionBuilder->mapWithKeys(function ($item) {
|
||||
return [$item->key => $item->value];
|
||||
});
|
||||
// Store data
|
||||
return response()->json([
|
||||
'message' => 'Data Sent',
|
||||
'data' => $jsonData
|
||||
], 200);
|
||||
}
|
||||
public function getPrescription()
|
||||
{
|
||||
$prescriptions = Prescription::all();
|
||||
return response()->json($prescriptions);
|
||||
}
|
||||
public function storePrescription(Request $request)
|
||||
{
|
||||
$prescription = Prescription::create($request->all());
|
||||
return response()->json($prescription, 200);
|
||||
}
|
||||
public function storePatientPrescription(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$prescription = PatientPrescription::create($request->all());
|
||||
$prescription->status = "pending";
|
||||
$prescription->save();
|
||||
$patient = $prescription->patient;
|
||||
$setting = Setting::find(1);
|
||||
Mail::send('emails.prescriptionAdd', ['patient' => $patient, 'prescription' => $prescription, 'setting' => $setting], function ($message) use ($patient, $user) {
|
||||
$message->to($patient->email, $patient->first_name)
|
||||
->subject('New Prescription Details from ' . $user->name);
|
||||
});
|
||||
return response()->json($prescription, 200);
|
||||
}
|
||||
public function updateStatusPrescription($patient_prescription_id, Request $request)
|
||||
{
|
||||
$status = $request->input("status");
|
||||
$prescription = PatientPrescription::find($patient_prescription_id);
|
||||
$prescription->status = $status;
|
||||
$prescription->save();
|
||||
$patient = $prescription->patient;
|
||||
$setting = Setting::find(1);
|
||||
Mail::send('emails.prescriptionUpdated', ['patient' => $patient, 'setting' => $setting], function ($message) use ($patient) {
|
||||
$message->to($patient->email, $patient->first_name)
|
||||
->subject('Prescription updated.');
|
||||
});
|
||||
return response()->json($prescription, 200);
|
||||
}
|
||||
|
||||
public function getStatusPrescription($patient_prescription_id)
|
||||
{
|
||||
$prescription = PatientPrescription::find($patient_prescription_id);
|
||||
return response()->json($prescription, 200);
|
||||
}
|
||||
public function getPatientPrescription($patient_id, $appointment_id)
|
||||
{
|
||||
$patientPrescription = PatientPrescription::with('prescription')
|
||||
->where('patient_id', $patient_id)
|
||||
->where('appointment_id', $appointment_id)
|
||||
->get();
|
||||
|
||||
$prescriptionData = [];
|
||||
foreach ($patientPrescription as $prescription) {
|
||||
$prescriptionData[] = [
|
||||
'patient' => $prescription->patient,
|
||||
'prescription' => $prescription->prescription,
|
||||
'created_at' => $prescription->created_at,
|
||||
'updated_at' => $prescription->updated_at,
|
||||
'direction_one' => $prescription->direction_one,
|
||||
'direction_two' => $prescription->direction_two,
|
||||
'dont_substitute' => $prescription->dont_substitute,
|
||||
'comments' => $prescription->comments,
|
||||
'appointment_id' => $prescription->appointment_id,
|
||||
'status' => $prescription->status,
|
||||
'appointment' => $prescription->appointment,
|
||||
'telemedPro' => $prescription->appointment->telemedPro,
|
||||
'licenseNumber' => LicenseNumberModel::where("provider_id", $patient_id)->orderBy('id', 'DESC')->first()
|
||||
];
|
||||
}
|
||||
if (!$patientPrescription->isEmpty()) {
|
||||
return response()->json($prescriptionData);
|
||||
} else {
|
||||
return response()->json(['message' => 'Prescription not found'], 404);
|
||||
}
|
||||
}
|
||||
public function getOrderData(Cart $cart, Request $request)
|
||||
{
|
||||
$cart = Cart::with("patient")->get();
|
||||
return response()->json(['cart' => $cart], 200);
|
||||
}
|
||||
|
||||
public function getLabKit(Cart $cart, Request $request)
|
||||
{
|
||||
$kit = LabKit::all();
|
||||
return response()->json(['kit' => $kit], 200);
|
||||
}
|
||||
|
||||
public function orderLabKit(LabKit $labkit, Patient $patient, Request $request)
|
||||
{
|
||||
|
||||
|
||||
$user = $patient;
|
||||
$cart = new Cart();
|
||||
$cart->lab_kit_id = $labkit->id;
|
||||
$cart->first_name = $patient->first_name;
|
||||
$cart->last_name = $patient->last_name;
|
||||
$cart->email = $patient->email;
|
||||
$cart->phone = $patient->phone_no;
|
||||
$cart->status = "pending";
|
||||
|
||||
$cart->date_of_birth = $patient->dob ?? null;
|
||||
|
||||
$cart->patient_id = $user->id;
|
||||
|
||||
$cart->shipping_address1 = $patient->address;
|
||||
$cart->shipping_city = $patient->city;
|
||||
$cart->shipping_state = $patient->state;
|
||||
$cart->shipping_zipcode = $patient->zip_code;
|
||||
$cart->shipping_country = $patient->country;
|
||||
|
||||
|
||||
$cart->shipping_amount = $labkit->amount;
|
||||
$cart->total_amount = $labkit->amount;
|
||||
|
||||
$cart->save();
|
||||
return response()->json(['status' => 'Success', 'cart' => $cart], 200);
|
||||
}
|
||||
|
||||
public function getorderedLabKit(LabKit $labkit, Patient $patient, Request $request)
|
||||
{
|
||||
$detail = Cart::select("carts.*", "lab_kit.name")->leftJoin("lab_kit", "carts.lab_kit_id", "=", "lab_kit.id")
|
||||
->where("carts.lab_kit_id", $labkit->id)
|
||||
->where("carts.patient_id", $patient->id)
|
||||
->get();
|
||||
|
||||
return response()->json(['order' => $detail], 200);
|
||||
}
|
||||
public function getorderedLabKitBasedOnPatient(Patient $patient, Request $request)
|
||||
{
|
||||
$detail = Cart::select("carts.*", "lab_kit.name")->leftJoin("lab_kit", "carts.lab_kit_id", "=", "lab_kit.id")
|
||||
->where("carts.patient_id", $patient->id)
|
||||
->get();
|
||||
|
||||
return response()->json(['order' => $detail], 200);
|
||||
}
|
||||
public function updateStatusOrderData(Cart $cart, Request $request)
|
||||
{
|
||||
|
||||
$cart = Cart::where("id", $cart->id)->firstOrFail();
|
||||
$cart->status = $request->input("status");
|
||||
$cart->save();
|
||||
|
||||
return response()->json(['status' => 'Success', 'cart' => $cart], 200);
|
||||
}
|
||||
public function PatientAppointment()
|
||||
{
|
||||
$user = Auth::user();
|
||||
$data = [];
|
||||
$appointments = Appointment::select('patient_id')->where('telemed_pros_id', $user->id)->groupBy('patient_id')->get();
|
||||
foreach ($appointments as $appointment) {
|
||||
$patient = Patient::where('id', $appointment->patient_id)->first();
|
||||
array_push($data, $patient->toArray());
|
||||
}
|
||||
return response()->json(['status' => 'Success', 'patient' => $data], 200);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Confirm Password Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password confirmations and
|
||||
| uses a simple trait to include the behavior. You're free to explore
|
||||
| this trait and override any functions that require customization.
|
||||
|
|
||||
*/
|
||||
|
||||
use ConfirmsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users when the intended url fails.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
}
|
22
app/Http/Controllers/Agent/Auth/ForgotPasswordController.php
Normal file
22
app/Http/Controllers/Agent/Auth/ForgotPasswordController.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
|
||||
use SendsPasswordResetEmails;
|
||||
}
|
104
app/Http/Controllers/Agent/Auth/LoginController.php
Normal file
104
app/Http/Controllers/Agent/Auth/LoginController.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Agent\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Telemedpro;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles authenticating users for the application and
|
||||
| redirecting them to your home screen. The controller uses a trait
|
||||
| to conveniently provide its functionality to your applications.
|
||||
|
|
||||
*/
|
||||
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/agent';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('agent.auth.login');
|
||||
}
|
||||
|
||||
protected function login(Request $request)
|
||||
{
|
||||
$credentials = $request->only('email', 'password');
|
||||
|
||||
$user = Telemedpro::where($this->username(), $credentials['email'])->first();
|
||||
|
||||
if ($user && Hash::check($credentials['password'], $user->password)) {
|
||||
// Auth::guard('agent')->login($user, $request->has('remember'));
|
||||
if ($this->guard('agent')->attempt(
|
||||
$this->credentials($request),
|
||||
$request->has('remember')
|
||||
)) {
|
||||
// dd($this->guard());
|
||||
return redirect($this->redirectTo);
|
||||
}
|
||||
dd($this->guard());
|
||||
// dd($user && Hash::check($credentials['password'], $user->password));
|
||||
return redirect($this->redirectTo);
|
||||
}
|
||||
|
||||
return back()->withErrors(['email' => 'Invalid credentials']);
|
||||
}
|
||||
|
||||
public function redirectPath()
|
||||
{
|
||||
return "/agent";
|
||||
}
|
||||
public function loginAgent(Request $request)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'email' => 'required|email',
|
||||
'password' => 'required'
|
||||
]);
|
||||
|
||||
$patient = Telemedpro::where('email', $validatedData['email'])->first();
|
||||
|
||||
if (!$patient || !Hash::check($validatedData['password'], $patient->password)) {
|
||||
return response()->json([
|
||||
'message' => 'Invalid credentials'
|
||||
], 422);
|
||||
}
|
||||
if (!$patient || $patient->status == 0) {
|
||||
return response()->json([
|
||||
'message' => 'Your account is undergoing verification.'
|
||||
], 422);
|
||||
}
|
||||
$token = $patient->createToken('auth_token')->plainTextToken;
|
||||
|
||||
return response()->json([
|
||||
'data' => $patient,
|
||||
'access_token' => $token,
|
||||
'token_type' => 'Bearer',
|
||||
]);
|
||||
}
|
||||
}
|
80
app/Http/Controllers/Agent/Auth/RegisterController.php
Normal file
80
app/Http/Controllers/Agent/Auth/RegisterController.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Agent\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Telemedpro;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles the registration of new users as well as their
|
||||
| validation and creation. By default this controller uses a trait to
|
||||
| provide this functionality without requiring any additional code.
|
||||
|
|
||||
*/
|
||||
|
||||
use RegistersUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after registration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
public function showRegisterForm()
|
||||
{
|
||||
return view('agent.auth.register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\Models\Telemedpro
|
||||
*/
|
||||
protected function register(Request $request)
|
||||
{
|
||||
Telemedpro::create([
|
||||
'name' => $request->input('name'),
|
||||
'email' => $request->input('email'),
|
||||
'password' => bcrypt($request->input('password')),
|
||||
]);
|
||||
return back();
|
||||
}
|
||||
}
|
30
app/Http/Controllers/Agent/Auth/ResetPasswordController.php
Normal file
30
app/Http/Controllers/Agent/Auth/ResetPasswordController.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
}
|
42
app/Http/Controllers/Agent/Auth/VerificationController.php
Normal file
42
app/Http/Controllers/Agent/Auth/VerificationController.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email Verification Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling email verification for any
|
||||
| user that recently registered with the application. Emails may also
|
||||
| be re-sent if the user didn't receive the original email message.
|
||||
|
|
||||
*/
|
||||
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Where to redirect users after verification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
}
|
204
app/Http/Controllers/Agent/DashboardController.php
Normal file
204
app/Http/Controllers/Agent/DashboardController.php
Normal file
@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Agent;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\DoctorAppointment;
|
||||
use App\Models\Telemedpro;
|
||||
use App\Models\LicenseNumberModel;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
protected $user_id;
|
||||
protected $url;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
// $this->middleware('auth');
|
||||
// if (isset(Auth::guard('agent')->user()->id))
|
||||
// $this->user_id = Auth::guard('agent')->user()->id;
|
||||
$this->url = $url;
|
||||
}
|
||||
public function index()
|
||||
{
|
||||
return view('agent.dashboard');
|
||||
}
|
||||
public function register(Request $request)
|
||||
{
|
||||
// Validate the request data
|
||||
$validator = Validator::make($request->all(), [
|
||||
'first_name' => ['required', 'string', 'max:255'],
|
||||
'last_name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8'],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
$first_name = $request->input('first_name');
|
||||
$last_name = $request->input('last_name');
|
||||
$email = $request->input('email');
|
||||
$digits = 4;
|
||||
$code = rand(pow(10, $digits - 1), pow(10, $digits) - 1);
|
||||
// Create the new user
|
||||
$setting = Setting::find(1);
|
||||
Mail::send('emails.providerVerificationEmail', ['name' => $first_name . " " . $last_name, "code" => $code, 'setting' => $setting], function ($message) use ($first_name, $last_name, $email) {
|
||||
$message->to($email, $first_name . " " . $last_name)
|
||||
->subject('Verify Your Email ');
|
||||
});
|
||||
$user = Telemedpro::create([
|
||||
'name' => $first_name . " " . $last_name,
|
||||
'first_name' => $request->input('first_name'),
|
||||
'last_name' => $request->input('last_name'),
|
||||
'email' => $request->input('email'),
|
||||
'password' => Hash::make($request->input('password')),
|
||||
'status' => 0,
|
||||
"email_verification" => $code
|
||||
]);
|
||||
$token = $user->createToken('auth_token')->plainTextToken;
|
||||
return response()->json([
|
||||
'user' => $user,
|
||||
'message' => 'User registered successfully',
|
||||
], 201);
|
||||
}
|
||||
|
||||
public function emailVerify($id, Request $request)
|
||||
{
|
||||
|
||||
$providerData = Telemedpro::where('email_verification', $request->get('token'))->where('id', $id)->first();
|
||||
|
||||
if ($providerData) {
|
||||
$providerData->email_verification = '';
|
||||
$providerData->email_verified_at = Carbon::now()->format('Y-m-d H:i:s');
|
||||
$providerData->save();
|
||||
return response()->json([
|
||||
'message' => 'Account verified',
|
||||
]);
|
||||
} else {
|
||||
return response()->json([
|
||||
'message' => 'already verified',
|
||||
], 422);
|
||||
}
|
||||
}
|
||||
public function saveProfile($id, Request $request)
|
||||
{
|
||||
$providerData = Telemedpro::find($id);
|
||||
if (!$providerData) {
|
||||
return response()->json([
|
||||
'message' => 'Provider not found',
|
||||
], 404);
|
||||
}
|
||||
$providerData->practice_state = $request->input('practice_state');
|
||||
$providerData->phone_number = $request->input('phone');
|
||||
$providerData->gender = $request->input('gender');
|
||||
$providerData->specialty = $request->input('specialty');
|
||||
$availabilityFrom = $request->input('availabilityFrom');
|
||||
if ($availabilityFrom && Carbon::hasFormat($availabilityFrom, 'H:i')) {
|
||||
$providerData->availability_from = Carbon::createFromFormat('H:i', $availabilityFrom)->format('H:i:s');
|
||||
} else {
|
||||
return response()->json([
|
||||
'message' => 'Invalid format for availability_from',
|
||||
], 400);
|
||||
}
|
||||
|
||||
// Validate and format availability_to
|
||||
$availability_to = $request->input('availabilityTo');
|
||||
if ($availability_to && Carbon::hasFormat($availability_to, 'H:i')) {
|
||||
$providerData->availability_to = Carbon::createFromFormat('H:i', $availability_to)->format('H:i:s');
|
||||
} else {
|
||||
return response()->json([
|
||||
'message' => 'Invalid format for availability_to',
|
||||
], 400);
|
||||
}
|
||||
$providerData->home_address = $request->input('home_address');
|
||||
$providerData->medical_license_number = $request->input('medical_license_number');
|
||||
$providerData->years_of_experience = $request->input('years_of_experience');
|
||||
$providerData->city = $request->input('city');
|
||||
$providerData->state = $request->input('state');
|
||||
$providerData->zip_code = $request->input('zip_code');
|
||||
$providerData->save();
|
||||
$this->saveLicenseNumber($id, $request->input('medical_license_number'));
|
||||
return response()->json([
|
||||
'user' => $providerData,
|
||||
'message' => 'Data saved ',
|
||||
], 201);
|
||||
}
|
||||
public function saveLicenseNumber($id, $licences)
|
||||
{
|
||||
foreach ($licences as $key => $value) {
|
||||
LicenseNumberModel::create([
|
||||
"provider_id" => $id,
|
||||
"state" => $key,
|
||||
"license_number" => $value,
|
||||
"status" => 1
|
||||
]);
|
||||
}
|
||||
}
|
||||
public function resendCode($id)
|
||||
{
|
||||
$digits = 4;
|
||||
$code = rand(pow(10, $digits - 1), pow(10, $digits) - 1);
|
||||
$providerData = Telemedpro::find($id);
|
||||
$providerData->email_verification = $code; //update code in database
|
||||
$email = $providerData->email;
|
||||
$first_name = $providerData->first_name;
|
||||
$last_name = $providerData->last_time;
|
||||
$setting = Setting::find(1);
|
||||
Mail::send('emails.providerVerificationEmail', ['name' => $first_name . " " . $last_name, "code" => $code, 'setting' => $setting], function ($message) use ($first_name, $last_name, $email) {
|
||||
$message->to($email, $first_name . " " . $last_name)
|
||||
->subject('Verify Your Email ');
|
||||
});
|
||||
$providerData->save();
|
||||
return response()->json([
|
||||
'message' => 'Verification code sent! ',
|
||||
], 201);
|
||||
}
|
||||
public function getProviderMeetings()
|
||||
{
|
||||
$appointments = Appointment::select(
|
||||
"patients.profile_picture",
|
||||
"patients.first_name",
|
||||
"patients.last_name",
|
||||
"appointments.id as appointment_id",
|
||||
"appointments.start_time",
|
||||
"appointments.end_time",
|
||||
"appointments.timezone",
|
||||
"appointments.duration",
|
||||
"appointments.appointment_date",
|
||||
"appointments.appointment_time",
|
||||
"appointments.status as appointment_status",
|
||||
"appointments.patient_name",
|
||||
"carts.id as order_id",
|
||||
"appointments.id as appointment_id",
|
||||
"appointments.patient_id"
|
||||
)
|
||||
->leftJoin("patients", "patients.id", "appointments.patient_id")
|
||||
->leftJoin("carts", "carts.appointment_id", "appointments.id")
|
||||
->where('telemed_pros_id', Auth::guard('agent')->user()->id)
|
||||
->where('start_time', "!=", null)
|
||||
->where('end_time', "!=", null)
|
||||
->orderBy('appointments.created_at', 'desc')
|
||||
->get();
|
||||
|
||||
foreach ($appointments as $appointment) {
|
||||
if ($appointment->profile_picture)
|
||||
$appointment->profile_picture = $this->url->to("storage/profile_pictures/", $appointment->profile_picture);
|
||||
else
|
||||
$appointment->profile_picture = asset('img/avatars/1.png');
|
||||
}
|
||||
|
||||
return response()->json($appointments, 200);
|
||||
}
|
||||
}
|
14
app/Http/Controllers/Agent/HomeController.php
Normal file
14
app/Http/Controllers/Agent/HomeController.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Agent;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('agent.home');
|
||||
}
|
||||
}
|
423
app/Http/Controllers/Agent/MeetingController.php
Normal file
423
app/Http/Controllers/Agent/MeetingController.php
Normal file
@ -0,0 +1,423 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Agent;
|
||||
|
||||
use Agence104\LiveKit\AccessToken;
|
||||
use Agence104\LiveKit\AccessTokenOptions;
|
||||
use Agence104\LiveKit\EgressServiceClient;
|
||||
use Agence104\LiveKit\RoomCreateOptions;
|
||||
use Agence104\LiveKit\RoomServiceClient;
|
||||
use Agence104\LiveKit\VideoGrant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\JassJWT;
|
||||
use App\Events\AppointmentCallEnded;
|
||||
use App\Events\AppointmentCreated;
|
||||
use App\Events\DeviceCurrentStatus;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Doctor;
|
||||
use App\Models\DoctorAppointment;
|
||||
use App\Models\Lab;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\Telemedpro;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Error;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Livekit\EncodedFileOutput;
|
||||
use Livekit\EncodedFileType;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class MeetingController extends Controller
|
||||
{
|
||||
public function getAsseblyAiToekn()
|
||||
{
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => '0014470a9fa14b598a73cc0133acca8c',
|
||||
])->post('https://api.assemblyai.com/v2/realtime/token', [
|
||||
'expires_in' => 1600
|
||||
]);
|
||||
|
||||
return $response->body();
|
||||
}
|
||||
public function show($meeting_id)
|
||||
{
|
||||
return view('agent.jetsi', compact('meeting_id'));
|
||||
}
|
||||
public function joinMeeting($meeting_id)
|
||||
{
|
||||
$jassToken = JassJWT::generate();
|
||||
$appoinement = Appointment::where("meeting_id", $meeting_id)->firstOrFail();
|
||||
|
||||
return view('agent.join-meeting', compact('meeting_id'), compact('jassToken'));
|
||||
}
|
||||
public function startCall($patient_id, $agent_id, $appointment_id, Request $request)
|
||||
{
|
||||
$call_type = $request->input('call_type');
|
||||
$telemed_pro = Telemedpro::where("id", $agent_id)->firstOrFail();
|
||||
$appointment = Appointment::find($appointment_id);
|
||||
$appointment->in_call = 1;
|
||||
$appointment->start_time = Carbon::now()->format('Y-m-d H:i:s');
|
||||
$appointment_booking_tokens = $this->bookAppointmentApi($appointment, $telemed_pro);
|
||||
$appointment->agent_call_token = $appointment_booking_tokens['tokenAgent'];
|
||||
$appointment->patient_call_token = $appointment_booking_tokens['tokenPatient'];
|
||||
$appointment->telemed_pros_id = $agent_id;
|
||||
$appointment->save();
|
||||
|
||||
event(new AppointmentCreated($patient_id, $appointment->id, $appointment->patient_call_token, $call_type));
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Appointment created!',
|
||||
'appointment_id' => $appointment->id,
|
||||
'meeting_id' => $appointment->agent_call_token,
|
||||
'call_type' => $call_type
|
||||
], 200);
|
||||
}
|
||||
|
||||
|
||||
public function startRecording(Appointment $appointment)
|
||||
{
|
||||
$telemed = Telemedpro::find($appointment->telemed_pros_id);
|
||||
if ($telemed->recording_switch == 0) {
|
||||
return response()->json([
|
||||
'message' => "Recording Off",
|
||||
'Response' => 'Error',
|
||||
], 200);
|
||||
}
|
||||
$roomName = 'appointment-' . $appointment->id;
|
||||
$video_token = md5(rand(100000000, 999999999) . rand(1, 9));
|
||||
$appointment->video_token = $video_token;
|
||||
$appointment->save();
|
||||
|
||||
$client = new EgressServiceClient("https://plugnmeet.codelfi.com", config('app.LK_API_KEY'), config('app.LK_API_SECRET'));
|
||||
try {
|
||||
$info = $client->startRoomCompositeEgress($roomName, 'speaker', new EncodedFileOutput([
|
||||
"filepath" => "/out/recordings/" . $video_token . ".mp4",
|
||||
"file_type" => EncodedFileType::MP4,
|
||||
]));
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'message' => $e->getMessage(),
|
||||
'Response' => 'Error',
|
||||
], 200);
|
||||
}
|
||||
return response()->json([
|
||||
'message' => "Success",
|
||||
'Response' => 'Success',
|
||||
], 200);
|
||||
}
|
||||
public function bookAppointmentApi($appointment, $availableTelemedPros)
|
||||
{
|
||||
$roomName = 'appointment-' . $appointment->id . "-" . uniqid();
|
||||
$opts = (new RoomCreateOptions())
|
||||
->setName($roomName)
|
||||
->setEmptyTimeout(30)
|
||||
->setMaxParticipants(5);
|
||||
$host = "https://plugnmeet.codelfi.com";
|
||||
$svc = new RoomServiceClient($host, config('app.LK_API_KEY'), config('app.LK_API_SECRET'));
|
||||
try {
|
||||
$svc->deleteRoom($roomName);
|
||||
} catch (Exception | Error $e) {
|
||||
}
|
||||
|
||||
$room = $svc->createRoom($opts);
|
||||
|
||||
$participantPatientName = "patient-" . uniqid() . $appointment->patient->first_name . " " . $appointment->patient->last_name;
|
||||
|
||||
$tokenOptionsPatient = (new AccessTokenOptions())
|
||||
->setIdentity($participantPatientName);
|
||||
$videoGrantPatient = (new VideoGrant())
|
||||
->setRoomJoin()
|
||||
->setRoomName($roomName);
|
||||
$tokenPatient = (new AccessToken(config('app.LK_API_KEY'), config('app.LK_API_SECRET')))
|
||||
->init($tokenOptionsPatient)
|
||||
->setGrant($videoGrantPatient)
|
||||
->toJwt();
|
||||
|
||||
$participantAgentName = "agent-" . uniqid() . $availableTelemedPros->name;
|
||||
$tokenOptionsAgent = (new AccessTokenOptions())
|
||||
->setIdentity($participantAgentName);
|
||||
$videoGrantAgent = (new VideoGrant())
|
||||
->setRoomJoin()
|
||||
->setRoomName($roomName);
|
||||
$tokenAgent = (new AccessToken(config('app.LK_API_KEY'), config('app.LK_API_SECRET')))
|
||||
->init($tokenOptionsAgent)
|
||||
->setGrant($videoGrantAgent)
|
||||
->toJwt();
|
||||
return [
|
||||
'tokenPatient' => $tokenPatient,
|
||||
'tokenAgent' => $tokenAgent,
|
||||
];
|
||||
}
|
||||
public function endCall($patient_id, $appointment_id)
|
||||
{
|
||||
$appointment = Appointment::find($appointment_id);
|
||||
$appointment->in_call = 0;
|
||||
$appointment->end_time = Carbon::now()->format('Y-m-d H:i:s');
|
||||
$appointment->save();
|
||||
|
||||
event(new AppointmentCallEnded($patient_id, $appointment->id));
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Call ended',
|
||||
'appointment_id' => $appointment->id,
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function searchLabsByAddress(Request $request)
|
||||
{
|
||||
$address = $request->input('address');
|
||||
|
||||
try {
|
||||
$labs = Lab::where('address', 'like', '%' . $address . '%')
|
||||
->orWhere('city', 'like', '%' . $address . '%')
|
||||
->orWhere('state', 'like', '%' . $address . '%')
|
||||
->orWhere('zip_code', 'like', '%' . $address . '%')
|
||||
->get(['id', 'name', 'city', 'state', 'zip_code', 'lang', 'lat']);
|
||||
|
||||
return response()->json($labs, 200);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => 'Failed to search labs'], 500);
|
||||
}
|
||||
}
|
||||
public function bookAppointment(Request $request)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'telemed_pros_id' => 'required|exists:telemed_pros,id',
|
||||
'patient_id' => 'required|exists:patients,id',
|
||||
'doctor_id' => 'required|exists:doctors,id',
|
||||
'appointment_id' => 'required',
|
||||
'appointment_time' => 'required|date_format:Y-m-d H:i:s',
|
||||
]);
|
||||
|
||||
$appointment = DoctorAppointment::create($validatedData);
|
||||
|
||||
|
||||
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Appointment booked successfully',
|
||||
'meeting_id' => $appointment->meeting_id,
|
||||
'appointment_time' => $validatedData['appointment_time']
|
||||
]);
|
||||
}
|
||||
public function updateInfo(Request $request, $patientId)
|
||||
{
|
||||
try {
|
||||
$patient = Patient::find($patientId);
|
||||
$patient->update($request->only(['city', 'state', 'address', 'zip_code', 'dob', 'country']));
|
||||
$patient->save();
|
||||
|
||||
return response()->json(['message' => 'Patient address updated successfully'], 200);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => $e->getMessage()], 400);
|
||||
}
|
||||
}
|
||||
public function getInfo(Request $request, $patientId)
|
||||
{
|
||||
try {
|
||||
$patient = Patient::find($patientId)->makeHidden(['password', 'remember_token']);
|
||||
if ($patient->dob) {
|
||||
$birthDate = new DateTime($patient->dob);
|
||||
$today = new DateTime(date('Y-m-d'));
|
||||
$age = $today->diff($birthDate)->y;
|
||||
$patient->age = $age;
|
||||
} else {
|
||||
$patient->age = 0;
|
||||
}
|
||||
|
||||
return response()->json($patient);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['error' => $e->getMessage()], 400);
|
||||
}
|
||||
}
|
||||
public function getDoctorList()
|
||||
{
|
||||
try {
|
||||
// Fetch only the necessary columns for efficiency
|
||||
$doctors = Doctor::select('id', 'name', 'designation')->get()->makeHidden(['password', 'remember_token']);
|
||||
|
||||
// Return a successful JSON response with the doctors
|
||||
return response()->json($doctors, 200);
|
||||
} catch (\Exception $e) {
|
||||
// Handle exceptions gracefully
|
||||
return response()->json(['error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
public function getAppointmentList()
|
||||
{
|
||||
try {
|
||||
$appointments = Appointment::select("patients.first_name", "patients.last_name", "telemed_pros.name as agent_name", "appointments.*") // Eager load the associated telemed pro
|
||||
->leftJoin("telemed_pros", "telemed_pros.id", "appointments.telemed_pros_id")
|
||||
->leftJoin("patients", "patients.id", "appointments.patient_id")
|
||||
/* ->orderBy('appointment_time', 'desc') */ // Optional: sort by appointment time
|
||||
->get();
|
||||
|
||||
return response()->json($appointments, 200);
|
||||
} catch (\Exception $e) {
|
||||
|
||||
return response()->json(['error' => 'Failed to retrieve appointments'], 500);
|
||||
}
|
||||
}
|
||||
public function getDoctorAppointmentList()
|
||||
{
|
||||
try {
|
||||
$appointments = DoctorAppointment::select("patients.first_name", "patients.last_name", "doctor_appointments.*") // Eager load the associated telemed pro
|
||||
->leftJoin("patients", "patients.id", "doctor_appointments.patient_id")
|
||||
->orderBy('doctor_appointments.created_at', 'desc') // Optional: sort by appointment time
|
||||
->get();
|
||||
|
||||
return response()->json($appointments, 200);
|
||||
} catch (\Exception $e) {
|
||||
|
||||
return response()->json(['error' => 'Failed to retrieve appointments'], 500);
|
||||
}
|
||||
}
|
||||
public function availableSlots($date)
|
||||
{
|
||||
// Ensure date is in a valid format
|
||||
$date = Carbon::parse($date);
|
||||
|
||||
// Generate all possible 30-minute slots between 9 AM and 4 PM
|
||||
$slots = collect();
|
||||
$startTime = Carbon::parse($date)->setTime(9, 0, 0);
|
||||
$endTime = Carbon::parse($date)->setTime(16, 0, 0);
|
||||
while ($startTime < $endTime) {
|
||||
$slots->push($startTime->format('Y-m-d H:i:s'));
|
||||
$startTime->addMinutes(30);
|
||||
}
|
||||
// Filter out booked slots
|
||||
$bookedAppointments = Appointment::where('appointment_date', '>=', $date->format('Y-m-d'))
|
||||
->where('appointment_date', '<', $date->addDay()->format('Y-m-d'))
|
||||
->pluck('appointment_date');
|
||||
$availableSlots = $slots->diff($bookedAppointments);
|
||||
|
||||
$formattedSlots = $availableSlots->map(function ($slot) {
|
||||
|
||||
$start = Carbon::parse($slot);
|
||||
|
||||
// Add AM/PM
|
||||
$startTime = $start->format('g:i A');
|
||||
|
||||
$end = (clone $start)->addMinutes(29);
|
||||
|
||||
// Add AM/PM
|
||||
$endTime = $end->format('g:i A');
|
||||
|
||||
return $startTime /* . ' - ' . $endTime */;
|
||||
});
|
||||
|
||||
// Additional checking if slot is booked
|
||||
$formattedSlots = $formattedSlots->filter(function ($slot) {
|
||||
|
||||
$startTime = Carbon::parse($slot);
|
||||
/*$startTime = Carbon::parse(explode(' - ', $slot)[0]);
|
||||
$endTime = Carbon::parse(explode(' - ', $slot)[1]); */
|
||||
|
||||
//return !Appointment::whereBetween('appointment_time', [$startTime/* , $endTime */])->exists();
|
||||
return !Appointment::where('appointment_time', $startTime)->exists();
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'available_slots' => $formattedSlots->toArray()
|
||||
]);
|
||||
}
|
||||
public function appointmentDetail(Appointment $appointment)
|
||||
{
|
||||
$patient = Patient::find($appointment->patient_id);
|
||||
$telemedPro = Telemedpro::find($appointment->telemed_pros_id);
|
||||
$doctor_appointment = DoctorAppointment::select("id", "appointment_date", "appointment_time", "appointment_id")->where('appointment_id', $appointment->id)->first();
|
||||
if (!$doctor_appointment)
|
||||
$doctor_appointment = [];
|
||||
else
|
||||
$doctor_appointment = $doctor_appointment->toArray();
|
||||
|
||||
if ($patient) {
|
||||
if ($patient->dob) {
|
||||
$birthDate = new DateTime($patient->dob);
|
||||
$today = new DateTime(date('Y-m-d'));
|
||||
$age = $today->diff($birthDate)->y;
|
||||
$patient->age = $age;
|
||||
} else {
|
||||
$patient->age = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'patient' => $patient->toArray() ?? [],
|
||||
'telemedPro' => $telemedPro->toArray() ?? [],
|
||||
'doctor_appointment' => $doctor_appointment ?? [],
|
||||
'agent_appointment' => $appointment,
|
||||
'video_url' => "https://plugnmeet.codelfi.com/recordings/" . $appointment->video_token . ".mp4",
|
||||
]);
|
||||
}
|
||||
public function labDetail(Appointment $appointment)
|
||||
{
|
||||
$lab = Lab::where("appointment_id", $appointment->id)->first();
|
||||
return response()->json([
|
||||
'lab_name' => $lab->name,
|
||||
'lab_address' => $lab->address,
|
||||
'lab_city' => $lab->city,
|
||||
'lab_state' => $lab->state,
|
||||
'lab_distance' => $lab->distance,
|
||||
'lab_contact_no' => $lab->contact_no,
|
||||
'lab_lang' => $lab->lang,
|
||||
'lab_lat' => $lab->lat,
|
||||
'slot_date' => $lab->slot_date,
|
||||
'slot_time' => $lab->slot_time,
|
||||
'booking_time' => $lab->booking_time,
|
||||
]);
|
||||
}
|
||||
public function getRoomList()
|
||||
{
|
||||
$svc = new RoomServiceClient("https://plugnmeet.codelfi.com", config('app.LK_API_KEY'), config('app.LK_API_SECRET'));
|
||||
|
||||
// List rooms.
|
||||
$rooms = $svc->listRooms();
|
||||
|
||||
dd($rooms);
|
||||
}
|
||||
|
||||
public function addNotePatient(Request $request)
|
||||
{
|
||||
// Validation (adjust as needed)
|
||||
|
||||
$patient = Auth::guard('patient')->user();
|
||||
|
||||
$addNotePatient = PatientNote::create([
|
||||
'note' => $request->input('note'),
|
||||
'note_type' => $request->input('note_type'),
|
||||
'patient_id' => $patient->id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Note created',
|
||||
'data' => $addNotePatient
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function getNotePatient(Request $request)
|
||||
{
|
||||
// Validation (adjust as needed)
|
||||
|
||||
$patient = Auth::guard('patient')->user();
|
||||
|
||||
$addNotePatient = PatientNote::where("patient_id", $patient->id)->get();
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Note created',
|
||||
'data' => $addNotePatient
|
||||
], 200);
|
||||
}
|
||||
public function markAppointmentsStatus($id)
|
||||
{
|
||||
$appointment = Appointment::find($id);
|
||||
$appointment->status = 'completed';
|
||||
$appointment->save();
|
||||
return response()->json([
|
||||
'message' => 'status updated !'
|
||||
], 200);
|
||||
}
|
||||
}
|
195
app/Http/Controllers/Agent/OrderController.php
Normal file
195
app/Http/Controllers/Agent/OrderController.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Agent;
|
||||
|
||||
use Agence104\LiveKit\AccessToken;
|
||||
use Agence104\LiveKit\AccessTokenOptions;
|
||||
use Agence104\LiveKit\EgressServiceClient;
|
||||
use Agence104\LiveKit\RoomCreateOptions;
|
||||
use Agence104\LiveKit\RoomServiceClient;
|
||||
use Agence104\LiveKit\VideoGrant;
|
||||
use App\Classes\Constant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\JassJWT;
|
||||
use App\Events\AppointmentCallEnded;
|
||||
use App\Events\AppointmentCreated;
|
||||
use App\Events\DeviceCurrentStatus;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Doctor;
|
||||
use App\Models\DoctorAppointment;
|
||||
use App\Models\Item;
|
||||
use App\Models\ItemHistory;
|
||||
use App\Models\Lab;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\Telemedpro;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Error;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Livekit\EncodedFileOutput;
|
||||
use Livekit\EncodedFileType;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
|
||||
class OrderController extends Controller
|
||||
{
|
||||
protected $user_id;
|
||||
protected $url;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->user_id = Auth::guard('agent')->user()->id;
|
||||
$this->url = $url;
|
||||
}
|
||||
public function orderList(Request $request)
|
||||
{
|
||||
|
||||
$fromDate = $request->get('from_date');
|
||||
$toDate = $request->get('to_date');
|
||||
$orderList = Cart::select("appointments.*", 'appointments.id as appointment_id', 'carts.*', 'carts.id as order_id')->leftJoin('appointments', 'appointments.id', 'carts.appointment_id')
|
||||
->where('appointments.telemed_pros_id', $this->user_id);
|
||||
if ($fromDate != "") {
|
||||
$from_date = Carbon::createFromFormat('m-d-Y', $fromDate)->format('Y-m-d');
|
||||
$orderList->where('created_at', ">=", $from_date . " 00:00:00");
|
||||
}
|
||||
if ($toDate != "") {
|
||||
$to_date = Carbon::createFromFormat('m-d-Y', $toDate)->format('Y-m-d');
|
||||
$orderList->where('created_at', "<=", $to_date . " 23:59:59");
|
||||
}
|
||||
|
||||
$orderListData = $orderList->get();
|
||||
$totalPrice = 0;
|
||||
$totalShippingCost = 0;
|
||||
foreach ($orderListData as $order) {
|
||||
$order->order_id = $order->id;
|
||||
$totalPrice = 0;
|
||||
$total_products = 0;
|
||||
$quantity = [];
|
||||
$totalShippingCost = 0;
|
||||
$order->order_total_amount = $totalPrice;
|
||||
$order->order_total_shipping = $totalShippingCost;
|
||||
$items = Item::leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id')
|
||||
->where('cart_id', $order->id)
|
||||
->get();
|
||||
$appointment = Appointment::where('id', $order->appointment_id)->first();
|
||||
|
||||
$order->appointment_status = $appointment->status;
|
||||
|
||||
|
||||
|
||||
$orderItems = [];
|
||||
foreach ($items as $item) {
|
||||
array_push($orderItems, $item->plansV1);
|
||||
$totalShippingCost += $item->shipping_cost;
|
||||
$item->total_price = $item->quantity * $item->price;
|
||||
$totalPrice += $item->total_price;
|
||||
$order->order_total_amount = $totalPrice;
|
||||
$order->order_total_shipping = $totalShippingCost;
|
||||
$item->plansV1->qty = $item->quantity;
|
||||
$item->plansV1->status = $item->status;
|
||||
}
|
||||
|
||||
$order->total_items = $total_products;
|
||||
$order->order_items = $orderItems;
|
||||
}
|
||||
return response()
|
||||
->json([
|
||||
'order_data' => $orderListData
|
||||
]);
|
||||
}
|
||||
public function orderDetails($id)
|
||||
{
|
||||
$orderItems = $this->getOrderItems($id);
|
||||
|
||||
$orderDetails = Cart::find($id);
|
||||
$items = Item::where('cart_id', $orderDetails->id)->get();
|
||||
|
||||
|
||||
$appointments = Appointment::select(
|
||||
'appointments.*',
|
||||
'telemed_pros.name as provider_name',
|
||||
'telemed_pros.email as provider_email',
|
||||
'telemed_pros.phone_number as provider_phone'
|
||||
)
|
||||
->leftJoin('telemed_pros', 'telemed_pros.id', 'appointments.telemed_pros_id')
|
||||
->where('appointments.id', $orderDetails->appointment_id)
|
||||
->first();
|
||||
$prescription = PatientPrescription::select(
|
||||
'patient_prescription.direction_quantity',
|
||||
'patient_prescription.refill_quantity',
|
||||
'patient_prescription.dosage',
|
||||
'patient_prescription.status',
|
||||
'patient_prescription.direction_one',
|
||||
'patient_prescription.direction_two',
|
||||
'patient_prescription.dont_substitute',
|
||||
'patient_prescription.comments',
|
||||
'patient_prescription.brand',
|
||||
'patient_prescription.from',
|
||||
'patient_prescription.quantity',
|
||||
'patient_prescription.created_at as prescription_date',
|
||||
'prescriptions.name as prescription_name',
|
||||
'patient_prescription.prescription_id',
|
||||
'telemed_pros.name as provide_name',
|
||||
'telemed_pros.id as provider_id'
|
||||
)
|
||||
->where("appointment_id", $orderDetails->appointment_id)
|
||||
->leftJoin('appointments', 'appointments.id', 'patient_prescription.appointment_id')
|
||||
->leftJoin('prescriptions', 'prescriptions.id', 'patient_prescription.prescription_id')
|
||||
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', 'telemed_pros.id')
|
||||
->get();
|
||||
$patientNotes = PatientNote::where("appointment_id", $orderDetails->appointment_id)->get();
|
||||
$appointments->provider_id = $appointments->telemed_pros_id;
|
||||
$patient = $orderDetails->patient;
|
||||
$patient->profile_picture = $this->url->to("storage/profile_pictures/" . $patient->profile_picture);
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'order_details' => $orderDetails,
|
||||
'order_items' => $orderItems,
|
||||
'patient_details' => $patient,
|
||||
'appointment_details' => $appointments,
|
||||
'items_activity' => $this->getShippingActivity($id),
|
||||
'appointment_notes' => $patientNotes,
|
||||
'prescription' => $prescription
|
||||
]);
|
||||
}
|
||||
public function getOrderItems($id)
|
||||
{
|
||||
$items = Item::leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id')
|
||||
->where('cart_id', $id)
|
||||
->get();
|
||||
$totalPrice = 0;
|
||||
$totalShippingCost = 0;
|
||||
$total_products = 0;
|
||||
foreach ($items as $item) {
|
||||
|
||||
$totalShippingCost += $item->shipping_cost;
|
||||
$item->total_price = $item->quantity * $item->price;
|
||||
$totalPrice += $item->total_price;
|
||||
$total_products += $item->quantity;
|
||||
$item->image_url = $this->url->to("product/" . $item->image_url);
|
||||
}
|
||||
|
||||
return [
|
||||
'items' => $items,
|
||||
'total_amount' => $totalPrice,
|
||||
'total_shipping_cost' => $totalShippingCost,
|
||||
'total_products' => $total_products,
|
||||
'total' => $totalPrice + $totalShippingCost
|
||||
];
|
||||
}
|
||||
public function getShippingActivity($id)
|
||||
{
|
||||
$itemsHistory = ItemHistory::select('items_history.*', 'plans_v1.title as item_name')
|
||||
->where('items_history.cart_id', $id)
|
||||
->leftJoin('items', 'items.id', 'items_history.item_id')
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->get();
|
||||
return $itemsHistory;
|
||||
}
|
||||
}
|
183
app/Http/Controllers/Agent/PatientProfileController.php
Normal file
183
app/Http/Controllers/Agent/PatientProfileController.php
Normal file
@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Agent;
|
||||
|
||||
use Agence104\LiveKit\AccessToken;
|
||||
use Agence104\LiveKit\AccessTokenOptions;
|
||||
use Agence104\LiveKit\EgressServiceClient;
|
||||
use Agence104\LiveKit\RoomCreateOptions;
|
||||
use Agence104\LiveKit\RoomServiceClient;
|
||||
use Agence104\LiveKit\VideoGrant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\JassJWT;
|
||||
use App\Events\AppointmentCallEnded;
|
||||
use App\Events\AppointmentCreated;
|
||||
use App\Events\DeviceCurrentStatus;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Doctor;
|
||||
use App\Models\DoctorAppointment;
|
||||
use App\Models\Item;
|
||||
use App\Models\ItemHistory;
|
||||
use App\Models\Lab;
|
||||
use App\Models\LabKit;
|
||||
use App\Models\LabkitOrderItem;
|
||||
use App\Models\Patient;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\Telemedpro;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Error;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Livekit\EncodedFileOutput;
|
||||
use Livekit\EncodedFileType;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class PatientProfileController extends Controller
|
||||
{
|
||||
protected $user_id;
|
||||
protected $url;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->user_id = Auth::guard('agent')->user()->id;
|
||||
$this->url = $url;
|
||||
}
|
||||
public function index($id)
|
||||
{
|
||||
$patient = Patient::where('id', $id)->first();
|
||||
if ($patient->profile_picture)
|
||||
$patient->profile_picture = $this->url->to("storage/profile_pictures/", $patient->profile_picture);
|
||||
else
|
||||
$patient->profile_picture = asset('img/avatars/1.png');;
|
||||
|
||||
$notes = PatientNote::select(
|
||||
'patient_notes.note',
|
||||
'telemed_pros.name as provider_name',
|
||||
'patient_notes.appointment_id',
|
||||
'patient_notes.created_at as note_date'
|
||||
)
|
||||
->leftJoin('telemed_pros', 'telemed_pros.id', 'patient_notes.telemed_pros_id')
|
||||
->where('patient_id', $id)->get();
|
||||
$prescriptions = PatientPrescription::select(
|
||||
'appointments.appointment_date',
|
||||
'appointments.appointment_time',
|
||||
'appointments.timezone',
|
||||
'appointments.start_time',
|
||||
'patient_prescription.direction_quantity',
|
||||
'patient_prescription.refill_quantity',
|
||||
'patient_prescription.dosage',
|
||||
'patient_prescription.status',
|
||||
'patient_prescription.direction_one',
|
||||
'patient_prescription.direction_two',
|
||||
'patient_prescription.dont_substitute',
|
||||
'patient_prescription.comments',
|
||||
'patient_prescription.brand',
|
||||
'patient_prescription.from',
|
||||
'patient_prescription.quantity',
|
||||
'patient_prescription.created_at as prescription_date',
|
||||
'telemed_pros.name',
|
||||
'telemed_pros.email as provider_email',
|
||||
'telemed_pros.gender as provider_gender',
|
||||
'telemed_pros.specialty as provider_specialty',
|
||||
'telemed_pros.years_of_experience',
|
||||
'prescriptions.name as prescription_name',
|
||||
'carts.id as order_id',
|
||||
// 'prescriptions.price as prescription_price',
|
||||
// 'prescriptions.shipping_cost as prescription_shipping_cost',
|
||||
'patient_prescription.prescription_id'
|
||||
)
|
||||
->leftJoin('appointments', 'appointments.id', 'patient_prescription.appointment_id')
|
||||
->leftJoin('carts', 'carts.appointment_id', '=', 'appointments.id')
|
||||
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', 'telemed_pros.id')
|
||||
->leftJoin('prescriptions', 'prescriptions.id', 'patient_prescription.prescription_id')
|
||||
->where('patient_prescription.patient_id', $id)->get();
|
||||
return response()->json(
|
||||
[
|
||||
'notes_history' => $notes,
|
||||
'prescriptions' => $prescriptions,
|
||||
'patient_details' => $patient
|
||||
],
|
||||
200
|
||||
);
|
||||
}
|
||||
public function labkitOrderItemStore(Request $request)
|
||||
{
|
||||
// Validate the request data
|
||||
$validator = Validator::make($request->all(), [
|
||||
'cart_id' => 'required|exists:carts,id',
|
||||
'item_id' => 'required|exists:items,id',
|
||||
'lab_kit_id' => 'required|exists:lab_kit,id',
|
||||
|
||||
/* 'result' => 'nullable|string', */
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'errors' => $validator->errors(),
|
||||
], 422);
|
||||
}
|
||||
|
||||
// Create a new LabkitOrderItem
|
||||
$labkitOrderItem = LabkitOrderItem::create([
|
||||
'cart_id' => $request['cart_id'],
|
||||
'item_id' => $request['item_id'],
|
||||
'lab_kit_id' => $request['lab_kit_id'],
|
||||
/* 'result' => $request['result'], */
|
||||
'status' => "Ordered",
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Order detail stored successfully',
|
||||
'data' => $labkitOrderItem,
|
||||
], 201);
|
||||
}
|
||||
public function labkitOrderItemGet(Request $request)
|
||||
{
|
||||
$labkitOrderItems = LabkitOrderItem::where('labkit_order_items.cart_id', $request->input('cart_id'))
|
||||
->leftJoin(
|
||||
'lab_kit',
|
||||
'labkit_order_items.lab_kit_id',
|
||||
'=',
|
||||
'lab_kit.id'
|
||||
)
|
||||
->leftJoin(
|
||||
'items',
|
||||
'items.id',
|
||||
'labkit_order_items.item_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'plans_v1',
|
||||
'plans_v1.id',
|
||||
'items.plans_id'
|
||||
)
|
||||
->select(
|
||||
'labkit_order_items.id',
|
||||
'labkit_order_items.status',
|
||||
'labkit_order_items.result',
|
||||
'lab_kit.name as lab_kit_name',
|
||||
'plans_v1.title as item_name'
|
||||
)
|
||||
->get();
|
||||
foreach ($labkitOrderItems as $labKit) {
|
||||
|
||||
if ($labKit->result != "")
|
||||
$labKit->result = $this->url->to('storage/lab_results/' . $labKit->result);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'data' => $labkitOrderItems,
|
||||
]);
|
||||
}
|
||||
public function getLabKit(Cart $cart, Request $request)
|
||||
{
|
||||
$kit = LabKit::all();
|
||||
return response()->json(['kit' => $kit], 200);
|
||||
}
|
||||
}
|
40
app/Http/Controllers/Auth/ConfirmPasswordController.php
Normal file
40
app/Http/Controllers/Auth/ConfirmPasswordController.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Confirm Password Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password confirmations and
|
||||
| uses a simple trait to include the behavior. You're free to explore
|
||||
| this trait and override any functions that require customization.
|
||||
|
|
||||
*/
|
||||
|
||||
use ConfirmsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users when the intended url fails.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
}
|
87
app/Http/Controllers/Auth/ForgotPasswordController.php
Normal file
87
app/Http/Controllers/Auth/ForgotPasswordController.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\PasswordResetTokens;
|
||||
use App\Models\Patient;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
|
||||
use SendsPasswordResetEmails;
|
||||
public function forgotPassword(Request $request)
|
||||
{
|
||||
|
||||
|
||||
$patient = Patient::where('email', $request->email)->first();
|
||||
|
||||
if (!$patient) {
|
||||
return response()->json(['message' => 'The specified email cannot be located.'], 404);
|
||||
}
|
||||
$token = base64_encode(Str::random(60));
|
||||
$tokenData = PasswordResetTokens::where('email', $request->email)->first();
|
||||
if ($tokenData) {
|
||||
PasswordResetTokens::where('email', $request->email)->delete();
|
||||
}
|
||||
PasswordResetTokens::create([
|
||||
'email' => $request->email,
|
||||
'token' => $token,
|
||||
'created_at' => now()
|
||||
]);
|
||||
|
||||
// Send reset link email
|
||||
Mail::send('emails.password_reset', ['token' => $token], function ($message) use ($request) {
|
||||
$message->to($request->email);
|
||||
$message->subject('Password Reset Request');
|
||||
});
|
||||
|
||||
return response()->json(['message' => 'Password reset link sent']);
|
||||
}
|
||||
|
||||
public function resetPassword(Request $request)
|
||||
{
|
||||
|
||||
$tokenData = PasswordResetTokens::where('token', $request->token)->first();
|
||||
|
||||
if (!$tokenData || !$request->token == $tokenData->token) {
|
||||
return response()->json([
|
||||
'msg' => "Link Expired",
|
||||
'status' => 'error'
|
||||
]);
|
||||
}
|
||||
|
||||
$password = $request->get('password');
|
||||
$confPassword = $request->get('confirm');
|
||||
if ($confPassword != $password) {
|
||||
return response()->json([
|
||||
'msg' => "Password don no match",
|
||||
'status' => 'error'
|
||||
]);
|
||||
}
|
||||
|
||||
$user = Patient::where('email', $tokenData->email)->first();
|
||||
$user->password = bcrypt($password);
|
||||
$user->save();
|
||||
PasswordResetTokens::where('token', $request->token)->delete();
|
||||
return response()->json([
|
||||
'msg' => "Password updated"
|
||||
]);
|
||||
}
|
||||
}
|
40
app/Http/Controllers/Auth/LoginController.php
Normal file
40
app/Http/Controllers/Auth/LoginController.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles authenticating users for the application and
|
||||
| redirecting them to your home screen. The controller uses a trait
|
||||
| to conveniently provide its functionality to your applications.
|
||||
|
|
||||
*/
|
||||
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
}
|
73
app/Http/Controllers/Auth/RegisterController.php
Normal file
73
app/Http/Controllers/Auth/RegisterController.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles the registration of new users as well as their
|
||||
| validation and creation. By default this controller uses a trait to
|
||||
| provide this functionality without requiring any additional code.
|
||||
|
|
||||
*/
|
||||
|
||||
use RegistersUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after registration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\Models\User
|
||||
*/
|
||||
protected function create(array $data)
|
||||
{
|
||||
return User::create([
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'password' => Hash::make($data['password']),
|
||||
]);
|
||||
}
|
||||
}
|
30
app/Http/Controllers/Auth/ResetPasswordController.php
Normal file
30
app/Http/Controllers/Auth/ResetPasswordController.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
}
|
42
app/Http/Controllers/Auth/VerificationController.php
Normal file
42
app/Http/Controllers/Auth/VerificationController.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email Verification Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling email verification for any
|
||||
| user that recently registered with the application. Emails may also
|
||||
| be re-sent if the user didn't receive the original email message.
|
||||
|
|
||||
*/
|
||||
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Where to redirect users after verification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
}
|
12
app/Http/Controllers/Controller.php
Normal file
12
app/Http/Controllers/Controller.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, ValidatesRequests;
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Confirm Password Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password confirmations and
|
||||
| uses a simple trait to include the behavior. You're free to explore
|
||||
| this trait and override any functions that require customization.
|
||||
|
|
||||
*/
|
||||
|
||||
use ConfirmsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users when the intended url fails.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
|
||||
class ForgotPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset emails and
|
||||
| includes a trait which assists in sending these notifications from
|
||||
| your application to your users. Feel free to explore this trait.
|
||||
|
|
||||
*/
|
||||
|
||||
use SendsPasswordResetEmails;
|
||||
}
|
67
app/Http/Controllers/Doctor/Auth/LoginController.php
Normal file
67
app/Http/Controllers/Doctor/Auth/LoginController.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\doctor\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Doctor;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles authenticating users for the application and
|
||||
| redirecting them to your home screen. The controller uses a trait
|
||||
| to conveniently provide its functionality to your applications.
|
||||
|
|
||||
*/
|
||||
|
||||
use AuthenticatesUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/doctor';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('doctor.auth.login');
|
||||
}
|
||||
|
||||
protected function login(Request $request)
|
||||
{
|
||||
$credentials = $request->only('email', 'password');
|
||||
|
||||
$user = Doctor::where($this->username(), $credentials['email'])->first();
|
||||
|
||||
if ($user && Hash::check($credentials['password'], $user->password)) {
|
||||
Auth::guard('doctor')->login($user, $request->has('remember'));
|
||||
return redirect($this->redirectTo);
|
||||
}
|
||||
|
||||
return back()->withErrors(['email' => 'Invalid credentials']);
|
||||
}
|
||||
|
||||
public function redirectPath() {
|
||||
return "/doctor";
|
||||
}
|
||||
}
|
80
app/Http/Controllers/Doctor/Auth/RegisterController.php
Normal file
80
app/Http/Controllers/Doctor/Auth/RegisterController.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\doctor\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Doctor;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles the registration of new users as well as their
|
||||
| validation and creation. By default this controller uses a trait to
|
||||
| provide this functionality without requiring any additional code.
|
||||
|
|
||||
*/
|
||||
|
||||
use RegistersUsers;
|
||||
|
||||
/**
|
||||
* Where to redirect users after registration.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
public function showRegisterForm()
|
||||
{
|
||||
return view('doctor.auth.register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\Models\Doctor
|
||||
*/
|
||||
protected function register(Request $request)
|
||||
{
|
||||
Doctor::create([
|
||||
'name' => $request->input('name'),
|
||||
'email' => $request->input('email'),
|
||||
'password' => bcrypt($request->input('password')),
|
||||
]);
|
||||
return back();
|
||||
}
|
||||
}
|
30
app/Http/Controllers/Doctor/Auth/ResetPasswordController.php
Normal file
30
app/Http/Controllers/Doctor/Auth/ResetPasswordController.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Where to redirect users after resetting their password.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
}
|
42
app/Http/Controllers/Doctor/Auth/VerificationController.php
Normal file
42
app/Http/Controllers/Doctor/Auth/VerificationController.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
|
||||
class VerificationController extends Controller
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Email Verification Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling email verification for any
|
||||
| user that recently registered with the application. Emails may also
|
||||
| be re-sent if the user didn't receive the original email message.
|
||||
|
|
||||
*/
|
||||
|
||||
use VerifiesEmails;
|
||||
|
||||
/**
|
||||
* Where to redirect users after verification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->middleware('signed')->only('verify');
|
||||
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||
}
|
||||
}
|
14
app/Http/Controllers/Doctor/HomeController.php
Normal file
14
app/Http/Controllers/Doctor/HomeController.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\doctor;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('doctor.home');
|
||||
}
|
||||
}
|
28
app/Http/Controllers/HomeController.php
Normal file
28
app/Http/Controllers/HomeController.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Support\Renderable
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('home');
|
||||
}
|
||||
}
|
139
app/Http/Controllers/OpenErm/PatientController.php
Normal file
139
app/Http/Controllers/OpenErm/PatientController.php
Normal file
@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\OpenErm;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class PatientController extends Controller
|
||||
{
|
||||
private $baseUrl = 'https://erm.codelfi.com';
|
||||
private $clientId = 'L31xI_99M2_atm565sWplF6XVTLliDID6u7ZQwF6Y7U';
|
||||
private $clientSecret = 'yu2Mo4550dtl5Fi_HrdGKHjRPTXcfUZLvKeLY5_za0Qi5tIts3HY6PTKt9dfFANX7y8GaLLFJn6WMOAjh0OeCg';
|
||||
private $username = 'VNS-admin-34';
|
||||
private $password = '2Uj3Y3fKDgVgLbf';
|
||||
|
||||
public function getPatientList(Request $request)
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
|
||||
$searchParams = [];
|
||||
|
||||
if ($request->has('fname')) {
|
||||
$searchParams['fname'] = $request->input('fname');
|
||||
}
|
||||
|
||||
if ($request->has('lname')) {
|
||||
$searchParams['lname'] = $request->input('lname');
|
||||
}
|
||||
|
||||
$response = Http::withHeaders([
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
])->get($this->baseUrl . '/apis/default/api/patient', $searchParams);
|
||||
|
||||
return $response->json();
|
||||
}
|
||||
public function getPatientById($puuid)
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
|
||||
$response = Http::withHeaders([
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
])->get($this->baseUrl . '/apis/default/api/patient/' . $puuid);
|
||||
|
||||
return $response->json();
|
||||
}
|
||||
public function registerPatient(Request $request)
|
||||
{
|
||||
$accessToken = $this->getAccessToken();
|
||||
|
||||
$patientData = $request->validate([
|
||||
'title' => 'required|string',
|
||||
'fname' => 'required|string',
|
||||
'mname' => 'nullable|string',
|
||||
'lname' => 'required|string',
|
||||
'street' => 'required|string',
|
||||
'postal_code' => 'required|string',
|
||||
'city' => 'required|string',
|
||||
'state' => 'required|string',
|
||||
'country_code' => 'required|string',
|
||||
'phone_contact' => 'required|string',
|
||||
'DOB' => 'required|date',
|
||||
'sex' => 'required|string',
|
||||
'race' => 'nullable|string',
|
||||
'ethnicity' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$response = Http::withHeaders([
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
])->post($this->baseUrl . '/apis/default/api/patient', $patientData);
|
||||
|
||||
return $response->json();
|
||||
}
|
||||
|
||||
private function getAccessToken()
|
||||
{
|
||||
if (Cache::has('access_token')) {
|
||||
return Cache::get('access_token');
|
||||
}
|
||||
|
||||
$response = Http::asForm()->withHeaders([
|
||||
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret),
|
||||
])->post($this->baseUrl . '/oauth2/default/token', [
|
||||
'grant_type' => 'password',
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
'user_role' => 'users',
|
||||
'username' => $this->username,
|
||||
'password' => $this->password,
|
||||
'scope' => 'openid offline_access api:oemr user/patient.read user/patient.write',
|
||||
]);
|
||||
|
||||
$tokenData = $response->json();
|
||||
|
||||
if (isset($tokenData['access_token'])) {
|
||||
Cache::put('access_token', $tokenData['access_token'], now()->addSeconds($tokenData['expires_in'] - 60));
|
||||
Cache::put('refresh_token', $tokenData['refresh_token'], now()->addDays(30));
|
||||
}
|
||||
|
||||
return $tokenData['access_token'] ?? null;
|
||||
}
|
||||
|
||||
private function refreshAccessToken()
|
||||
{
|
||||
$refreshToken = Cache::get('refresh_token');
|
||||
|
||||
if (!$refreshToken) {
|
||||
return $this->getAccessToken();
|
||||
}
|
||||
|
||||
$response = Http::asForm()->withHeaders([
|
||||
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret),
|
||||
])->post($this->baseUrl . '/oauth2/default/token', [
|
||||
'grant_type' => 'refresh_token',
|
||||
'client_id' => $this->clientId,
|
||||
'client_secret' => $this->clientSecret,
|
||||
'refresh_token' => $refreshToken,
|
||||
]);
|
||||
|
||||
$tokenData = $response->json();
|
||||
|
||||
if (isset($tokenData['access_token'])) {
|
||||
Cache::put('access_token', $tokenData['access_token'], now()->addSeconds($tokenData['expires_in'] - 60));
|
||||
if (isset($tokenData['refresh_token'])) {
|
||||
Cache::put('refresh_token', $tokenData['refresh_token'], now()->addDays(30));
|
||||
}
|
||||
return $tokenData['access_token'];
|
||||
}
|
||||
|
||||
return $this->getAccessToken();
|
||||
}
|
||||
}
|
248
app/Http/Controllers/OrderController.php
Normal file
248
app/Http/Controllers/OrderController.php
Normal file
@ -0,0 +1,248 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\Item;
|
||||
use App\Models\ItemHistory;
|
||||
use App\Models\PatientNote;
|
||||
use App\Models\PatientPrescription;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Prescription;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use PhpParser\Node\Stmt\Const_;
|
||||
|
||||
class OrderController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected $user_id;
|
||||
protected $url;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->user_id = Auth::guard('patient')->user()->id;
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Support\Renderable
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('home');
|
||||
}
|
||||
public function orderList(Request $request)
|
||||
{
|
||||
|
||||
$fromDate = $request->get('from_date');
|
||||
$toDate = $request->get('to_date');
|
||||
$orderList = Cart::where('carts.patient_id', $this->user_id);
|
||||
if ($fromDate != "") {
|
||||
$from_date = Carbon::createFromFormat('m-d-Y', $fromDate)->format('Y-m-d');
|
||||
$orderList->where('created_at', ">=", $from_date . " 00:00:00");
|
||||
}
|
||||
if ($toDate != "") {
|
||||
$to_date = Carbon::createFromFormat('m-d-Y', $toDate)->format('Y-m-d');
|
||||
$orderList->where('created_at', "<=", $to_date . " 23:59:59");
|
||||
}
|
||||
|
||||
$orderListData = $orderList->get();
|
||||
$totalPrice = 0;
|
||||
$totalShippingCost = 0;
|
||||
foreach ($orderListData as $order) {
|
||||
$totalPrice = 0;
|
||||
$total_products = 0;
|
||||
$quantity = [];
|
||||
$totalShippingCost = 0;
|
||||
$order->order_total_amount = $totalPrice;
|
||||
$order->order_total_shipping = $totalShippingCost;
|
||||
$items = Item::leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id')
|
||||
->where('cart_id', $order->id)
|
||||
->get();
|
||||
//$order->appointment_status = Appointment::where('id', $order->appointment_id)->first()->status;
|
||||
|
||||
$orderItems = [];
|
||||
foreach ($items as $item) {
|
||||
array_push($orderItems, $item->plansV1);
|
||||
$totalShippingCost += $item->shipping_cost;
|
||||
$item->total_price = $item->quantity * $item->price;
|
||||
$totalPrice += $item->total_price;
|
||||
$order->order_total_amount = $totalPrice;
|
||||
$order->order_total_shipping = $totalShippingCost;
|
||||
$item->plansV1->qty = $item->quantity;
|
||||
}
|
||||
|
||||
$order->total_items = $total_products;
|
||||
$order->order_items = $orderItems;
|
||||
}
|
||||
return response()
|
||||
->json([
|
||||
'order_data' => $orderListData
|
||||
]);
|
||||
}
|
||||
|
||||
public function orderDetails($id)
|
||||
{
|
||||
$orderItems = $this->getOrderItems($id);
|
||||
|
||||
$orderDetails = Cart::find($id);
|
||||
$items = Item::where('cart_id', $orderDetails->id)->get();
|
||||
|
||||
|
||||
$appointments = Appointment::select(
|
||||
'appointments.*',
|
||||
'telemed_pros.name as provider_name',
|
||||
'telemed_pros.email as provider_email',
|
||||
'telemed_pros.phone_number as provider_phone',
|
||||
'carts.total_amount',
|
||||
'carts.shipping_amount'
|
||||
)
|
||||
->leftJoin('telemed_pros', 'telemed_pros.id', 'appointments.telemed_pros_id')
|
||||
->leftJoin('carts', 'carts.appointment_id', 'appointments.id')
|
||||
|
||||
->where('appointments.id', $orderDetails->appointment_id)
|
||||
->first();
|
||||
|
||||
$prescription = PatientPrescription::select(
|
||||
'patient_prescription.direction_quantity',
|
||||
'patient_prescription.refill_quantity',
|
||||
'patient_prescription.dosage',
|
||||
'patient_prescription.status',
|
||||
'patient_prescription.direction_one',
|
||||
'patient_prescription.direction_two',
|
||||
'patient_prescription.dont_substitute',
|
||||
'patient_prescription.comments',
|
||||
'patient_prescription.brand',
|
||||
'patient_prescription.from',
|
||||
'patient_prescription.quantity',
|
||||
'patient_prescription.created_at as prescription_date',
|
||||
'prescriptions.name as prescription_name',
|
||||
'patient_prescription.prescription_id',
|
||||
'telemed_pros.name as provide_name',
|
||||
'telemed_pros.id as provider_id'
|
||||
)
|
||||
->where("appointment_id", $orderDetails->appointment_id)
|
||||
->leftJoin('appointments', 'appointments.id', 'patient_prescription.appointment_id')
|
||||
->leftJoin('prescriptions', 'prescriptions.id', 'patient_prescription.prescription_id')
|
||||
->leftJoin('telemed_pros', 'appointments.telemed_pros_id', 'telemed_pros.id')
|
||||
->get();
|
||||
$patientNotes = PatientNote::where("appointment_id", $orderDetails->appointment_id)->get();
|
||||
if ($appointments)
|
||||
$appointments->provider_id = $appointments->telemed_pros_id;
|
||||
$patient = $orderDetails->patient;
|
||||
$patient->profile_picture = $this->url->to("storage/profile_pictures/" . $patient->profile_picture);
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'order_details' => $orderDetails,
|
||||
'order_items' => $orderItems,
|
||||
'patient_details' => $patient,
|
||||
'appointment_details' => $appointments,
|
||||
'items_activity' => $this->getShippingActivity($id),
|
||||
'appointment_notes' => $patientNotes,
|
||||
'prescription' => $prescription
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function getShippingActivity($id)
|
||||
{
|
||||
$itemsHistory = ItemHistory::select('items_history.*', 'plans_v1.title as item_name')
|
||||
->where('items_history.cart_id', $id)
|
||||
->leftJoin('items', 'items.id', 'items_history.item_id')
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->get();
|
||||
return $itemsHistory;
|
||||
}
|
||||
public function getPatientShippingActivity()
|
||||
{
|
||||
$orderDetails = Cart::where('patient_id', $this->user_id)->orderBy('id', 'Desc')->first();
|
||||
|
||||
$itemsHistory = ItemHistory::select('items_history.*', 'plans_v1.title as item_name')
|
||||
->where('items_history.cart_id', $orderDetails->id)
|
||||
->leftJoin('items', 'items.id', 'items_history.item_id')
|
||||
->leftJoin('plans_v1', 'plans_v1.id', 'items.plans_id')
|
||||
->get();
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'item_history' => $itemsHistory
|
||||
|
||||
]);
|
||||
}
|
||||
public function getOrderItems($id)
|
||||
{
|
||||
$items = Item::leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id')
|
||||
->where('cart_id', $id)
|
||||
->get();
|
||||
$totalPrice = 0;
|
||||
$totalShippingCost = 0;
|
||||
$total_products = 0;
|
||||
foreach ($items as $item) {
|
||||
|
||||
$totalShippingCost += $item->shipping_cost;
|
||||
$item->total_price = $item->quantity * $item->price;
|
||||
$totalPrice += $item->total_price;
|
||||
$total_products += $item->quantity;
|
||||
$item->image_url = $this->url->to("product/" . $item->image_url);
|
||||
}
|
||||
|
||||
return [
|
||||
'items' => $items,
|
||||
'total_amount' => $totalPrice,
|
||||
'total_shipping_cost' => $totalShippingCost,
|
||||
'total_products' => $total_products,
|
||||
'total' => $totalPrice + $totalShippingCost
|
||||
];
|
||||
}
|
||||
public function subscriptionList()
|
||||
{
|
||||
|
||||
$orderDetails = Cart::leftJoin('items', 'carts.id', 'items.cart_id')
|
||||
->leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id')
|
||||
->where('patient_id', $this->user_id)
|
||||
->where('plans_v1.is_prescription_required', '1')
|
||||
->get();
|
||||
foreach ($orderDetails as $details) {
|
||||
$details->image_url = $this->url->to("product/" . $details->image_url);
|
||||
}
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'subscriptions' => $orderDetails
|
||||
]);
|
||||
}
|
||||
public function getSubscriptionDetails($id)
|
||||
{
|
||||
$orderDetails = Cart::find($id);
|
||||
|
||||
$items = Item::leftJoin('plans_v1', 'items.plans_id', 'plans_v1.id')
|
||||
->where('plans_v1.is_prescription_required', '1')
|
||||
->get();
|
||||
$appointments = Appointment::find($orderDetails->appointment_id);
|
||||
|
||||
$patient = $orderDetails->patient;
|
||||
|
||||
$patient->profile_picture = $this->url->to("storage/profile_pictures/" . $patient->profile_picture);
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'order_details' => $orderDetails,
|
||||
'order_items' => $items,
|
||||
'patient_details' => $patient,
|
||||
'appointment_details' => $appointments
|
||||
|
||||
]);
|
||||
}
|
||||
}
|
1852
app/Http/Controllers/PatientController.php
Normal file
1852
app/Http/Controllers/PatientController.php
Normal file
File diff suppressed because it is too large
Load Diff
164
app/Http/Controllers/ProfileController.php
Normal file
164
app/Http/Controllers/ProfileController.php
Normal file
@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Classes\Constant;
|
||||
use App\Models\Appointment;
|
||||
use App\Models\Cart;
|
||||
use App\Models\LabKit;
|
||||
use App\Models\LabkitOrderItem;
|
||||
use App\Models\Patient;
|
||||
use App\Models\Subscription;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected $user_id;
|
||||
protected $url;
|
||||
public function __construct(UrlGenerator $url)
|
||||
{
|
||||
$this->middleware('auth');
|
||||
$this->user_id = Auth::guard('patient')->user()->id;
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Support\Renderable
|
||||
*/
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('home');
|
||||
}
|
||||
public function profileDetails()
|
||||
{
|
||||
$patient = Auth::guard('patient')->user();
|
||||
$patient->profile_picture = $this->url->to("storage/profile_pictures/" . $patient->profile_picture);
|
||||
// $patient->profile_picture = Storage::path("profile_pictures/" . $patient->profile_picture);
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'profile' => $patient
|
||||
]);
|
||||
}
|
||||
public function UpdateProfile(Request $request)
|
||||
{
|
||||
$patient = Patient::find($this->user_id);
|
||||
$patient->address = $request->get('address');
|
||||
$patient->city = $request->get('city');
|
||||
$patient->state = $request->get('state');
|
||||
$patient->zip_code = $request->get('zip_code');
|
||||
$patient->first_name = $request->get('first_name');
|
||||
$patient->last_name = $request->get('last_name');
|
||||
$patient->phone_no = $request->get('phone_no');
|
||||
$patient->gender = $request->get('gender');
|
||||
$patient->save();
|
||||
return response()
|
||||
->json([
|
||||
'message' => 'Profile updated!'
|
||||
]);
|
||||
}
|
||||
public function resetPassword(Request $request)
|
||||
{
|
||||
$oldPassword = $request->get('old_password');
|
||||
$newPassword = $request->get('new_password');
|
||||
|
||||
$user = Patient::find($this->user_id);
|
||||
if (Hash::check($oldPassword, $user->password)) {
|
||||
$user->password = bcrypt($newPassword);
|
||||
$user->save();
|
||||
return response()->json([
|
||||
'msg' => "Password updated"
|
||||
]);
|
||||
} else {
|
||||
return response()->json([
|
||||
'msg' => "Password does not match",
|
||||
'status' => 'error'
|
||||
]);
|
||||
}
|
||||
}
|
||||
public function changeProfileImage(Request $request)
|
||||
{
|
||||
$patient = Patient::find($this->user_id);
|
||||
$image = $request->get('image');
|
||||
$fileName = 'profile-' . time();
|
||||
|
||||
$logo = base64_decode($image);
|
||||
$ext = (explode('/', finfo_buffer(finfo_open(), $logo, FILEINFO_MIME_TYPE))[1]);
|
||||
|
||||
$imageName = $fileName . '.' . $ext;
|
||||
Storage::disk('local')->put("public/profile_pictures/" . $imageName, $logo);
|
||||
$patient->profile_picture = $imageName;
|
||||
$patient->save();
|
||||
return response()->json([
|
||||
'msg' => "File Uploaded",
|
||||
'status' => 'success'
|
||||
]);
|
||||
}
|
||||
public function getStats()
|
||||
{
|
||||
$upcomingAppointments = Appointment::where('patient_id', $this->user_id)
|
||||
->whereNull('start_time')
|
||||
->count();
|
||||
$TotalCounts = Appointment::where('patient_id', $this->user_id)
|
||||
->whereNotNull('start_time')
|
||||
->whereNotNull('end_time')
|
||||
->count();
|
||||
$orders = Cart::where('patient_id', $this->user_id)->count();
|
||||
$subscriptions = Subscription::where('patient_id', $this->user_id)->count();
|
||||
return response()->json([
|
||||
'upcoming_meetings' => $upcomingAppointments,
|
||||
'total_meetings' => $TotalCounts,
|
||||
'total_orders' => $orders,
|
||||
'total_subscription' => $subscriptions
|
||||
]);
|
||||
}
|
||||
public function labkitOrderItemGet(Request $request)
|
||||
{
|
||||
$labkitOrderItems = LabkitOrderItem::where('labkit_order_items.cart_id', $request->input('cart_id'))
|
||||
->leftJoin(
|
||||
'lab_kit',
|
||||
'labkit_order_items.lab_kit_id',
|
||||
'=',
|
||||
'lab_kit.id'
|
||||
)
|
||||
->leftJoin(
|
||||
'items',
|
||||
'items.id',
|
||||
'labkit_order_items.item_id'
|
||||
)
|
||||
->leftJoin(
|
||||
'plans_v1',
|
||||
'plans_v1.id',
|
||||
'items.plans_id'
|
||||
)
|
||||
->select(
|
||||
'labkit_order_items.id',
|
||||
'labkit_order_items.status',
|
||||
'labkit_order_items.result',
|
||||
'lab_kit.name as lab_kit_name',
|
||||
'plans_v1.title as item_name'
|
||||
)
|
||||
->get();
|
||||
foreach ($labkitOrderItems as $labKit) {
|
||||
|
||||
if ($labKit->result != "")
|
||||
$labKit->result = $this->url->to('storage/lab_results/' . $labKit->result);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'data' => $labkitOrderItems,
|
||||
]);
|
||||
}
|
||||
}
|
83
app/Http/Kernel.php
Normal file
83
app/Http/Kernel.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array<int, class-string|string>
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class /* . ':60,100' */,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's middleware aliases.
|
||||
*
|
||||
* Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
|
||||
*
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
|
||||
'admin_auth' => \App\Http\Middleware\AdminAuth::class,
|
||||
'admin_authenticated' => \App\Http\Middleware\AdminRedirectAuthenticated::class,
|
||||
'agent_auth' => \App\Http\Middleware\AgentAuth::class,
|
||||
'agent_authenticated' => \App\Http\Middleware\AgentRedirectAuthenticated::class,
|
||||
'doctor_auth' => \App\Http\Middleware\DoctorAuth::class,
|
||||
'patient_auth' => \App\Http\Middleware\PatientAuth::class,
|
||||
'access_control' => \App\Http\Middleware\AccessControlMiddleware::class,
|
||||
'patient_authenticated' => \App\Http\Middleware\PatientAuthenticated::class,
|
||||
'doctor_authenticated' => \App\Http\Middleware\DoctorRedirectAuthenticated::class,
|
||||
|
||||
|
||||
];
|
||||
protected $middlewareAliases = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
|
||||
];
|
||||
}
|
48
app/Http/Middleware/AccessControlMiddleware.php
Normal file
48
app/Http/Middleware/AccessControlMiddleware.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use App\Model\ProcessLog;
|
||||
use Carbon\Carbon;
|
||||
use App\Classes\Constant;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use App\Model\Client;
|
||||
use App\Model\JsToken;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class AccessControlMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$key = false;
|
||||
$pass = false;
|
||||
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
|
||||
$headers = [
|
||||
'Access-Control-Allow-Methods' => 'POST,GET,OPTIONS,PUT,DELETE',
|
||||
'Access-Control-Allow-Headers' => 'Content-Type, X-Auth-Token, Origin, Authorization',
|
||||
];
|
||||
if ($request->getMethod() == "OPTIONS") {
|
||||
|
||||
return response()->json('OK',200,$headers);
|
||||
}
|
||||
$response = $next($request);
|
||||
foreach ($headers as $key => $value) {
|
||||
$response->header($key, $value);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
30
app/Http/Middleware/AdminAuth.php
Normal file
30
app/Http/Middleware/AdminAuth.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use App\Model\ProcessLog;
|
||||
use Carbon\Carbon;
|
||||
use App\Classes\Constant;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use App\Model\Client;
|
||||
use App\Model\JsToken;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class AdminAuth
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
Auth::setDefaultDriver('admin');
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
58
app/Http/Middleware/AdminRedirectAuthenticated.php
Normal file
58
app/Http/Middleware/AdminRedirectAuthenticated.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Tymon\JWTAuth\Facades\JWTAuth;
|
||||
use Tymon\JWTAuth\Exceptions\JWTException;
|
||||
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
|
||||
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
|
||||
|
||||
|
||||
class AdminRedirectAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $guard
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, $guard = null)
|
||||
{
|
||||
try {
|
||||
$user = JWTAuth::parseToken()->authenticate();
|
||||
} catch (TokenExpiredException $e) {
|
||||
return response()->json(['error' => 'Token has expired'], 401);
|
||||
} catch (TokenInvalidException $e) {
|
||||
return response()->json(['error' => 'Token is invalid'], 401);
|
||||
} catch (JWTException $e) {
|
||||
return response()->json(['error' => 'Token is missing or invalid'], 401);
|
||||
} catch (TokenExpiredException $e) {
|
||||
// Invalidate the old token
|
||||
$token = JWTAuth::getToken();
|
||||
JWTAuth::invalidate($token);
|
||||
|
||||
|
||||
|
||||
|
||||
// Return an error response with instructions for obtaining a new token
|
||||
return response()->json([
|
||||
'error' => 'Token has expired',
|
||||
'message' => 'Please obtain a new token from the authentication endpoint.'
|
||||
], 401);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// // Check if the user has the required role or permissions
|
||||
// if (!$user->hasRole('admin') && !$user->hasPermission('access_admin_panel')) {
|
||||
// return response()->json(['error' => 'Unauthorized'], 403);
|
||||
// }
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
30
app/Http/Middleware/AgentAuth.php
Normal file
30
app/Http/Middleware/AgentAuth.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use App\Model\ProcessLog;
|
||||
use Carbon\Carbon;
|
||||
use App\Classes\Constant;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use App\Model\Client;
|
||||
use App\Model\JsToken;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class AgentAuth
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
Auth::setDefaultDriver('agent');
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
28
app/Http/Middleware/AgentRedirectAuthenticated.php
Normal file
28
app/Http/Middleware/AgentRedirectAuthenticated.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AgentRedirectAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $guard
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
if (Auth::user() && Auth::guard('agent')->check()) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
return redirect('/agent/login');
|
||||
|
||||
|
||||
}
|
||||
}
|
17
app/Http/Middleware/Authenticate.php
Normal file
17
app/Http/Middleware/Authenticate.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*/
|
||||
protected function redirectTo(Request $request): ?string
|
||||
{
|
||||
return $request->expectsJson() ? null : route('login');
|
||||
}
|
||||
}
|
30
app/Http/Middleware/DoctorAuth.php
Normal file
30
app/Http/Middleware/DoctorAuth.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use App\Model\ProcessLog;
|
||||
use Carbon\Carbon;
|
||||
use App\Classes\Constant;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use App\Model\Client;
|
||||
use App\Model\JsToken;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class DoctorAuth
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
Auth::setDefaultDriver('doctor');
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user