Compare commits

...

173 Commits

Author SHA1 Message Date
c9cf8d7e0a up: various twig templates
* various twig updates
2025-02-10 16:18:53 -05:00
b828333222 fix: twig note templates
* fix edit notes and and member present
* refactor enum moving process
2025-02-10 15:10:25 -05:00
607ca79c4d up: various
* various minor update
2025-02-10 15:08:28 -05:00
0ebd90a03b up: twig company-info
* add vendorId twig template form element
2025-02-10 15:05:56 -05:00
24784bb1bb add: twig case
* add case rate to twig template forms
2025-02-10 15:04:43 -05:00
e3380bab2f up: UserChecker
* Rename user class
2025-02-10 15:03:02 -05:00
2cd4c68baf fix: MemberRepository
* Fix getting selected members from a note
2025-02-10 15:00:10 -05:00
52f835bbda fix: *NoteFormType
* Fix member selection
2025-02-10 14:59:13 -05:00
680b7ab9bd up: MemberCaseFormType
* Add rate property form element
2025-02-10 14:58:11 -05:00
4f6a80eade up: MemberCaseFormType
* Add vendorId property
2025-02-10 14:57:33 -05:00
53d9350cb8 up: MemberCase
* Add rate integer property
2025-02-10 14:54:45 -05:00
428304e5af up: Company
* add vendorId property and methods, may need to add more for reporting data
2025-02-09 18:16:14 -05:00
c4d1a33272 up: VisitNote & StandardNote
* couple minor changes
2025-02-09 18:15:21 -05:00
4fd42970ac up: Member
* add checked property and setId method to support note editing and retrieval and display of form parameters
2025-02-09 18:14:53 -05:00
1fd72d95e0 ref: MessageController
* move message controller to new path, forgot to update namespace
2025-02-09 18:14:01 -05:00
74ad66496e add: DefaultController
* add up method for connection checking
2025-02-09 18:13:32 -05:00
8851c4f6e8 ref: AjaxController
* refactor for readability
2025-02-09 18:13:00 -05:00
51ea4e2311 up: ReferralController
* remove $this->msgs and just call Libs::getMessages method
2025-02-09 18:12:36 -05:00
4859aa23b8 up: NoteController
* add error if user doesn't select referral when trying to add new note
* Finalize note editing
2025-02-09 18:11:48 -05:00
e601727514 sec: AdminController
* set initial password change date to epoch when creating new account
2025-02-09 18:10:14 -05:00
b54e2a51f9 ref: security.yaml
* update entity path after moving entities around
2025-02-09 18:09:11 -05:00
d51c67db3d up: notes.js
* Convert duration to hours/units
* Move calcTime method here
2025-02-09 18:08:32 -05:00
1cfc4c7355 rm: itinerary.js
* remove arrival because it's unnecessary
2025-02-09 18:06:42 -05:00
8e85405426 upd: CaseController
* remove assignCaseDocument method in favor of Member Document assignment
2025-01-28 21:02:20 -05:00
9887889ecb ref: Repositories
* Refactor all files
2025-01-28 20:59:14 -05:00
593958cc68 ref: Libs
* Refactor files
* Move autocompleteAddress method to GeoapifyController
2025-01-28 20:58:47 -05:00
528827868b upd: Forms
* Move classes
2025-01-28 20:54:50 -05:00
af6ebbb1b2 mv: Factories
* move files
2025-01-28 20:48:41 -05:00
e08e23d647 mv: Enums
* Move enums
2025-01-28 20:48:00 -05:00
bcc32bf445 mv: Refactor
* Move entities for organization
2025-01-28 20:47:26 -05:00
ee2fce4c41 upd: DataFixtures
* Refactor after moving files
2025-01-28 20:46:38 -05:00
13aaaae34c mv: All Controllers
* Move all controllers to sub-directories for organization
2025-01-28 20:43:23 -05:00
fc9ebbd327 upd: importmap
* add moment library
2025-01-24 11:20:13 -05:00
4cddccdf6e upd: twig nav
* remove case notes nav in favor of navigating through case data
* rename Case Addresses to Addresses
2025-01-24 11:19:06 -05:00
3d786f1f16 upd: twig list-notes
* correct link for adding a new note
* remove display of present members
2025-01-24 11:16:25 -05:00
e5f09bd8cc upd: Libs
Permissions checking
* Add checkPermissions method to check the permissions of the user to the case to make sure they have permissions to add or edit.
2025-01-24 10:35:46 -05:00
77d90ed691 fix: NoteForms
* change members field to unmapped
2025-01-24 10:34:12 -05:00
0d69b51ff9 upd: CommunityResource
* Add method to convert class to Location object
2025-01-24 10:19:43 -05:00
df29fd0d99 fix: NoteController
Save members
* get note members working, still need to setup editing
2025-01-24 10:18:56 -05:00
09ae2756c2 upd: ItineraryController
* remove unnecessary use statements
2025-01-24 10:17:43 -05:00
520409b0b4 fix: CaseController
* add permission validation
2025-01-24 10:15:49 -05:00
fe622ef794 upd: twig edit-members
add member documents
2025-01-22 21:32:58 -05:00
0844b3fc58 upd: MemberDocumentRepository
Remove
* remove unsigned documents from repository for member to sign
2025-01-22 21:32:26 -05:00
6468e77445 upd: User
vCard profile
* Add profile image to vCard
2025-01-22 21:31:36 -05:00
2e41c1ed83 fix: CompanyDocument
Add Property
* add selected property to support edit-member functionality
2025-01-22 21:28:27 -05:00
6ecb76a829 fix: MemberController
member editting
* Add documents
* Cleanup
2025-01-22 21:20:24 -05:00
1fa3843b50 fix: remove class permission requirement 2025-01-22 21:02:30 -05:00
e376dadb4b add: composer
* add phpstan library and require extensions
2025-01-21 14:46:35 -05:00
b990ea55cb fix: twig
* couple display fixes
2025-01-21 14:46:03 -05:00
67d83a1f98 add: twig nav
* add company directory link
2025-01-21 14:44:39 -05:00
79db6b2ec9 fix: twig add-member
* add checkboxes for each company document
2025-01-21 14:43:55 -05:00
0c5fa617ad fix: twig list-users
* fix display of user profile
* add text muting if user is inactive
2025-01-21 14:43:20 -05:00
6effcba396 fix: twig edit-user
* fix background image display
* fix display for work and personal phone numbers
* add active checkbox
* fix displays for role checkboxes
2025-01-21 14:41:49 -05:00
43e6811928 fix: twig users
Fix user background image that displays left of the form
2025-01-21 14:40:01 -05:00
705d7330b0 add: twig company-info
Add new display
2025-01-21 14:38:49 -05:00
7bc73345b0 fix: twig couple files
* fix referralType display after converting to enum
2025-01-21 14:38:12 -05:00
610cccc191 fix: twig assign-case
* add number of cases to user list
2025-01-21 14:36:46 -05:00
a47a5e8adb fix: twig add-case
* fix display with admit and close dates
* convert referralType to use enum
* fix display for case level, referral source & 2, county
* remove case documents checkboxes
2025-01-21 14:35:53 -05:00
81838608b3 add: NavList
Add company_directory field
2025-01-21 14:32:32 -05:00
d39942eced fix: MemberCase
Migration for CaseDocuments to MemberDocuments
Convert referralType field to use ReferralType Enum
2025-01-21 14:32:04 -05:00
cdacfd918a fix: MessageFactory
Add link parameter to createNewCase method
2025-01-21 14:30:17 -05:00
922852f211 fix: User
various updates
* remove unnecessary caseWorker, caseManager, therapist, su properties
* Removed retrieveUnreadNotifications method that was just a stub
* convert "is..." methods to check for present roles
* update getJobs method with above logic
* add generateVCard method to support company directory
2025-01-21 14:29:31 -05:00
224a5cd243 add: MemberDocument
Add MemberDocument class and assoc repo
2025-01-21 14:25:00 -05:00
6d8fbd5bb8 fix: MemberCase
ReferralType
* Convert ReferralType in class to an Enum
2025-01-21 14:24:11 -05:00
82ee30a724 add: CompanyDocument
Add class
* Add CompanyDocument class, associated repo and twig files
2025-01-21 14:23:14 -05:00
e13dc0bf66 fix: MemberController
MemberDocument migration
* Migrate CaseDocument to MemberDocument
* Setup assigning a document to a case member when creating member
* Still need to fix member edit
2025-01-21 14:20:57 -05:00
844209d3e3 commit gitmessage template 2025-01-21 14:18:06 -05:00
001a674f6f fix: DocumentController
move case documents to member documents
first draft of signing
2025-01-21 14:13:19 -05:00
caeb15f05b add: CompanyController
Add company directory method
2025-01-21 14:11:40 -05:00
2af4b8e04e fix: CaseController
migrate documents to MemberController
add link to new case message
2025-01-21 14:09:21 -05:00
c04e255476 fix: AdminController
ensure new users are active
fix role assignments and remove unnecessary fields
fix supervision assignment to update the record instead of deleting
2025-01-21 14:08:12 -05:00
2e77baae1b Add UserChecker to check for expired passwords, ensure users have active accounts 2025-01-21 02:07:50 +00:00
d74e10803c Add UserChecker to check for expired passwords, ensure users have active accounts 2025-01-21 02:04:29 +00:00
3d67d74242 added active and lastLogin properties 2025-01-13 22:17:22 +00:00
c2608a17cf added method to update the lastlogin so we can track how long it's been since a user last logged in. 2025-01-13 22:12:12 +00:00
1cb6bedb5c add docs for the case 2025-01-11 22:30:54 -05:00
74e811e950 add docs for the case 2025-01-11 22:03:30 -05:00
b7c0b3de6b add work and personal phone to form 2025-01-11 21:57:45 -05:00
458ba42644 couple updates 2025-01-10 15:09:44 +00:00
6687dc1401 add signature_pad and tinymce libraries 2025-01-10 15:09:01 +00:00
dc3fec7eff add company logo to form 2025-01-10 15:08:31 +00:00
acee114ccf add link to company documents if in company editor and replace links with path calls to route name 2025-01-10 15:07:59 +00:00
5f0ce69a47 remove notifcationCount variable and limit displayed notifications to 5 2025-01-10 15:06:03 +00:00
d2f8bc7cbf use company logo if available and add link to company data 2025-01-10 15:05:22 +00:00
b7b0c8e6c4 add block for assigning documents to a case, use company timezone, update anchor tag class 2025-01-10 15:03:53 +00:00
722954d0d0 remove message returning limit 2025-01-10 14:56:08 +00:00
57e002916c fix error 2025-01-10 14:55:43 +00:00
178f44fd2d add methods to get travel info 2025-01-10 14:55:14 +00:00
7b4da30342 add default const to simplify setting and resetting the list 2025-01-10 14:54:22 +00:00
03cbbc0db6 add formatPhone and getMessages methods. Also, add method to autocomplete addresses 2025-01-10 14:53:33 +00:00
f454888a6f add company form for updating the company 2025-01-10 14:51:44 +00:00
dce5dcab2f add document controller for document actions 2025-01-10 14:50:03 +00:00
75cffad2ea add company controller for company actions 2025-01-10 14:49:08 +00:00
cd8cbcf6ba add documentextras enum for documntation creation 2025-01-10 14:47:55 +00:00
6956256341 add signature block 2025-01-10 14:47:17 +00:00
42fcb7b2f5 add company logo 2025-01-10 14:46:35 +00:00
351cc7c3ac add infowindow method for mapping, convert datetime creation to use company timezone 2025-01-10 14:46:19 +00:00
e1e4c12801 add InfoWindow data methods for mapping 2025-01-10 14:44:59 +00:00
6260b13df0 convert datetime to use company timezone 2025-01-10 14:39:31 +00:00
02fcb0cc54 remove notificationCount, convert to use Libs::getMessages method, change datetime creation to use company timezone 2025-01-10 13:33:33 +00:00
2d7b7e6d12 remove notificationCount, convert to Libs::getMessages method, change datetime creation to add company timezone, remove CaseController::showCaseNotes 2025-01-10 12:44:37 +00:00
604f693c45 add company timezone 2025-01-10 12:37:16 +00:00
be80563038 add css to remove underlines in anchor tags 2025-01-10 12:36:14 +00:00
04d5e88820 javascript for various functions 2025-01-10 12:34:49 +00:00
d85c1571e7 add update for personal and work phone number 2025-01-05 06:22:29 +00:00
adcd02ff2b add modal to send message to supervisor and contact info for supervisor 2025-01-05 06:20:38 +00:00
ec487ed1ac add icon and user profile image for message type and sender 2025-01-05 06:17:37 +00:00
83a886c134 add repositories 2025-01-05 06:13:39 +00:00
43bff55192 add method to filter notes 2025-01-05 06:11:35 +00:00
2031165afc add method to format phones 2025-01-05 06:10:22 +00:00
f14a4fa67c add staff_note enum type 2025-01-05 06:10:00 +00:00
f0853bfcb2 add connector class for notes and members 2025-01-05 06:09:29 +00:00
980affbfbb add personal and work phone 2025-01-05 06:08:02 +00:00
f9608bce18 add jsonSerialize 2025-01-05 06:07:46 +00:00
c78698ace4 reconfigure 2025-01-05 06:04:21 +00:00
91723ed9be reconfigure 2025-01-05 06:03:42 +00:00
758a439187 convert list-notes to not show anything by default but have a few filter fields to display what is needed, change add notes to use different member collection and tables, add filter method 2025-01-05 06:00:40 +00:00
6dc478d0b3 add exclusion for uploads folder 2025-01-05 05:56:57 +00:00
478cb006b4 for vich_uploader 2025-01-05 05:56:34 +00:00
5b3bb9f14c add mileage_rate .env variable 2025-01-05 05:56:08 +00:00
d5b3a56e0f add firewall path for uploads/user_images 2025-01-05 05:55:39 +00:00
ca379711e2 add vich_uploader config 2025-01-05 05:54:51 +00:00
c6d4a871fa add slugifier api for profile image uploading 2025-01-03 15:38:33 +00:00
9f23dfa0eb add chartjs to importmap 2025-01-03 15:37:35 +00:00
f12f9dda12 move stylesheets block and add page_css block 2025-01-03 15:36:37 +00:00
b2972fec3e update to use actual gradient fill color for flash messages 2025-01-03 15:35:41 +00:00
18c7c33ffb remove documentation footer button 2025-01-03 15:34:41 +00:00
68236e1571 add distance measurement 2025-01-03 15:33:41 +00:00
fe47746c1f update add user with profile image upload and first draft of profile updating 2025-01-03 15:32:59 +00:00
edfe6936f5 add different color pinpoint icons 2025-01-03 15:32:06 +00:00
ea322dc2ac Complete profile image, password update functionality 2025-01-03 15:31:07 +00:00
8d97ab0345 update map variables to use env variables, fix link for itinerary report and add active link for case_itinerary 2025-01-03 15:24:17 +00:00
133d99d297 start work on dashboard and complete first draft of profile 2025-01-03 15:22:45 +00:00
96abea4198 convert map parameters to env variables, add corrected breadcrumb 2025-01-03 14:04:02 +00:00
368b4fbcd3 allow uploading profile image 2025-01-03 14:01:54 +00:00
577dee227d format 2025-01-01 06:05:07 +00:00
79bb26e9f3 format 2025-01-01 06:04:24 +00:00
109384ec99 add report page and move map button to it 2025-01-01 06:03:17 +00:00
781935821b add getRecentTravel method 2025-01-01 06:01:18 +00:00
81ba235b08 add message link to staff note signature notifications 2025-01-01 06:00:46 +00:00
c3bc40561b update notification reader 2025-01-01 05:59:21 +00:00
af41590fd3 add itinerary report page, update map page, add markers for origin and destination, add filter-itinerary-by-case method 2025-01-01 05:57:42 +00:00
03c7153565 update openMap method for itinerary report 2025-01-01 05:55:09 +00:00
b42b1ea410 fix fetch link, add filterItineraryByCase method 2025-01-01 05:52:35 +00:00
2e163d526c add location form 2024-12-31 23:08:22 +00:00
d99ef31fef update libraries 2024-12-31 23:07:58 +00:00
e5bd7c4003 add page_js to be able to add javascript specific to a page 2024-12-31 23:07:18 +00:00
67c341c390 add id for flash messages 2024-12-31 23:05:11 +00:00
ef45c6cd28 add csrf protection 2024-12-31 23:04:37 +00:00
642492411e rename caseId to memberCase 2024-12-31 23:03:45 +00:00
1d16cadc7b fix close calculations 2024-12-31 23:03:19 +00:00
e44b346788 readd stimulus library and controller 2024-12-31 23:02:32 +00:00
6a5a5c2282 add leaflet controller 2024-12-31 23:02:06 +00:00
6c340b4229 first draft of case addresses and itineraries 2024-12-31 23:01:37 +00:00
1b5ca4bd34 remove functions to place in other js files 2024-12-31 23:00:17 +00:00
7f2f6aa749 add js libraries 2024-12-31 22:59:55 +00:00
d0e48b4142 remove bootstrap for importmap library 2024-12-31 22:59:14 +00:00
66100f0eaf make bg-gradient-dark background-image important to override bootstrap 2024-12-31 22:58:43 +00:00
e207668205 remove empty map 2024-12-31 22:57:49 +00:00
5b0ededa27 remove bootstrap, popper, perfect-scrollbar, and smooth-scrollbar from javascript block and added to importmap 2024-12-25 17:19:52 +00:00
ff50c96b74 formatting. 2024-12-25 17:18:45 +00:00
52a39792e0 formatting 2024-12-25 17:18:30 +00:00
f76ca5c3cc fix typo and added case_itinerary 2024-12-25 17:17:50 +00:00
d67db33ed0 add getRoute method and format numbers returned 2024-12-25 17:17:23 +00:00
1e3a6dd612 fix getting correct breadcrumb link and highling correct nav link 2024-12-25 17:16:04 +00:00
6a9c35842f formatting 2024-12-25 17:15:12 +00:00
2206fe33c9 add case addresses link 2024-12-25 03:07:29 +00:00
fc2218ee23 add lat/lon 2024-12-25 03:01:03 +00:00
b9d165928a add vicVichy/uploader-bundle 2024-12-25 02:54:45 +00:00
f877e3f4df fix 2024-12-25 02:51:04 +00:00
2655848d96 Add environment variables for data creation for testing 2024-12-25 02:48:32 +00:00
12199b6152 add staffnote fixture 2024-12-23 03:06:40 +00:00
b87e970164 add case viewer for case workers 2024-12-23 03:06:10 +00:00
197 changed files with 25785 additions and 19703 deletions

5
.gitmessage Normal file
View File

@ -0,0 +1,5 @@
{commit-type}: {module}
{description}
### Changes
* {change1}

View File

@ -4,32 +4,7 @@
* This file will be included onto the page via the importmap() Twig function,
* which should already be in your base.html.twig.
*/
import './bootstrap.js';
import './vendor/bootstrap/bootstrap.index.js';
import './vendor/bootstrap/dist/css/bootstrap.min.css';
import './styles/app.css';
function filterCasesByUser(userId) {
fetch('/index.php/api/filter-cases-by-user', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ userId: userId })
})
.then(response => response.json())
.then(data => {
const caseList = document.getElementById('case-list');
caseList.innerHTML = '';
data.forEach(c => {
caseList.innerHTML += `
<tr>
<td>${c.clientName}</td>
<td>${c.caseNumber}</td>
<td>${c.dcsCaseId}</td>
<td>${c.referralType}/${c.referralSource.name}<br/><a href='mailto:${c.referralSource.email}'>${c.referralSource.email}</a></td>
<td>${c.county.value}</td>
<td>${c.referrals.length}</td>
<td></td>
<td></td>
</tr>`;
})
});
}

5
assets/bootstrap.js vendored Normal file
View File

@ -0,0 +1,5 @@
import { startStimulusApp } from '@symfony/stimulus-bundle';
const app = startStimulusApp();
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

11
assets/controllers.json Normal file
View File

@ -0,0 +1,11 @@
{
"controllers": {
"@symfony/ux-leaflet-map": {
"map": {
"enabled": true,
"fetch": "lazy"
}
}
},
"entrypoints": []
}

View File

@ -24034,7 +24034,7 @@ label,
}
.bg-gradient-dark {
background-image: linear-gradient(195deg, #42424a 0%, #191919 100%);
background-image: linear-gradient(195deg, #42424a 0%, #191919 100%) !important;
}
.bg-gradient-faded-primary {
@ -29150,5 +29150,3 @@ pre[class*=language-] {
overflow: auto !important;
}
}
/*# sourceMappingURL=dashboard-free.css.map */

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

97
assets/js/app/filter.js Normal file
View File

@ -0,0 +1,97 @@
export function filterAddressesByCase() {
if (!document.getElementById('case-filter').value) {
return;
}
fetch('/api/filter-address-by-case/' + document.getElementById('case-filter').value, {
method: 'POST',
header: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(result => {
const addressList = document.getElementById('addressList');
const origin = document.getElementById('origin');
const destination = document.getElementById('destination');
origin.innerHTML = '';
destination.innerHTML = '';
addressList.innerHTML = '';
origin.innerHTML += '<option value="">-- Origin --</option>';
destination.innerHTML += '<option value="">-- Destination --</option>';
result.forEach(a => {
origin.innerHTML += `<option value='${a.id}'>${a.name}</option>`;
destination.innerHTML += `<option value='${a.id}'>${a.name}</option>`;
addressList.innerHTML += `
<tr>
<td>
<div class='d-flex px-2 py-1'>
<div class='d-flex flex-column justify-content-center'>
<h6 class='mb-0 text-small'>
${a.name}
</h6>
</div>
</div>
</td>
<td>${a.formattedAddress}</td>
<td class='align-middle text-center text-xs'>${a.lat}/${a.lon}</td>
<td class='align-middle'>
<a href='/addresses/edit/${a.id}' class='text-secondary' title='Edit Address'>
<i class='material-symbols-rounded opacity-5'>edit</i>
</a>
</td>
</tr>`;
})
});
}
export function filterItineraryByCase() {
let caseId = null;
let startDate = null;
let endDate = null;
if (document.getElementById('case-filter').value) {
caseId = document.getElementById('case-filter').value;
}
if (document.getElementById('start-date-filter').value) {
startDate = document.getElementById('start-date-filter').value;
}
if (document.getElementById('end-date-filter').value) {
endDate = document.getElementById('end-date-filter').value;
}
fetch('/api/filter-itinerary-by-case', {
method: 'POST',
header: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
caseId: caseId,
startDate: startDate,
endDate: endDate,
})
})
.then(response => response.json())
.then(result => {
const itineraryList = document.getElementById('itineraryList');
itineraryList.innerHTML = '';
result.forEach(i => {
itineraryList.innerHTML += `
<tr>
<td>${i.date}</td>
<td>${i.case}</td>
<td>${i.origin.name}</td>
<td>${i.destination.name}</td>
<td>${i.duration}</td>
<td>${i.distance}</td>
<td></td>
</tr>`;
})
});
}

View File

@ -0,0 +1,51 @@
export function createItinerary() {
if (!document.getElementById('case-filter').value) {
return;
}
let date = document.getElementById('date');
date.value = new Date().toLocaleDateString();
let btn = document.getElementById('create-itinerary');
btn.setAttribute('data-bs-toggle', 'modal');
btn.setAttribute('data-bs-target', '#exampleModalMessage');
btn.click();
}
export function addLocationToItinerary() {
let date = document.getElementById('date').value;
let origin = document.getElementById('origin').value;
let destination = document.getElementById('destination').value;
let departure = document.getElementById('departure').value;
let caseMileage = document.getElementById('case-mileage').checked;
let caseId = document.getElementById('case-filter').value;
fetch('/api/add-location-to-itinerary', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
caseId: caseId,
date: date,
origin: origin,
destination: destination,
departure: departure,
caseMileage: caseMileage
})
})
.then(response => response.json())
.then(data => {
if (data.success === true) {
$('#close-modal').click();
}
});
}
export function openMap() {
document.getElementById('caseId').value = document.getElementById('case-filter').value;
document.getElementById('startDate').value = document.getElementById('start-date-filter').value;
document.getElementById('endDate').value = document.getElementById('end-date-filter').value;
document.getElementById('map-form').submit();
}

32
assets/js/app/message.js Normal file
View File

@ -0,0 +1,32 @@
export function messageSupervisor() {
let btn = document.getElementById('message-supervisor');
btn.setAttribute('data-bs-toggle', 'modal');
btn.setAttribute('data-bs-target', '#message-modal');
btn.click();
}
export function openMessage() {
let btn = document.getElementById('open-message');
btn.setAttribute('data-bs-toggle', 'modal');
btn.setAttribute('data-bs-target', '#message-modal');
btn.click();
}
export function sendMessage() {
fetch('/api/send-message', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
case: document.getElementById('my-cases').value,
message: document.getElementById('message').value
})
})
.then(response => response.json())
.then(data => {
if (data.success === true) {
$('#close-modal').click();
}
});
}

91
assets/js/app/notes.js Normal file
View File

@ -0,0 +1,91 @@
export function filterNotes()
{
let referralId = document.getElementById('referralList').value;
let startDate = document.getElementById('startDate').value;
let endDate = document.getElementById('endDate').value;
let caseId = null;
if (referralId.substr(0, 5) == 'case-') {
caseId = referralId.substr(5);
referralId = null;
}
fetch('/api/filter-notes', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
'referral': referralId,
'startDate': startDate,
'endDate': endDate,
'case': caseId
})
})
.then(response => response.json())
.then(data => {
const noteList = document.getElementById('note-list');
noteList.innerHTML = '';
data.forEach(i => {
let duration = (parseInt(i.duration) / 60).toFixed(2);
noteList.innerHTML += `
<tr>
<td>${i.date}<br/>
${i.startTime}-${i.endTime} (${duration})</td>
<td class='text-center'>${i.location}</td>
<td class='text-center'>${i.method}</td>
<td'>${i.members}</td>
<td style='text-align: right;'>
<a href='/edit-note/${i.noteType}/${i.id}' class='text-secondary' title='Edit Note'>
<i class="material-symbols-rounded opacity-5">edit</i>
</a>
</td>
</tr>`;
})
});
}
export function calcTime(precision = 15) {
if (!document.getElementById('note_form_startTime').value || !document.getElementById('note_form_endTime').value) {
console.log('ending');
return;
}
let st = document.getElementById('note_form_startTime').value.split(':');
let et = document.getElementById('note_form_endTime').value.split(':');
let sd = new Date();
let ed = new Date();
sd.setHours(st[0]);
sd.setMinutes(st[1]);
sd.setSeconds(0);
ed.setHours(et[0]);
ed.setMinutes(et[1]);
ed.setSeconds(0);
let timediff = (ed.getTime() - sd.getTime()) / 1000;
let increments = (timediff / 60) / precision;
if (isFloat(increments)) {
let mod = (timediff / 60) % precision;
if (mod >= (precision / 2)) {
increments++;
}
increments = parseInt(increments);
}
document.getElementById('case-mins').value = (increments * precision)+' minutes';
document.getElementById('case-hours').value = ((increments * precision) / 60)+' hours';
}
export function autosaveNote()
{
}
export function checkNotes() {
}

21
assets/js/app/user.js Normal file
View File

@ -0,0 +1,21 @@
export function createSignatureBlock() {
pad = new SignaturePad(document.getElementById('signature_pad'));
const ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext("2d").scale(ratio, ratio);
//pad.clear(); // otherwise isEmpty() might return incorrect value
}
export function clearSignatureBlock() {
//const pad = new SignaturePad(document.getElementById('signature_pad'));
pad.clear();
}
export function saveSignatureBlock() {
//const pad = new SignaturePad(document.getElementById('signature_pad'));
const data = pad.toData();
document.getElementById('signature').value = data;
return true;
}

File diff suppressed because one or more lines are too long

View File

@ -8,3 +8,7 @@
color: white;
font-size: 6pt;
}
a {
text-decoration: none !important;
}

View File

@ -14,6 +14,7 @@
"doctrine/orm": "^3.3",
"phpdocumentor/reflection-docblock": "^5.4",
"phpstan/phpdoc-parser": "^1.33",
"symfony-cmf/slugifier-api": "^2.1",
"symfony/asset": "7.2.*",
"symfony/asset-mapper": "7.2.*",
"symfony/console": "7.2.*",
@ -47,7 +48,8 @@
"symfony/yaml": "7.2.*",
"twig/extra-bundle": "^2.12|^3.0",
"twig/intl-extra": "^3.15",
"twig/twig": "^2.12|^3.0"
"twig/twig": "^2.12|^3.0",
"vich/uploader-bundle": "^2.5"
},
"config": {
"allow-plugins": {
@ -100,8 +102,12 @@
}
},
"require-dev": {
"ext-dom": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"doctrine/doctrine-fixtures-bundle": "^4.0",
"fakerphp/faker": "^1.24",
"phpstan/phpstan": "^2.1",
"phpunit/phpunit": "^9.5",
"symfony/browser-kit": "7.2.*",
"symfony/css-selector": "7.2.*",

View File

@ -14,4 +14,5 @@ return [
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
Symfony\UX\Map\UXMapBundle::class => ['all' => true],
Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true],
];

View File

@ -7,21 +7,32 @@ security:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
class: App\Entity\System\User
property: username
# used to reload user from session & other features (e.g. switch_user)
firewalls:
profile_images:
pattern: ^/uploads/user_images/
security: false
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
pattern:
- ^/_profiler
- ^/_wdt
- ^/css
- ^/images
- ^/js
- ^/uploads
- ^/favicon.ico
security: false
main:
lazy: true
provider: app_user_provider
user_checker: App\Security\UserChecker
form_login:
login_path: app_login
check_path: app_login
enable_csrf: false
default_target_path: /dashboard
default_target_path: app_dashboard
logout:
path: app_logout
# where to redirect after logout

View File

@ -1,5 +1,10 @@
twig:
file_name_pattern: '*.twig'
globals:
mileage_rate: '%env(MILEAGE_RATE)%'
company_timezone: '%env(COMPANY_TIMEZONE)%'
company_image_path: '%env(COMPANY_IMAGE_PATH)%'
user_image_path: '%env(USER_IMAGE_PATH)%'
when@test:
twig:

View File

@ -0,0 +1,20 @@
vich_uploader:
db_driver: orm
metadata:
auto_detection: true
cache: file
type: attribute
mappings:
imageName:
uri_prefix: "%app.path.imageName%"
upload_destination: "%kernel.project_dir%/public/upload/user/profiles"
namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
inject_on_load: false
delete_on_update: true
delete_on_remove: true
#mappings:
# products:
# uri_prefix: /images/products
# upload_destination: '%kernel.project_dir%/public/images/products'
# namer: Vich\UploaderBundle\Naming\SmartUniqueNamer

View File

@ -4,6 +4,7 @@
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters:
app.path.imageName: /upload/user/profiles
services:
# default configuration for services in *this* file

View File

@ -16,12 +16,18 @@ return [
'path' => './assets/app.js',
'entrypoint' => true,
],
'@hotwired/stimulus' => [
'version' => '3.2.2',
],
'@symfony/stimulus-bundle' => [
'path' => './vendor/symfony/stimulus-bundle/assets/dist/loader.js',
],
'@symfony/ux-leaflet-map' => [
'path' => './vendor/symfony/ux-leaflet-map/assets/dist/map_controller.js',
],
'jquery' => [
'version' => '3.7.1',
],
'@hotwired/stimulus' => [
'version' => '3.2.2',
],
'leaflet' => [
'version' => '1.9.4',
],
@ -29,7 +35,60 @@ return [
'version' => '1.9.4',
'type' => 'css',
],
'@symfony/ux-leaflet-map' => [
'path' => './vendor/symfony/ux-leaflet-map/assets/dist/map_controller.js',
'bootstrap' => [
'version' => '5.3.3',
],
'@popperjs/core' => [
'version' => '2.11.8',
],
'bootstrap/dist/css/bootstrap.min.css' => [
'version' => '5.3.3',
'type' => 'css',
],
'perfect-scrollbar' => [
'version' => '1.5.6',
],
'perfect-scrollbar/css/perfect-scrollbar.min.css' => [
'version' => '1.5.6',
'type' => 'css',
],
'smooth-scrollbar' => [
'version' => '8.8.4',
],
'tslib' => [
'version' => '2.8.1',
],
'core-js/es/map' => [
'version' => '3.39.0',
],
'core-js/es/set' => [
'version' => '3.39.0',
],
'core-js/es/weak-map' => [
'version' => '3.39.0',
],
'core-js/es/array/from' => [
'version' => '3.39.0',
],
'core-js/es/object/assign' => [
'version' => '3.39.0',
],
'notify.js' => [
'version' => '0.0.3',
],
'underscore' => [
'version' => '1.5.2',
],
'chartjs' => [
'version' => '0.3.24',
],
'signature_pad' => [
'version' => '5.0.4',
],
'tinymce' => [
'version' => '7.6.0',
],
'moment' => [
'version' => '2.30.1',
],
];

1
public/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
uploads

View File

@ -2,6 +2,16 @@
use App\Kernel;
if (preg_match("/theme\//", $_SERVER['REQUEST_URI'])) {
print file_get_contents(dirname(__FILE__).$_SERVER['REQUEST_URI']);
exit;
}
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
$_SERVER['HTTPS'] = 'on';
$_SERVER['SERVER_PORT'] = 443;
}
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
return function (array $context) {

View File

@ -1,17 +1,19 @@
<?php
namespace App\Controller;
namespace App\Controller\Admin;
use App\Entity\Messages;
use App\Entity\Supervision;
use App\Entity\User;
use App\Entity\Staff\Supervision;
use App\Entity\System\User;
use App\Factory\MessageFactory;
use App\Form\EditUserFormType;
use App\Form\SupervisorFormType;
use App\Form\UserFormType;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use App\Libs\Libs;
use App\Repository\UserRepository;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
@ -20,18 +22,15 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Component\String\Slugger\SluggerInterface;
#[IsGranted('ROLE_ADMIN')]
class AdminController extends AbstractController
{
private array $msgs;
private int $notificationCount = 0;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly UserPasswordHasherInterface $userPasswordHasher,
private array $navLinks = []
private array $navLinks = [],
) {
$this->navLinks = NavList::LIST;
}
@ -41,8 +40,6 @@ class AdminController extends AbstractController
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->navLinks['admin_dashboard'] = NavList::PRESENT_LINK;
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
return $this->render(
'internal/admin/admin-dashboard.html.twig',
@ -52,8 +49,7 @@ class AdminController extends AbstractController
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_admin_dashboard'), 'Admin Dashboard')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
@ -63,8 +59,6 @@ class AdminController extends AbstractController
public function listUsers(#[CurrentUser()] User $user): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
/** @var UserRepository $repo */
$repo = $this->entityManager->getRepository(User::class);
@ -88,19 +82,19 @@ class AdminController extends AbstractController
new Breadcrumb($this->generateUrl('app_list_users'), 'List Users')
],
'users' => $users,
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
}
#[Route('/add-user', name: 'app_add_user')]
public function addUser(Request $request, #[CurrentUser()] User $admin): Response
{
public function addUser(
Request $request,
#[CurrentUser()] User $admin,
SluggerInterface $slugger
): Response {
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($admin);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($admin);
$user = new User();
$form = $this->createForm(UserFormType::class, $user);
@ -140,8 +134,24 @@ class AdminController extends AbstractController
->setRateType($form->get('rateType')->getData())
->setRate($form->get('rate')->getData())
->setLevel($form->get('level')->getData())
->setCompany($admin->getCompany());
->setCompany($admin->getCompany())
->setActive(true)
->setPasswordChanged(new DateTime('1970-01-01 00:00:00', new DateTimeZone($_ENV['COMPANY_TIMEZONE'])))
;
if ($form->get('imageName')->getData()) {
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $form['imageName']->getData();
$destination = $this->getParameter('kernel.project_dir').'/public/uploads/user_images/';
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$newFilename = $slugger->slug($originalFilename).'-'.uniqid().'.'.$file->guessExtension();
$file->move(
$destination,
$newFilename
);
$user->setImageName($newFilename);
}
$msg = MessageFactory::createUser($admin, $user, 'Welcome', "Welcome to CM Tracker");
@ -166,8 +176,7 @@ class AdminController extends AbstractController
new Breadcrumb($this->generateUrl('app_add_user'), 'Add User')
],
'form' => $form,
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($admin, $this->entityManager),
]
)
);
@ -178,8 +187,6 @@ class AdminController extends AbstractController
{
/** @var UserRepository $userRepo */
$userRepo = $this->entityManager->getRepository(User::class);
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($admin);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($admin);
/** @var User $user */
$user = $userRepo->find($id);
@ -190,15 +197,31 @@ class AdminController extends AbstractController
$this->navLinks['user_list'] = NavList::PRESENT_LINK;
if ($form->isSubmitted() && $form->isValid()) {
$roles = ['ROLE_USER'];
if ($form->get('caseWorker')->getData()) {
$roles[] = 'ROLE_CASE_WORKER';
}
if ($form->get('caseManager')->getData()) {
$roles[] = 'ROLE_CASE_MANAGER';
}
if ($form->get('therapist')->getData()) {
$roles[] = 'ROLE_THERAPIST';
}
if ($form->get('su')->getData()) {
$roles[] = 'ROLE_ADMIN';
}
$user->setName($form->get('name')->getData())
->setEmail($form->get('email')->getData())
->setCaseWorker($form->get('caseWorker')->getData())
->setCaseManager($form->get('caseManager')->getData())
->setTherapist($form->get('therapist')->getData())
->setSu($form->get('su')->getData())
->setRoles($roles)
->setActive((bool) $form->get('active')->getData())
->setRateType($form->get('rateType')->getData())
->setRate($form->get('rate')->getData())
->setLevel($form->get('level')->getData());
->setLevel($form->get('level')->getData())
;
$this->entityManager->flush();
@ -216,8 +239,7 @@ class AdminController extends AbstractController
],
'data' => $user,
'form' => $form,
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($admin, $this->entityManager),
]
)
);
@ -228,32 +250,35 @@ class AdminController extends AbstractController
{
/** @var UserRepository $userRepo */
$userRepo = $this->entityManager->getRepository(User::class);
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($admin);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($admin);
/** @var User $user */
$user = $userRepo->find($id);
$prevSup = $this->entityManager->getRepository(Supervision::class)->findBy(['worker' => $user]);
$prevSup = $this->entityManager->getRepository(Supervision::class)->findOneBy(['worker' => $user]);
$form = $this->createForm(SupervisorFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var User $supervisor */
$supervisor = $form->get('supervisor')->getData();
if (count($prevSup) > 0) {
$this->entityManager->remove($prevSup[0]);
if ($prevSup) {
$prevSup->setSupervisor($supervisor);
$this->entityManager->persist($prevSup);
$this->entityManager->flush();
}
$this->addFlash('success', "Supervisor updated for {$user->getName()}");
} else {
$sup = new Supervision();
$sup->setSupervisor($supervisor);
$sup->setWorker($user);
$sup->setSupervisor($supervisor);
$this->entityManager->persist($sup);
$this->entityManager->flush();
$this->addFlash('success', "Supervisor assigned to {$user->getName()}");
}
$supMsg = MessageFactory::createUser($admin, $supervisor, 'New Case Worker', "You've been assigned a new case worker, {$user->getName()}");
$userMsg = MessageFactory::createUser($admin, $user, 'New Staff Supervisor', "You've been assigned a new staff supervisor {$supervisor->getName()}");
$this->entityManager->persist($sup);
$this->entityManager->persist($userMsg);
$this->entityManager->persist($supMsg);
$this->entityManager->flush();
@ -273,8 +298,7 @@ class AdminController extends AbstractController
'user' => $user,
'form' => $form,
'supervisors' => $userRepo->getCaseManagers($admin->getCompany()),
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($admin, $this->entityManager),
]
)
);

View File

@ -0,0 +1,420 @@
<?php
namespace App\Controller\Case;
use App\Entity\Case\CaseLocation;
use App\Entity\Company\CompanyDocument;
use App\Entity\Case\Member;
use App\Entity\Case\MemberCase;
use App\Entity\System\Location;
use App\Entity\System\ReferralSource;
use App\Entity\System\User;
use App\Entity\System\UserCase;
use App\Factory\MessageFactory;
use App\Form\CaseDocumentFormType;
use App\Form\LocationFormType;
use App\Form\MemberCaseFormType;
use App\Form\UserCaseFormType;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class CaseController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = []
) {
$this->navLinks = NavList::LIST;
$this->navLinks['case_list'] = NavList::PRESENT_LINK;
}
#[Route('/my-cases', name: 'app_my_cases')]
public function myCases(#[CurrentUser()] User $user, Request $request): Response
{
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$this->navLinks['my_cases'] = NavList::PRESENT_LINK;
$this->navLinks['case_list'] = NavList::DEFAULT;
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$cases = [];
foreach ($ucs as $uc) {
/** @var UserCase $uc */
$cases[] = $uc->getMemberCase();
}
return $this->render(
'internal/cases/my-cases.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
(
strpos($request->server->get('HTTP_REFERER'), 'list-cases') !== false
? new Breadcrumb($this->generateUrl('app_list_cases'), 'Cases')
: new Breadcrumb($this->generateUrl('app_my_cases'), 'My Cases')
),
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'cases' => $cases,
]
)
);
}
#[Route('/list-cases', name: 'app_list_cases')]
public function listCases(#[CurrentUser()] User $user): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$cases = $this->entityManager->getRepository(MemberCase::class)->findAll();
$workers = $this->entityManager->getRepository(User::class)->getCaseWorkers();
return $this->render(
'internal/admin/cases/list-cases.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases')
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'cases' => $cases,
'workers' => $workers,
]
)
);
}
#[Route('/case/{caseId}', name: 'app_view_case')]
public function showCase(Request $request, #[CurrentUser()] User $user, string $caseId): Response
{
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
/** @todo validate user has access to case, check for admin, case manager of case worker */
if (!Libs::checkPermissions($user, $case, $this->entityManager)) {
throw new AccessDeniedException();
}
$sources = $this->entityManager->getRepository(ReferralSource::class)->findAll();
return $this->render(
'internal/cases/view-case.html.twig',
array_merge(
$this->navLinks,
[
'case' => $case,
'sources' => $sources,
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'Cases'),
new Breadcrumb($this->generateUrl('app_view_case', ['caseId' => $case->getId()]), 'View Case')
],
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
}
#[Route('/add-case', name: 'app_add_case')]
public function addCase(Request $request, #[CurrentUser()] User $admin): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$case = new MemberCase();
$form = $this->createForm(MemberCaseFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$case = $form->getData();
$this->entityManager->persist($case);
$this->entityManager->flush();
$this->addFlash('success', 'Case added successfully');
return $this->redirectToRoute('app_list_cases');
}
return $this->render(
'internal/admin/cases/add-case.html.twig',
array_merge(
$this->navLinks,
[
'title' => 'Add Case',
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_add_case'), 'Add Case')
],
'notifications' => Libs::getMessages($admin, $this->entityManager),
'form' => $form,
'sources' => $this->entityManager->getRepository(ReferralSource::class)->retrieveOrderedList(),
]
)
);
}
#[Route('/edit-case/{id}', name: 'app_edit_case')]
public function editCase(Request $request, #[CurrentUser()] User $admin, string $id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
$form = $this->createForm(MemberCaseFormType::class, $case);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$case = $form->getData();
$this->entityManager->flush();
$this->addFlash('success', 'Case updated successfully');
return $this->redirectToRoute('app_list_cases');
}
return $this->render(
'internal/admin/cases/edit-case.html.twig',
array_merge(
$this->navLinks,
[
'title' => 'Edit Case',
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_edit_case', ['id' => $id]), 'Edit Case')
],
'notifications' => Libs::getMessages($admin, $this->entityManager),
'form' => $form,
'case' => $case,
'sources' => $this->entityManager->getRepository(ReferralSource::class)->retrieveOrderedList(),
]
)
);
}
#[Route('/assign-case/{id}', name: 'app_assign_case')]
public function assignCase(string $id, Request $request, #[CurrentUser()] User $admin): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$caseWorkers = $this->entityManager->getRepository(User::class)->getCaseWorkers();
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
$prevUc = $this->entityManager->getRepository(UserCase::class)->findBy(['memberCase' => $case]);
$uc = new UserCase();
$form = $this->createForm(UserCaseFormType::class, $uc);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $form->get('user')->getData();
$uc = $form->getData();
$uc->setMemberCase($case);
$uc->setUser($user);
if (count($prevUc) > 0) {
$this->entityManager->remove($prevUc[0]);
$this->entityManager->flush();
}
$msg = MessageFactory::createNewCase(
$admin,
$user,
$this->generateUrl('app_view_case', ['caseId' => $case->getId()->toString()])
);
$this->entityManager->persist($uc);
$this->entityManager->persist($msg);
$this->entityManager->flush();
$this->addFlash('success', 'Case assigned successfully');
return $this->redirectToRoute('app_list_cases');
}
return $this->render(
'internal/admin/cases/assign-case.html.twig',
array_merge(
$this->navLinks,
[
'title' => 'Assign Case',
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_assign_case', ['id' => $id]), 'Assign User')
],
'notifications' => Libs::getMessages($admin, $this->entityManager),
'case' => $case,
'form' => $form,
'id' => $id,
'caseWorkers' => $caseWorkers,
'assignedWorkerId' => (count($case->getUserCases()) > 0 ? $case->getUserCases()->first()->getUser()->getId() : null),
]
)
);
}
#[Route('/addresses/list', name: 'app_list_case_addresses')]
public function listCaseAddresses(Request $request, #[CurrentUser()] User $user): Response
{
$this->navLinks['case_itinerary'] = NavList::PRESENT_LINK;
$this->navLinks['case_list'] = 'nav-link text-dark';
$addresses = $this->entityManager->getRepository(Location::class)->getUserLocations($user);
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$cases = [];
foreach ($ucs as $uc) {
/** @var UserCase $uc */
$cases[] = $uc->getMemberCase();
}
return $this->render(
'internal/cases/addresses/list-case-addresses.html.twig',
array_merge(
$this->navLinks,
[
'title' => 'List Case Addresses',
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_my_cases'), 'My Cases'),
new Breadcrumb($this->generateUrl('app_list_case_addresses'), 'List Case Addresses')
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'addresses' => $addresses,
'cases' => $cases,
]
)
);
}
#[Route('/addresses/add', name: 'app_case_add_address')]
public function addCaseAddress(Request $request, #[CurrentUser()] User $user): Response
{
$this->navLinks['case_itinerary'] = NavList::PRESENT_LINK;
$this->navLinks['case_list'] = 'nav-link text-dark';
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$cases = [];
foreach ($ucs as $uc) {
/** @var UserCase $uc */
$cases[] = $uc->getMemberCase();
}
$address = new Location();
$form = $this->createForm(LocationFormType::class, $address);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var Location $address */
$address = $form->getData();
foreach ($request->get('cases') as $caseId) {
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
$cl = new CaseLocation();
$cl->setMemberCase($case)
->setLocation($address);
$this->entityManager->persist($cl);
}
list($lat, $lon) = Libs::getLatLonFromGeoapify((string) $address);
$address->setLat($lat)
->setLon($lon);
//dd($address);
$this->entityManager->persist($address);
$this->entityManager->flush();
$this->addFlash('success', 'Address added successfully');
return $this->redirectToRoute('app_list_case_addresses');
}
return $this->render(
'internal/cases/addresses/add-case-address.html.twig',
array_merge(
$this->navLinks,
[
'title' => 'Add Case Address',
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_case_addresses'), 'List Addresses'),
new Breadcrumb($this->generateUrl('app_case_add_address'), 'Add Case Address')
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'form' => $form,
'cases' => $cases,
]
)
);
}
#[Route('/addresses/edit/{id}', name: 'app_case_edit_address')]
public function editCaseAddress(Request $request, string $id, #[CurrentUser()] User $user): Response
{
$this->navLinks['case_itinerary'] = NavList::PRESENT_LINK;
$this->navLinks['case_list'] = 'nav-link text-dark';
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $this->getUser()]);
$lcs = $this->entityManager->getRepository(CaseLocation::class)->findBy(['location' => $id]);
$inCases = [];
foreach ($lcs as $lc) {
$inCases[] = $lc->getMemberCase()->getId()->toString();
}
$cases = [];
foreach ($ucs as $uc) {
/** @var UserCase $uc */
$cases[] = $uc->getMemberCase();
}
$location = $this->entityManager->getRepository(Location::class)->find($id);
$form = $this->createForm(LocationFormType::class, $location);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
list($lat, $lon) = Libs::getLatLonFromGeoapify((string) $location);
$location->setLat($lat)
->setLon($lon);
$this->entityManager->flush();
$this->addFlash('success', 'Address updated successfully');
return $this->redirectToRoute('app_list_case_addresses');
}
return $this->render(
'internal/cases/addresses/edit-case-address.html.twig',
array_merge(
$this->navLinks,
[
'title' => 'Edit Case Address',
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_case_addresses'), 'List Case Addresses'),
new Breadcrumb($this->generateUrl('app_case_edit_address', ['id' => $id]), 'Edit Case Address')
],
'location' => $location,
'cases' => $cases,
'inCases' => $inCases,
'form' => $form,
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Controller\Case;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
class GeoapifyController extends AbstractController
{
#[Route('/api/autocomplete-address/{searchText}', name: 'app_api_autocomplete_address')]
public function autocompleteAddress(string $searchText): Response
{
$params = [
'text' => $searchText,
'format' => 'json',
'apiKey' => $_ENV['GEOAPIFY_API_KEY']
];
$url = "https://api.geoapify.com/v1/autocomplete?".http_build_query($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$result = curl_exec($ch);
curl_close($ch);
return $this->json($result);
}
}

View File

@ -0,0 +1,161 @@
<?php
namespace App\Controller\Case;
use App\Entity\Case\CaseItinerary;
use App\Entity\Case\MemberCase;;
use App\Entity\System\User;
use App\Entity\System\UserCase;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
use App\Libs\NavList;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\UX\Map\InfoWindow;
use Symfony\UX\Map\Map;
use Symfony\UX\Map\Marker;
use Symfony\UX\Map\Point;
use Symfony\UX\Map\Polyline;
class ItineraryController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = []
) {
$this->navLinks = NavList::LIST;
}
#[Route('/itinerary/report', name: 'app_report_itinerary')]
public function reportItinerary(Request $request, #[CurrentUser()] ?User $user): Response
{
$this->navLinks['case_itinerary'] = NavList::PRESENT_LINK;
$itineraries = $this->entityManager->getRepository(CaseItinerary::class)->getRecentTravel(
$user
);
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$cases = [];
foreach ($ucs as $uc) {
/** @var UserCase $uc */
$cases[] = $uc->getMemberCase();
}
return $this->render(
'internal/cases/itinerary/report.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_dashboard'), 'Dashboard'),
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'itineraries' => $itineraries,
'cases' => $cases
]
)
);
}
#[Route('/itinerary/map', name: 'app_map_itinerary')]
public function mapItinerary(Request $request, #[CurrentUser()] ?User $user): Response
{
$this->navLinks['case_itinerary'] = NavList::PRESENT_LINK;
$case = null;
if ($request->getPayload()->get('caseId')) {
$case = $this->entityManager->getRepository(MemberCase::class)->find($request->getPayload()->get('caseId'));
}
$startDate = (
$request->getPayload()->get('startDate')
?
new DateTime($request->getPayload()->get('startDate'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']))
:
null);
$endDate = (
$request->getPayload()->get('endDate')
?
new DateTime($request->getPayload()->get('endDate'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']))
:
null);
$itineraries = $this->entityManager->getRepository(CaseItinerary::class)->getRecentTravel($user, [
'case' => $case,
'from' => $startDate,
'to' => $endDate,
]);
$map = new Map('default');
$map->center(new Point($_ENV['MAP_CENTER_LAT'], $_ENV['MAP_CENTER_LON']))
->zoom($_ENV['MAP_ZOOM_LEVEL'])
;
$total_distance = 0;
$total_duration = new DateTime('00:00:00');
foreach ($itineraries as $itinerary) {
/** @var CaseItinerary $itinerary */
$map->addMarker(new Marker(
position: new Point(
$itinerary->getOriginLocation()->getLat(),
$itinerary->getOriginLocation()->getLon()
),
title: $itinerary->getOriginLocation()->getName(),
infoWindow: new InfoWindow(
content: $itinerary->originInfoWindow(),
)
));
$map->addMarker(new Marker(
position: new Point(
$itinerary->getDestLocation()->getLat(),
$itinerary->getDestLocation()->getLon()
),
title: $itinerary->getDestLocation()->getName(),
infoWindow: new InfoWindow(
content: $itinerary->destinationInfoWindow(),
)
));
/** @var CaseItinerary $itinerary */
$map->addPolyline(new Polyline(
points: $itinerary->getGPSPolyLines(),
infoWindow: new InfoWindow(
content: $itinerary->getMemberCase()->getCaseName()
),
extra: ['color' => '#FF0000']
));
$total_distance += $itinerary->getDistance();
$total_duration->add($itinerary->getDuration());
}
$map->fitBoundsToMarkers(true);
$diff = new DateTime('00:00:00');
$di = $diff->diff($total_duration);
return $this->render(
'internal/cases/itinerary/map.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_my_cases'), 'My Cases'),
new Breadcrumb($this->generateUrl('app_report_itinerary'), 'Itinerary Report'),
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'map' => $map,
'total_distance' => $total_distance,
'total_duration' => $di->format("%H:%i'%s''"),
]
)
);
}
}

View File

@ -0,0 +1,210 @@
<?php
namespace App\Controller\Case;
use App\Entity\Company\CompanyDocument;
use App\Entity\Case\Member;
use App\Entity\Case\MemberCase;;
use App\Entity\Case\MemberDocument;
use App\Entity\System\User;
use App\Entity\System\UserCase;
use App\Form\MemberFormType;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class MemberController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = [],
) {
$this->navLinks = NavList::LIST;
$this->navLinks['case_list'] = NavList::PRESENT_LINK;
}
#[Route('/list-members/{id}', name: 'app_case_members')]
public function listMembers(Request $request, #[CurrentUser()] User $user, string $id): Response
{
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
$members = $this->entityManager->getRepository(Member::class)->getCaseMembersByName($case);
return $this->render(
'internal/cases/members/list-members.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $id]), 'List Members'),
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'case' => $case,
'members' => $members,
]
)
);
}
#[Route('/add-member/{id}', name: 'app_case_add_member')]
public function addMember(Request $request, #[CurrentUser()] User $user, string $id): Response
{
/** @var MemberCase $case */
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
/** @var UserCase $userCase */
$userCase = $this->entityManager->getRepository(UserCase::class)->findOneBy(['memberCase' => $case]);
/** @var User $caseWorker */
$caseWorker = $userCase->getUser();
/** @var array $docs<int, CompanyDocuments> */
$docs = $this->entityManager->getRepository(CompanyDocument::class)->findBy(['company' => $user->getCompany()], ['title' => 'ASC']);
$member = new Member();
$form = $this->createForm(MemberFormType::class, $member, ['docs' => $docs]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$member = $form->getData();
$member->setCaseId($case)
->setChild(($form->get('isChild') ? true : false))
->setParent(($form->get('isParent') ? true : false))
->setAdultChild(($form->get('isAdultChild') ? true : false))
->setLegalGuardian(($form->get('isLegalGuardian') ? true : false))
->setParentsLiveTogether(($form->get('parentsLiveTogether') ? true : false))
->setDcsApproved(($form->get('dcsApproved') ? true : false))
;
$this->entityManager->persist($member);
$this->entityManager->flush();
$selectedDocs = $form->get('docs');
foreach ($selectedDocs->getData() as $doc) {
$dbDoc = $this->entityManager->getRepository(CompanyDocument::class)->find($doc);
if (!$dbDoc) {
continue;
}
$md = new MemberDocument();
$md->setClient($member)
->setDocument($dbDoc)
->setCaseWorker($caseWorker)
;
$this->entityManager->persist($md);
$this->entityManager->flush();
}
$this->addFlash(
'success',
'Member added successfully'
);
return $this->redirectToRoute('app_case_members', ['id' => $case->getId()]);
}
return $this->render(
'internal/cases/members/add-member.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $id]), 'List Members'),
new Breadcrumb($this->generateUrl('app_case_add_member', ['id' => $id]), 'Add Member'),
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'case' => $case,
'form' => $form->createView(),
'docs' => $docs,
]
)
);
}
#[Route('/case/{caseId}/edit-member/{memberId}', name: 'app_case_edit_member')]
public function editMember(Request $request, #[CurrentUser()] User $user, string $caseId, string $memberId): Response
{
/** @var Member $member */
$member = $this->entityManager->getRepository(Member::class)->find($memberId);
/** @var MemberCase $case */
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
/** @var array<int, CompanyDocuments> $docs */
$docs = $this->entityManager->getRepository(CompanyDocument::class)->findBy(['company' => $user->getCompany()], ['title' => 'ASC']);
/** @var array<int, MemberDocument> $memberDocs */
$memberDocs = $this->entityManager->getRepository(MemberDocument::class)->findBy(['client' => $member]);
$memberDbDocs = [];
foreach($memberDocs as $md) {
$memberDbDocs[] = $md->getDocument()->getId()->toString();
}
foreach ($docs as $idx => $d) {
if (in_array($d->getId()->toString(), $memberDbDocs)) {
$docs[$idx]->setSelected();
}
}
$form = $this->createForm(MemberFormType::class, $member, ['docs' => $docs]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$member = $form->getData();
$member->setChild(($form->get('isChild') ? true : false))
->setParent(($form->get('isParent') ? true : false))
->setAdultChild(($form->get('isAdultChild') ? true : false))
->setLegalGuardian(($form->get('isLegalGuardian') ? true : false))
->setParentsLiveTogether(($form->get('parentsLiveTogether') ? true : false))
->setDcsApproved(($form->get('dcsApproved') ? true : false))
;
$this->entityManager->getRepository(MemberDocument::class)->removeUnsigned($member);
$selectedDocs = $form->get('docs')->getData();
foreach ($selectedDocs as $d) {
$md = new MemberDocument();
$md->setClient($member)
->setCaseWorker($user)
->setDocument($d)
;
$this->entityManager->persist($md);
$this->entityManager->flush();
}
$this->entityManager->flush();
$this->addFlash(
'success',
'Member updated successfully'
);
return $this->redirectToRoute('app_case_members', ['id' => $caseId]);
}
return $this->render(
'internal/cases/members/edit-member.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'Cases'),
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $caseId]), 'Members'),
new Breadcrumb($this->generateUrl('app_case_edit_member', ['caseId' => $caseId, 'memberId' => $memberId]), 'Edit Member'),
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'member' => $member,
'form' => $form->createView(),
'caseId' => $caseId,
'docs' => $docs,
'selectedDocs' => $memberDbDocs,
]
)
);
}
}

View File

@ -0,0 +1,203 @@
<?php
namespace App\Controller\Case;
use App\Entity\Case\Member;
use App\Entity\Case\MemberCase;;
use App\Entity\Case\Referral;
use App\Entity\Case\StandardNote;
use App\Entity\Case\StandardNoteMember;
use App\Entity\System\User;
use App\Entity\System\UserCase;
use App\Entity\Case\VisitNote;
use App\Entity\Case\VisitNoteMembers;
use App\Enums\Case\NoteLocation;
use App\Enums\Case\NoteMethod;
use App\Enums\Case\ReferralServiceType;
use App\Form\StandardNoteFormType;
use App\Form\VisitNoteFormType;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class NoteController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = [],
) {
$this->navLinks = NavList::LIST;
$this->navLinks['case_notes'] = NavList::PRESENT_LINK;
}
#[Route('/list-notes/{caseId?null}', name: 'app_list_notes')]
public function listNotes(string $caseId = null, #[CurrentUser()] User $user, Request $request): Response
{
/** @var UserCase[] $cases */
$cases = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$caseNotes = null;
$case = null;
if ($caseId != 'null') {
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
$params = [
'case' => $case,
'referral' => null,
'startDate' => null,
'endDate' => null,
];
$caseNotes = array_merge(
$this->entityManager->getRepository(VisitNote::class)->filterNotes($user, $params),
$this->entityManager->getRepository(StandardNote::class)->filterNotes($user, $params),
);
}
return $this->render(
'internal/cases/notes/list-notes.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_notes'), 'List Notes')
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'cases' => $cases,
'caseNotes' => $caseNotes,
'case' => $case,
]
)
);
}
#[Route('/add-note/{referralId}', name: 'app_add_note')]
public function addNote(#[CurrentUser()] User $user, Request $request, ?string $referralId = null): Response
{
if (substr($referralId, 0, 4) == 'case') {
throw $this->createNotFoundException('Select Referral from dropdown');
}
/** @var Referral $referral */
$referral = $this->entityManager->getRepository(Referral::class)->find($referralId);
$this->entityManager->getRepository(Referral::class)->populateNotes($referral);
$members = $this->entityManager->getRepository(Member::class)->findBy(['memberCase' => $referral->getMemberCase()]);
$defaultMethod = NoteMethod::BILLABLE;
$defaultLocation = NoteLocation::COMMUNITY_OUTING;
$form = $this->createForm(StandardNoteFormType::class, null, ['members' => $members]);
$template = 'internal/cases/notes/add-standard-note.html.twig';
if ($referralId == 'null') {
$referralId = null;
}
if ($referral->getServiceCode() == ReferralServiceType::VS_THBB) {
$form = $this->createForm(VisitNoteFormType::class, null, ['members' => $members]);
$template = 'internal/cases/notes/add-visit-note.html.twig';
$defaultMethod = NoteMethod::BILLABLE_SUPERVISED_VISIT;
} elseif ($referral->getServiceCode() == ReferralServiceType::VS_THBBT) {
$defaultMethod = NoteMethod::BILLABLE;
$defaultLocation = NoteLocation::VEHICLE_TRANSPORTATION;
}
$form = $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var VisitNote|StandardNote $note */
$note = $form->getData();
$note->setReferral($referral);
$this->entityManager->persist($note);
$this->entityManager->flush();
if ($form->get('members')->getData()) {
foreach ($form->get('members')->getData() as $mem) {
if ($referral->getServiceCode() == ReferralServiceType::VS_THBB) {
$nm = new VisitNoteMembers();
$nm->setVisitNote($note)
->setPerson($mem)
;
} else {
$nm = new StandardNoteMember();
$nm->setStandardNote($note)
->setPerson($mem)
;
}
$this->entityManager->persist($nm);
$this->entityManager->flush();
}
}
$this->addFlash('success', 'Note added successfully');
return $this->redirectToRoute('app_list_notes');
}
return $this->render(
$template,
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_notes'), 'List Notes')
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'referral' => $referral,
'form' => $form,
'members' => $members,
'default_method' => $defaultMethod,
'default_location' => $defaultLocation,
]
)
);
}
#[Route('/edit-note/{noteType}/{noteId}', name: 'app_edit_note')]
public function editNote(string $noteId, string $noteType, #[CurrentUser()] User $user, Request $request): Response
{
$form = null;
$members = [];
/** @var VisitNote|StandardNote $note */
if ($noteType == 'visit') {
/** @var VisitNote $note */
$note = $this->entityManager->getRepository(VisitNote::class)->find($noteId);
$members = $this->entityManager->getRepository(Member::class)->getMembersByCaseAndNote($note->getReferral()->getMemberCase(), $note);
$form = $this->createForm(VisitNoteFormType::class, $note, [
'members' => $members,
//'members' => $this->entityManager->getRepository(Member::class)->findBy(['memberCase' => $note->getReferral()->getMemberCase()])
]);
} elseif ($noteType == 'standard') {
$note = $this->entityManager->getRepository(StandardNote::class)->find($noteId);
$form = $this->createForm(StandardNoteFormType::class, $note, [
'members' => $members,
]);
}
return $this->render(
'internal/cases/notes/edit-note.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_notes'), 'List Notes')
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'note' => $note,
'referral' => $note->getReferral(),
'form' => $form,
'noteType' => $noteType,
'members' => $members,
]
)
);
}
}

View File

@ -1,15 +1,15 @@
<?php
namespace App\Controller;
namespace App\Controller\Case;
use App\Entity\MemberCase;
use App\Entity\Messages;
use App\Entity\Referral;
use App\Entity\User;
use App\Entity\UserCase;
use App\Entity\Case\MemberCase;;
use App\Entity\Case\Referral;
use App\Entity\System\User;
use App\Entity\System\UserCase;
use App\Factory\MessageFactory;
use App\Form\ReferralFormType;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -27,21 +27,22 @@ class ReferralController extends AbstractController
*/
private array $msgs;
private int $notificationCount;
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = []
) {
$this->navLinks = NavList::LIST;
if (strpos($_SERVER['HTTP_REFERER'], 'my-cases') !== false) {
$this->navLinks['my_cases'] = NavList::PRESENT_LINK;
} else {
$this->navLinks['case_list'] = NavList::PRESENT_LINK;
}
}
#[Route('/list-referrals/{id}', name: 'app_list_referrals')]
public function listReferrals(#[CurrentUser()] User $user, string $id): Response
public function listReferrals(#[CurrentUser()] User $user, string $id, Request $request): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
$openReferrals = $this->entityManager->getRepository(Referral::class)->getActiveReferrals($case);
@ -53,11 +54,14 @@ class ReferralController extends AbstractController
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
(
strpos($request->server->get('HTTP_REFERER'), 'my-cases') !== false
? new Breadcrumb($this->generateUrl('app_my_cases'), 'My Cases')
: new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases')
),
new Breadcrumb($this->generateUrl('app_list_referrals', ['id' => $case->getId()]), 'Referrals'),
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'case' => $case,
'openReferrals' => $openReferrals,
'closedReferrals' => $closedReferrals,
@ -70,8 +74,7 @@ class ReferralController extends AbstractController
public function addReferral(Request $request, #[CurrentUser()] User $user, string $id): Response
{
$this->denyAccessUnlessGranted(['ROLE_ADMIN', 'ROLE_CASE_MANAGER']);
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
/** @var UserCase $uc */
@ -106,7 +109,6 @@ class ReferralController extends AbstractController
new Breadcrumb($this->generateUrl('app_case_add_referral', ['id' => $case->getId()]), 'Add Referral')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'case' => $case,
'form' => $form,
]
@ -118,8 +120,6 @@ class ReferralController extends AbstractController
public function editReferral(Request $request, #[CurrentUser()] User $user, string $caseId, string $referralId): Response
{
$this->denyAccessUnlessGranted(['ROLE_ADMIN', 'ROLE_CASE_MANAGER']);
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$referral = $this->entityManager->getRepository(Referral::class)->find($referralId);
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
@ -150,8 +150,7 @@ class ReferralController extends AbstractController
new Breadcrumb($this->generateUrl('app_list_referrals', ['id' => $case->getId()]), 'Referrals'),
new Breadcrumb($this->generateUrl('app_case_edit_referral', ['caseId' => $case->getId(), 'referralId' => $referral->getId()]), 'Edit Referral'),
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($user, $this->entityManager),
'case' => $case,
'form' => $form,
'referral' => $referral,

View File

@ -1,285 +0,0 @@
<?php
namespace App\Controller;
use App\Entity\MemberCase;
use App\Entity\Messages;
use App\Entity\ReferralSource;
use App\Entity\User;
use App\Entity\UserCase;
use App\Factory\MessageFactory;
use App\Form\MemberCaseFormType;
use App\Form\UserCaseFormType;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class CaseController extends AbstractController
{
/**
* Variable to store unread notification messages
*
* @var array
*/
private array $msgs;
private int $notificationCount;
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = []
) {
$this->navLinks = NavList::LIST;
$this->navLinks['case_list'] = NavList::PRESENT_LINK;
}
#[Route('/my-cases', name: 'app_my_cases')]
public function myCases(#[CurrentUser()] User $user): Response
{
$this->navLinks['my_cases'] = NavList::PRESENT_LINK;
$this->navLinks['case_list'] = 'nav-link text-dark';
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$cases = [];
foreach ($ucs as $uc) {
/** @var UserCase $uc */
$cases[] = $uc->getMemberCase();
}
return $this->render(
'internal/cases/my-cases.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_my_cases'), 'List Cases')
],
'notifications' => $this->msgs,
'cases' => $cases,
'notificationCount' => $this->notificationCount,
]
)
);
}
#[Route('/list-cases', name: 'app_list_cases')]
public function listCases(#[CurrentUser()] User $user): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$cases = $this->entityManager->getRepository(MemberCase::class)->findAll();
$workers = $this->entityManager->getRepository(User::class)->getCaseWorkers();
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
return $this->render(
'internal/admin/cases/list-cases.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases')
],
'notifications' => $this->msgs,
'cases' => $cases,
'workers' => $workers,
'notificationCount' => $this->notificationCount,
]
)
);
}
#[Route('/add-case', name: 'app_add_case')]
public function addCase(Request $request, #[CurrentUser()] User $admin): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($admin);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($admin);
$case = new MemberCase();
$form = $this->createForm(MemberCaseFormType::class, $case);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$case = $form->getData();
$this->entityManager->persist($case);
$this->entityManager->flush();
$this->addFlash('success', 'Case added successfully');
return $this->redirectToRoute('app_list_cases');
}
return $this->render(
'internal/admin/cases/add-case.html.twig',
array_merge(
$this->navLinks,
[
'title' => 'Add Case',
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_add_case'), 'Add Case')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'form' => $form,
'sources' => $this->entityManager->getRepository(ReferralSource::class)->retrieveOrderedList(),
]
)
);
}
#[Route('/edit-case/{id}', name: 'app_edit_case')]
public function editCase(Request $request, #[CurrentUser()] User $admin, string $id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($admin);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($admin);
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
$form = $this->createForm(MemberCaseFormType::class, $case);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$case = $form->getData();
$this->entityManager->flush();
$this->addFlash('success', 'Case updated successfully');
return $this->redirectToRoute('app_list_cases');
}
return $this->render(
'internal/admin/cases/edit-case.html.twig',
array_merge(
$this->navLinks,
[
'title' => 'Edit Case',
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_edit_case', ['id' => $id]), 'Edit Case')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'form' => $form,
'case' => $case,
'sources' => $this->entityManager->getRepository(ReferralSource::class)->retrieveOrderedList(),
]
)
);
}
#[Route('/assign-case/{id}', name: 'app_assign_case')]
public function assignCase(string $id, Request $request, #[CurrentUser()] User $admin): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($admin);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($admin);
$caseWorkers = $this->entityManager->getRepository(User::class)->getCaseWorkers();
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
$prevUc = $this->entityManager->getRepository(UserCase::class)->findBy(['memberCase' => $case]);
$uc = new UserCase();
$form = $this->createForm(UserCaseFormType::class, $uc);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $form->get('user')->getData();
$uc = $form->getData();
$uc->setMemberCase($case);
$uc->setUser($user);
if (count($prevUc) > 0) {
$this->entityManager->remove($prevUc[0]);
$this->entityManager->flush();
}
$msg = MessageFactory::createNewCase($admin, $user);
$this->entityManager->persist($uc);
$this->entityManager->persist($msg);
$this->entityManager->flush();
$this->addFlash('success', 'Case assigned successfully');
return $this->redirectToRoute('app_list_cases');
}
return $this->render(
'internal/admin/cases/assign-case.html.twig',
array_merge(
$this->navLinks,
[
'title' => 'Assign Case',
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_assign_case', ['id' => $id]), 'Assign User')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'case' => $case,
'form' => $form,
'id' => $id,
'caseWorkers' => $caseWorkers,
'assignedWorkerId' => (count($case->getUserCases()) > 0 ? $case->getUserCases()->first()->getUser()->getId() : null),
]
)
);
}
#[Route('/case-notes/{id}', name: 'app_case_notes')]
public function showCaseNotes(Request $request, string $id): Response
{
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
return new Response();
}
#[Route('/api/case/{caseId}/user/{userId}', name: 'ajax_case_user_level_check')]
public function checkUserCaseLevel(string $caseId, string $userId) : Response
{
$ret = true;
$user = $this->entityManager->getRepository(User::class)->find($userId);
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
$res = UserCase::checkLevel($user, $case);
if (!$res) {
$ret = [
'userLevel' => ucwords(str_replace('_', ' ', strtolower($user->getLevel()->name))),
'caseLevel' => ucwords(str_replace('_', ' ', strtolower($case->getLevel()->name))),
];
}
return $this->json($ret);
}
#[Route('/api/filter-cases-by-user', name: 'ajax_filter_cases_by_user')]
public function filterCasesByUser(Request $request): Response
{
/** @var User $user */
$user = $this->entityManager->getRepository(User::class)->find($request->query->get('userId'));
/** @var UserCase[] $ucs */
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$ret = [];
foreach ($ucs as $uc) {
$ret[] = $uc->getMemberCase();
}
dump($ret);
die;
return $this->json($ret);
}
}

View File

@ -0,0 +1,227 @@
<?php
namespace App\Controller\Company;
use App\Entity\Company\Company;
use App\Entity\Company\CompanyDocument;
use App\Entity\System\User;
use App\Form\CompanyDocumentFormType;
use App\Form\InternalCompanyFormType;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use App\Libs\Libs;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Component\String\Slugger\SluggerInterface;
class CompanyController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = []
){
$this->navLinks = NavList::LIST;
}
#[Route('/company', name: 'app_company')]
#[IsGranted(new Expression('is_granted("ROLE_ADMIN")'))]
public function editCompanyInfo(
#[CurrentUser()] User $user,
Request $request,
SluggerInterface $slugger
): Response {
$this->navLinks['company_nav'] = NavList::PRESENT_LINK;
$company = $user->getCompany();
$form = $this->createForm(InternalCompanyFormType::class, $company);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
/** @var Company $company */
$company = $form->getData();
if ($form->get('companyLogo')->getData()) {
$file = $form['companyLogo']->getData();
$destination = $this->getParameter('kernel.project_dir').'/public/uploads/company/';
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$newFilename = $slugger->slug($originalFilename).'-'.uniqid().'.'.$file->guessExtension();
$file->move(
$destination,
$newFilename
);
$company->setCompanyLogo($newFilename);
}
$this->entityManager->flush();
return $this->redirectToRoute('app_admin_dashboard');
}
return $this->render(
'internal/admin/company/company-info.html.twig',
array_merge(
$this->navLinks,
[
'form' => $form,
'company' => $company,
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_admin_dashboard'), "Admin Dashboard"),
],
'msgs' => Libs::getMessages($user, $this->entityManager),
]
)
);
}
#[Route('/company/directory', name: 'app_company_directory')]
public function companyDirectory(#[CurrentUser()] User $user): Response
{
$this->navLinks['company_nav'] = NavList::PRESENT_LINK;
$users = $this->entityManager->getRepository(User::class)->findBy(['company' => $user->getCompany()], ['name' => 'ASC']);
return $this->render(
'internal/admin/company/directory.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb(
($this->isGranted('ROLE_ADMIN') ? $this->generateUrl('app_admin_dashboard') : $this->generateUrl('app_dashboard')),
($this->isGranted('ROLE_ADMIN') ? "Admin Dashboard" : "Dashboard")
),
],
'users' => $users,
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
}
#[Route('/user/download-vcard/{id}', name: 'app_download_user_vcard')]
public function downloadUserVcard(#[CurrentUser()] User $user, string $id): Response
{
$coworker = $this->entityManager->getRepository(User::class)->find($id);
if (!$coworker) {
throw new NotFoundHttpException('Coworker not found');
}
if ($coworker->getCompany() !== $user->getCompany()) {
throw new NotFoundHttpException('Coworker not found');
}
return new Response($coworker->generateVCard(), 200, [
'Content-Type' => 'text/vcf',
'Content-Disposition' => 'attachment; filename="' . str_replace(' ', '', $coworker->getName()) . '.vcf"',
'Content-Length' => strlen($coworker->generateVCard()),
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Expires' => '0',
'Pragma' => 'public',
'Content-Transfer-Encoding' => 'binary'
]);
}
#[Route('/docs/list', name: 'app_list_documents')]
#[IsGranted(new Expression('is_granted("ROLE_ADMIN")'))]
public function listDocs(#[CurrentUser()] User $user): Response
{
$this->navLinks['company_nav'] = NavList::PRESENT_LINK;
$companyDocs = $this->entityManager->getRepository(CompanyDocument::class)->findBy(['company' => $user->getCompany()], ['title' => 'ASC']);
return $this->render(
'internal/admin/company/docs/list-documents.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [],
'notifications' => Libs::getMessages($user, $this->entityManager),
'docs' => $companyDocs,
]
)
);
}
#[Route('/docs/add', name: 'app_add_doc')]
#[IsGranted(new Expression('is_granted("ROLE_ADMIN")'))]
public function addCompanyDocument(Request $request, #[CurrentUser()] User $user): Response
{
$this->navLinks['company_nav'] = NavList::PRESENT_LINK;
$form = $this->createForm(CompanyDocumentFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var CompanyDocument $doc */
$doc = $form->getData();
$doc->setCompany($user->getCompany());
$doc->setUpdated(new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE'])));
$this->entityManager->persist($doc);
$this->entityManager->flush();
return $this->redirectToRoute('app_list_documents');
}
return $this->render(
'internal/admin/company/docs/add-document.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [],
'notifications' => Libs::getMessages($user, $this->entityManager),
'form' => $form,
]
)
);
}
#[Route('/docs/edit/{docId}', name: 'app_edit_doc')]
#[IsGranted(new Expression('is_granted("ROLE_ADMIN")'))]
public function editCompanyDocument(string $docId, Request $request, #[CurrentUser()] User $user): Response
{
$companyDoc = $this->entityManager->getRepository(CompanyDocument::class)->find($docId);
$this->navLinks['company_nav'] = NavList::PRESENT_LINK;
checkdate(1, 1, 1);
$form = $this->createForm(CompanyDocumentFormType::class, $companyDoc);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var CompanyDocument $doc */
$doc = $form->getData();
$doc->setUpdated(new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE'])));
$this->entityManager->persist($doc);
$this->entityManager->flush();
return $this->redirectToRoute('app_list_documents');
}
return $this->render(
'internal/admin/company/docs/edit-document.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [],
'notifications' => Libs::getMessages($user, $this->entityManager),
'form' => $form,
'doc' => $companyDoc,
'docText' => str_replace("\r\n", "", $companyDoc->getText())
]
)
);
}
}

View File

@ -0,0 +1,82 @@
<?php
namespace App\Controller\Company;
use App\Entity\Company\CompanyDocument;
use App\Entity\Case\Member;
use App\Entity\Case\MemberDocument;
use App\Entity\System\User;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use App\Libs\Libs;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class DocumentController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = []
) {
$this->navLinks = NavList::LIST;
}
#[Route('/member/{memberId}', name: 'app_display_case_doc')]
public function displayCaseDocument(string $memberId, #[CurrentUser()] User $user): Response
{
/** @var Member $member */
$member = $this->entityManager->getRepository(Member::class)->find($memberId);
$memberDocs = $this->entityManager->getRepository(MemberDocument::class)->findBy(['client' => $member]);
return $this->render(
'internal/cases/members/documents/list-member-docs.html.twig',
array_merge(
$this->navLinks,
[
'notifications' => Libs::getMessages($user, $this->entityManager),
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_my_cases'), 'Cases'),
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $member->getCaseId()->getId()->toString()]), 'Members'),
],
'docs' => $memberDocs,
]
)
);
}
#[Route('/member/{memberId}/document/{docId}/sign', name: 'app_member_sign_case_doc')]
public function signCaseDocument(string $memberId, string $docId, #[CurrentUser()] User $user, Request $request): Response
{
/** @var Member $member */
$member = $this->entityManager->getRepository(Member::class)->find($memberId);
/** @var CompanyDocument $doc */
$doc = $this->entityManager->getRepository(CompanyDocument::class)->find($docId);
/** @var MemberDocument $memDoc */
$memDoc = $this->entityManager->getRepository(MemberDocument::class)->findOneBy([
'document' => $doc,
'client' => $member,
'caseWorker' => $user
]);
if (!$memDoc) {
throw new NotFoundHttpException('Document not found');
}
//$form = $this->createForm(MemberDocument::class);
/** @todo add form data */
//$form->add();
return $this->render(
'internal/cases/members/documents/sign-member-doc.html.twig', [
'doc' => $memDoc,
'caseWorkerSignature' => $user->getSignature(),
]
);
}
}

View File

@ -1,87 +0,0 @@
<?php
namespace App\Controller;
use App\Entity\Messages;
use App\Entity\User;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class DefaultController extends AbstractController
{
/**
* Variable to store unread notification messages
*
* @var array
*/
private array $msgs;
private int $notificationCount = 0;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly UserPasswordHasherInterface $userPasswordHasher,
private array $navLinks = []
) {
$this->navLinks = NavList::LIST;
}
#[Route('/dashboard', name: 'app_dashboard')]
public function dashboard(Request $request, #[CurrentUser()] ?User $user): Response
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
if (!$user->getCompany()) {
return $this->redirectToRoute('app_register_step', ['step' => RegistrationController::REGISTER_STEP_TWO]);
}
$this->navLinks['user_dashboard'] = NavList::PRESENT_LINK;
return $this->render(
'internal/dashboard.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb('', 'Dashboard')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
}
#[Route('/profile', name: 'app_profile')]
public function profile(#[CurrentUser()] User $user): Response
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->navLinks['profile'] = NavList::PRESENT_LINK;
return $this->render(
'internal/profile.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb('', 'Profile')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
}
}

View File

@ -1,208 +0,0 @@
<?php
namespace App\Controller;
use App\Entity\Member;
use App\Entity\User;
use App\Entity\MemberCase;
use App\Entity\Messages;
use App\Form\MemberFormType;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class MemberController extends AbstractController
{
/**
* Variable to store unread notification messages
*
* @var array
*/
private array $msgs;
private int $notificationCount;
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = [],
) {
$this->navLinks = NavList::LIST;
$this->navLinks['case_list'] = NavList::PRESENT_LINK;
}
#[Route('/list-members/{id}', name: 'app_case_members')]
public function listMembers(Request $request, #[CurrentUser()] User $user, string $id): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
$members = $this->entityManager->getRepository(Member::class)->getCaseMembersByName($case);
return $this->render(
'internal/cases/members/list-members.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $id]), 'List Members'),
],
'notifications' => $this->msgs,
'case' => $case,
'members' => $members,
'notificationCount' => $this->notificationCount,
]
)
);
}
#[Route('/add-member/{id}', name: 'app_case_add_member')]
public function addMember(Request $request, #[CurrentUser()] User $user, string $id): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
/** @var MemberCase $case */
$case = $this->entityManager->getRepository(MemberCase::class)->find($id);
$member = new Member();
$form = $this->createForm(MemberFormType::class, $member);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$member->setCaseId($case)
->setFirstName($form->get('firstName')->getData())
->setLastName($form->get('lastName')->getData())
->setDob($form->get('dob')->getData())
->setGender($form->get('gender')->getData())
->setRace($form->get('race')->getData())
->setLanguage($form->get('language')->getData())
->setPersonalId($form->get('personalId')->getData())
->setEmergencyContact($form->get('emergencyContact')->getData())
->setEmail($form->get('email')->getData())
->setAddress($form->get('address')->getData())
->setCity($form->get('city')->getData())
->setState($form->get('state')->getData())
->setZip($form->get('zip')->getData())
->setPhone($form->get('phone')->getData())
->setRelationship($form->get('relationship')->getData())
->setDayPhone($form->get('dayPhone')->getData())
->setEveningPhone($form->get('eveningPhone')->getData())
->setCellPhone($form->get('cellPhone')->getData())
->setSchool($form->get('school')->getData())
->setMaritalStatus($form->get('maritalStatus')->getData())
->setChild($form->get('isChild')->getData())
->setParent($form->get('isParent')->getData())
->setAdultChild($form->get('isAdultChild')->getData())
->setLegalGuardian($form->get('isLegalGuardian')->getData())
->setParentsLiveTogether($form->get('parentsLiveTogether')->getData())
->setDcsApproved($form->get('dcsApproved')->getData())
;
$this->entityManager->persist($member);
$this->entityManager->flush();
$this->addFlash(
'success',
'Member added successfully'
);
return $this->redirectToRoute('app_case_members', ['id' => $case->getId()]);
}
return $this->render(
'internal/cases/members/add-member.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $id]), 'List Members'),
new Breadcrumb($this->generateUrl('app_case_add_member', ['id' => $id]), 'Add Member'),
],
'notifications' => $this->msgs,
'case' => $case,
'form' => $form->createView(),
'notificationCount' => $this->notificationCount,
]
)
);
}
#[Route('/case/{caseId}/edit-member/{memberId}', name: 'app_case_edit_member')]
public function editMember(Request $request, #[CurrentUser()] User $user, string $caseId, string $memberId): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$member = $this->entityManager->getRepository(Member::class)->find($memberId);
$form = $this->createForm(MemberFormType::class, $member);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$member->setFirstName($form->get('firstName')->getData())
->setLastName($form->get('lastName')->getData())
->setDob($form->get('dob')->getData())
->setGender($form->get('gender')->getData())
->setRace($form->get('race')->getData())
->setLanguage($form->get('language')->getData())
->setPersonalId($form->get('personalId')->getData())
->setEmergencyContact($form->get('emergencyContact')->getData())
->setEmail($form->get('email')->getData())
->setAddress($form->get('address')->getData())
->setCity($form->get('city')->getData())
->setState($form->get('state')->getData())
->setZip($form->get('zip')->getData())
->setPhone($form->get('phone')->getData())
->setRelationship($form->get('relationship')->getData())
->setDayPhone($form->get('dayPhone')->getData())
->setEveningPhone($form->get('eveningPhone')->getData())
->setCellPhone($form->get('cellPhone')->getData())
->setSchool($form->get('school')->getData())
->setMaritalStatus($form->get('maritalStatus')->getData())
->setChild($form->get('isChild')->getData())
->setParent($form->get('isParent')->getData())
->setAdultChild($form->get('isAdultChild')->getData())
->setLegalGuardian($form->get('isLegalGuardian')->getData())
->setParentsLiveTogether($form->get('parentsLiveTogether')->getData())
->setDcsApproved($form->get('dcsApproved')->getData())
;
$this->entityManager->flush();
$this->addFlash(
'success',
'Member updated successfully'
);
return $this->redirectToRoute('app_case_members', ['id' => $caseId]);
}
return $this->render(
'internal/cases/members/edit-member.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_cases'), 'List Cases'),
new Breadcrumb($this->generateUrl('app_case_members', ['id' => $caseId]), 'List Members'),
new Breadcrumb($this->generateUrl('app_case_edit_member', ['caseId' => $caseId, 'memberId' => $memberId]), 'Edit Member'),
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'member' => $member,
'form' => $form->createView(),
'caseId' => $caseId,
]
)
);
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace App\Controller;
use App\Entity\Messages;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
class MessageController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager
) {
}
#[Route('/api/notifications/{msgId}', name: 'app_read_message')]
public function readMessage(string $msgId): Response
{
$message = $this->entityManager->getRepository(Messages::class)->find($msgId);
$message->setReceived(new \DateTimeImmutable());
$this->entityManager->flush();
return new JsonResponse(true, Response::HTTP_OK);
}
}

View File

@ -1,190 +0,0 @@
<?php
namespace App\Controller;
use App\Entity\Member;
use App\Entity\Messages;
use App\Entity\Referral;
use App\Entity\StandardNote;
use App\Entity\User;
use App\Entity\UserCase;
use App\Entity\VisitNote;
use App\Enums\NoteLocation;
use App\Enums\NoteMethod;
use App\Enums\ReferralServiceType;
use App\Form\StandardNoteFormType;
use App\Form\VisitNoteFormType;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class NoteController extends AbstractController
{
/**
* Variable to store unread notification messages
*
* @var array
*/
private array $msgs;
private int $notificationCount;
public function __construct(
private EntityManagerInterface $entityManager,
private array $navLinks = [],
) {
$this->navLinks = NavList::LIST;
$this->navLinks['case_notes'] = NavList::PRESENT_LINK;
}
#[Route('/list-notes/{id?null}', name: 'app_list_notes')]
public function listNotes(#[CurrentUser()] User $user, ?string $id = null): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
/** @var UserCase[] $cases */
$cases = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$referrals = [];
$notes = [];
if ($id == 'null') {
$id = null;
}
if ($id) {
$referrals[] = $this->entityManager->getRepository(Referral::class)->find($id);
} else {
foreach ($cases as $case) {
$referrals = array_merge(
$referrals,
$this->entityManager->getRepository(Referral::class)->findBy(['memberCase' => $case->getMemberCase()])
);
}
}
foreach ($referrals as $referral) {
$notes = array_merge(
$notes,
$this->entityManager->getRepository(VisitNote::class)->getOrderedNotes($referral),
$this->entityManager->getRepository(StandardNote::class)->getOrderedNotes($referral),
);
}
return $this->render(
'internal/cases/notes/list-notes.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_notes'), 'List Notes')
],
'notifications' => $this->msgs,
'cases' => $cases,
'notes' => $notes,
'notificationCount' => $this->notificationCount,
]
)
);
}
#[Route('/add-note/{id?null}', name: 'app_add_note')]
public function addNote(#[CurrentUser()] User $user, Request $request, ?string $id = null): Response
{
/** @var Referral $referral */
$referral = $this->entityManager->getRepository(Referral::class)->find($id);
$this->entityManager->getRepository(Referral::class)->populateNotes($referral);
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$members = $this->entityManager->getRepository(Member::class)->findBy(['caseId' => $referral->getMemberCase()]);
$defaultMethod = NoteMethod::BILLABLE;
$defaultLocation = NoteLocation::COMMUNITY_OUTING;
$form = $this->createForm(StandardNoteFormType::class, null, ['members' => $members]);
$template = 'internal/cases/notes/add-standard-note.html.twig';
if ($id == 'null') {
$id = null;
}
if ($referral->getServiceCode() == ReferralServiceType::VS_THBB) {
$form = $this->createForm(VisitNoteFormType::class, null, ['members' => $members]);
$template = 'internal/cases/notes/add-visit-note.html.twig';
$defaultMethod = NoteMethod::BILLABLE_SUPERVISED_VISIT;
} elseif ($referral->getServiceCode() == ReferralServiceType::VS_THBBT) {
$defaultMethod = NoteMethod::BILLABLE;
$defaultLocation = NoteLocation::VEHICLE_TRANSPORTATION;
}
$form = $form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var VisitNote|StandardNote $note */
$note = $form->getData();
$note->setReferral($referral);
$this->entityManager->persist($note);
$this->entityManager->flush();
return $this->redirectToRoute('app_list_notes');
}
return $this->render(
$template,
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_list_notes'), 'List Notes')
],
'notifications' => $this->msgs,
'referral' => $referral,
'form' => $form,
'default_method' => $defaultMethod,
'default_location' => $defaultLocation,
'notificationCount' => $this->notificationCount,
]
)
);
}
#[Route('/edit-note/{noteId}', name: 'app_edit_note')]
public function editNote(string $noteId, #[CurrentUser()] User $user, Request $request): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
return $this->render(
'internal/cases/notes/edit-note.html.twig',
array_merge(
$this->navLinks,
[
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
}
#[Route('/api/filter-notes', name: 'api_filter_notes')]
public function filterNotes(#[CurrentUser()] User $user, Request $request): Response
{
$startDate = $request->get('startDate');
$endDate = $request->get('endDate');
$referralId = $request->get('referralId');
$referral = null;
if ($referralId) {
$referral = $this->entityManager->getRepository(Referral::class)->find($referralId);
}
return $this->json(array_merge(
$this->entityManager->getRepository(VisitNote::class)->filterNotes($user, $referral, $startDate, $endDate),
$this->entityManager->getRepository(StandardNote::class)->filterNotes($user, $referral, $startDate, $endDate),
));
}
}

View File

@ -1,10 +1,9 @@
<?php
namespace App\Controller;
namespace App\Controller\Resources;
use App\Entity\CommunityResource;
use App\Entity\Messages;
use App\Entity\User;
use App\Entity\Resources\CommunityResource;
use App\Entity\System\User;
use App\Form\ResourceFormType;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
@ -22,15 +21,6 @@ use Symfony\UX\Map\Point;
class CommunityResourceController extends AbstractController
{
/**
* Variable to store unread notification messages
*
* @var array
*/
private array $msgs;
private int $notificationCount;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private array $navLinks = []
@ -43,8 +33,6 @@ class CommunityResourceController extends AbstractController
public function list(#[CurrentUser()] User $user): Response
{
$rsc = $this->entityManager->getRepository(CommunityResource::class)->findAll();
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
return $this->render(
'internal/community_resource/list.html.twig',
@ -55,8 +43,7 @@ class CommunityResourceController extends AbstractController
new Breadcrumb('#', 'Community Resources')
],
'resources' => $rsc,
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
@ -65,23 +52,24 @@ class CommunityResourceController extends AbstractController
#[Route('/resource/map', name: 'app_community_resource_map')]
public function map(#[CurrentUser()] User $user): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$rcs = $this->entityManager->getRepository(CommunityResource::class)->findAll();
$map = new Map('default');
$map->center(new Point(39.768502, -86.157918))
->zoom(9)
$map->center(new Point($_ENV['MAP_CENTER_LAT'], $_ENV['MAP_CENTER_LON']))
->zoom($_ENV['MAP_ZOOM_LEVEL'])
;
foreach ($rcs as $rsc) {
/** @var CommunityResource $rsc */
$map->addMarker(new Marker(
position: new Point($rsc->getLat(), $rsc->getLon()),
title: $rsc->getName(),
infoWindow: new InfoWindow(
content: "{$rsc->getName()}<br>{$rsc->getAddress()}, {$rsc->getCity()}, {$rsc->getState()->value} {$rsc->getZip()}<br>Services: " . $rsc->getServicesAvailable()
)
content: $rsc->_toInfoWindow()
),
extra: [
'type' => ''
]
));
}
@ -92,10 +80,10 @@ class CommunityResourceController extends AbstractController
[
'map' => $map,
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_community_resource'), 'List Resources'),
new Breadcrumb('#', 'Community Resources')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
@ -104,9 +92,6 @@ class CommunityResourceController extends AbstractController
#[Route('/resource/add', name: 'app_community_resource_add')]
public function add(#[CurrentUser()] User $user, Request $request): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$form = $this->createForm(ResourceFormType::class);
$form->handleRequest($request);
@ -144,8 +129,7 @@ class CommunityResourceController extends AbstractController
new Breadcrumb($this->generateUrl('app_community_resource'), 'List Resources'),
new Breadcrumb('#', 'Add Resource')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
@ -155,9 +139,6 @@ class CommunityResourceController extends AbstractController
#[Route('/resource/edit/{id}', name: 'app_community_resource_edit')]
public function edit(string $id, #[CurrentUser()] User $user, Request $request): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$rsc = $this->entityManager->getRepository(CommunityResource::class)->find($id);
$form = $this->createForm(ResourceFormType::class, $rsc);
@ -193,8 +174,7 @@ class CommunityResourceController extends AbstractController
new Breadcrumb($this->generateUrl('app_community_resource'), 'List Resources'),
new Breadcrumb('#', 'Edit Resource')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
@ -222,13 +202,4 @@ class CommunityResourceController extends AbstractController
'Content-Transfer-Encoding' => 'binary'
]);
}
#[Route('/api/filter-resource-by-county', name: 'app_api_filter_resource_by_county')]
public function filterResourceByCounty(Request $request): Response
{
$data = json_decode($request->getContent(), true);
$county = $data['county'];
$resources = $this->entityManager->getRepository(CommunityResource::class)->findBy(['county' => $county]);
return $this->json($resources);
}
}

View File

@ -1,17 +1,17 @@
<?php
namespace App\Controller;
namespace App\Controller\Staff;
use App\Entity\MemberCase;
use App\Entity\Messages;
use App\Entity\StaffNote;
use App\Entity\Supervision;
use App\Entity\User;
use App\Entity\UserCase;
use App\Entity\Case\MemberCase;;
use App\Entity\Staff\StaffNote;
use App\Entity\Staff\Supervision;
use App\Entity\System\User;
use App\Entity\System\UserCase;
use App\Factory\MessageFactory;
use App\Form\StaffNoteFormType;
use App\Form\SupervisorStaffNoteFormType;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -19,6 +19,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\Component\Translation\Exception\NotFoundResourceException;
class StaffController extends AbstractController
{
@ -29,8 +30,6 @@ class StaffController extends AbstractController
*/
private array $msgs;
private int $notificationCount;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private array $navLinks = []
@ -42,8 +41,7 @@ class StaffController extends AbstractController
#[Route('/staff-dashboard', name: 'app_staff_dashboard')]
public function staffDashboard(#[CurrentUser()] User $user): Response
{
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$sups = $this->entityManager->getRepository(Supervision::class)->findBy(['supervisor' => $user]);
$staff = [];
@ -62,7 +60,6 @@ class StaffController extends AbstractController
new Breadcrumb('', 'Staff Dashboard')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
@ -74,18 +71,25 @@ class StaffController extends AbstractController
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->navLinks['staff_dashboard'] = NavList::DEFAULT;
$this->navLinks['staff_notes'] = NavList::PRESENT_LINK;
$this->msgs = Libs::getMessages($user, $this->entityManager);
$sup = $this->entityManager->getRepository(Supervision::class)->findOneBy(['worker' => $user]);
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$cases = [];
$this->navLinks['staff_dashboard'] = 'nav-link text-dark';
$this->navLinks['staff_notes'] = NavList::PRESENT_LINK;
foreach ($ucs as $uc) {
$cases[] = $uc->getMemberCase();
$case = $uc->getMemberCase();
$lastNote = $this->entityManager->getRepository(StaffNote::class)->findOneBy(['memberCase' => $case], ['date' => 'DESC']);
if ($lastNote) {
$case->emptyStaffNotes();
$case->addStaffNote($lastNote);
}
$cases[] = $case;
}
return $this->render(
@ -101,7 +105,6 @@ class StaffController extends AbstractController
new Breadcrumb('', 'Staff Cases')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
@ -113,16 +116,26 @@ class StaffController extends AbstractController
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$staff = $this->entityManager->getRepository(User::class)->find($staffId);
$sup = $this->entityManager->getRepository(Supervision::class)->findOneBy(['worker' => $staff, 'supervisor' => $user]);
if (!$sup) {
throw new NotFoundResourceException("It does not appear you are the supervisor to this case worker");
}
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $staff]);
$cases = [];
foreach ($ucs as $case) {
/** @var UserCase $case */
$cases[] = $case->getMemberCase();
foreach ($ucs as $uc) {
/** @var MemberCase $case */
$case = $uc->getMemberCase();
$lastNote = $this->entityManager->getRepository(StaffNote::class)->findOneBy(['memberCase' => $case], ['date' => 'DESC']);
if ($lastNote) {
$case->emptyStaffNotes();
$case->addStaffNote($lastNote);
}
$cases[] = $case;
}
return $this->render(
@ -136,8 +149,7 @@ class StaffController extends AbstractController
new Breadcrumb($this->generateUrl('app_staff_dashboard'), 'Staff Dashboard'),
new Breadcrumb('', 'Staff Cases')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
@ -149,8 +161,9 @@ class StaffController extends AbstractController
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$this->navLinks['staff_dashboard'] = NavList::DEFAULT;
$this->navLinks['staff_notes'] = NavList::PRESENT_LINK;
$isWorker = ($staffId == $user->getId()->toString());
$staff = $this->entityManager->getRepository(User::class)->find($staffId);
@ -179,7 +192,6 @@ class StaffController extends AbstractController
new Breadcrumb('', 'List Notes')
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
@ -191,8 +203,9 @@ class StaffController extends AbstractController
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$this->navLinks['staff_dashboard'] = NavList::DEFAULT;
$this->navLinks['staff_notes'] = NavList::PRESENT_LINK;
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
$form = $this->createForm(StaffNoteFormType::class);
@ -202,6 +215,7 @@ class StaffController extends AbstractController
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var StaffNote $note */
$note = $form->getData();
$note->setMemberCase($case);
@ -209,9 +223,12 @@ class StaffController extends AbstractController
$sup = $this->entityManager->getRepository(Supervision::class)->findOneBy(['worker' => $user]);
$msg = MessageFactory::createStaffing($user, $sup->getSupervisor());
$this->entityManager->persist($msg);
$this->entityManager->persist($note);
$this->entityManager->persist($msg);
$this->entityManager->flush();
$msg->setLink("/staff/sup-sign-note/" . $note->getId());
$this->entityManager->persist($msg);
$this->entityManager->flush();
$this->addFlash('info', 'Staff note added');
@ -238,7 +255,6 @@ class StaffController extends AbstractController
new Breadcrumb('', 'Add Note'),
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
@ -250,13 +266,14 @@ class StaffController extends AbstractController
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$this->navLinks['staff_dashboard'] = NavList::DEFAULT;
$this->navLinks['staff_notes'] = NavList::PRESENT_LINK;
$note = $this->entityManager->getRepository(StaffNote::class)->find($noteId);
$case = $note->getMemberCase();
if ($note->supervisorSignDateTime || $note->workerSignDateTime) {
if ($note->getSupervisorSignDateTime() || $note->getWorkerSignDateTime()) {
$this->addFlash('error', 'This note has already been signed');
return $this->redirectToRoute('app_staff_view_note', ['noteId' => $noteId]);
}
@ -285,7 +302,6 @@ class StaffController extends AbstractController
new Breadcrumb('', 'Edit Note'),
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
@ -297,8 +313,9 @@ class StaffController extends AbstractController
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$this->navLinks['staff_dashboard'] = NavList::DEFAULT;
$this->navLinks['staff_notes'] = NavList::PRESENT_LINK;
$note = $this->entityManager->getRepository(StaffNote::class)->find($noteId);
$case = $note->getMemberCase();
@ -336,7 +353,6 @@ class StaffController extends AbstractController
new Breadcrumb('', 'Sign Note'),
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
@ -348,8 +364,7 @@ class StaffController extends AbstractController
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$note = $this->entityManager->getRepository(StaffNote::class)->find($noteId);
$case = $note->getMemberCase();
@ -362,10 +377,10 @@ class StaffController extends AbstractController
$note->setSupervisorSignDateTime(new \DateTimeImmutable());
/** @var UserCase $uc */
$uc = $this->entityManager->getRepository(UserCase::class)->findOneBy(['case' => $case]);
$uc = $this->entityManager->getRepository(UserCase::class)->findOneBy(['memberCase' => $case]);
$msg = MessageFactory::createSupervisorSignStaffNote($user, $uc->getUser(), $case);
$msg->setLink('/staff/sign-my-note/' . $note->getId());
$this->entityManager->persist($msg);
$this->entityManager->flush();
@ -388,7 +403,6 @@ class StaffController extends AbstractController
new Breadcrumb('', 'Sign Note'),
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);
@ -400,8 +414,9 @@ class StaffController extends AbstractController
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->redirectToRoute('app_login');
}
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$this->navLinks['staff_dashboard'] = NavList::DEFAULT;
$this->navLinks['staff_notes'] = NavList::PRESENT_LINK;
$note = $this->entityManager->getRepository(StaffNote::class)->find($noteId);
@ -417,7 +432,6 @@ class StaffController extends AbstractController
new Breadcrumb('', 'View Note'),
],
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
]
)
);

View File

@ -0,0 +1,274 @@
<?php
namespace App\Controller\System;
use App\Entity\Case\CaseItinerary;
use App\Entity\Case\CaseLocation;
use App\Entity\Resources\CommunityResource;
use App\Entity\Case\MemberCase;;
use App\Entity\Case\Referral;
use App\Entity\Case\StandardNote;
use App\Entity\Case\StandardNoteMember;
use App\Entity\System\Location;
use App\Entity\System\User;
use App\Entity\System\UserCase;
use App\Entity\Case\VisitNote;
use App\Entity\Case\VisitNoteMembers;
use App\Libs\Libs;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class AjaxController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager,
) {
}
#[Route('/api/itinerary/{id}/add', name: 'ajax_itinerary_add')]
public function addItinerary(string $id, Request $request): Response
{
$itinerary = $this->entityManager->getRepository(UserCase::class)->find($id);
$data = json_decode($request->getContent());
$location = new Location();
//$location->setItinerary($itinerary)
;
return $this->json($location);
}
#[Route('/api/filter-address-by-case/{caseId}', name: 'ajax_filter_address_by_case')]
public function filterAddressByCase(string $caseId, Request $request): Response
{
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
$addresses = $this->entityManager->getRepository(Location::class)->getLocationsByCase($case);
return $this->json($addresses);
}
#[Route('/api/case/{caseId}/user/{userId}', name: 'ajax_case_user_level_check')]
public function checkUserCaseLevel(string $caseId, string $userId, #[CurrentUser()] User $admin) : Response
{
$ret = true;
$user = $this->entityManager->getRepository(User::class)->find($userId);
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
if (!Libs::checkPermissions($user, $case, $this->entityManager)) {
throw new AccessDeniedHttpException ('You do not have permission to access this resource.');
}
$res = UserCase::checkLevel($admin, $case);
if (!$res) {
$ret = [
'userLevel' => ucwords(str_replace('_', ' ', strtolower($user->getLevel()->name))),
'caseLevel' => ucwords(str_replace('_', ' ', strtolower($case->getLevel()->name))),
];
}
return $this->json($ret);
}
#[Route('/api/filter-cases-by-user', name: 'ajax_filter_cases_by_user')]
public function filterCasesByUser(Request $request): Response
{
/** @var User $user */
$user = $this->entityManager->getRepository(User::class)->find($request->query->get('userId'));
/** @var UserCase[] $ucs */
$ucs = $this->entityManager->getRepository(UserCase::class)->findBy(['user' => $user]);
$ret = [];
foreach ($ucs as $uc) {
$ret[] = $uc->getMemberCase();
}
return $this->json($ret);
}
#[Route('/api/filter-resource-by-county', name: 'app_api_filter_resource_by_county')]
public function filterResourceByCounty(Request $request): Response
{
$data = json_decode($request->getContent(), true);
$county = $data['county'];
if ($county) {
$resources = $this->entityManager->getRepository(CommunityResource::class)->findBy(['county' => $county]);
} else {
$resources = $this->entityManager->getRepository(CommunityResource::class)->findAll();
}
return $this->json($resources);
}
#[Route('/api/get-case-locations/{caseId}', name: 'get_case_locations')]
public function createItinerary(string $caseId): Response
{
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
$cls = $this->entityManager->getRepository(CaseLocation::class)->getCaseLocations($case);
$crs = $this->entityManager->getRepository(CommunityResource::class)->findAll();
$locations = [];
foreach ($cls as $cl) {
/** @var CaseLocation $cl */
$locations[] = $cl->getLocation();
}
foreach ($crs as $cr) {
$locations[] = $cr->toLocation();
}
return $this->json($locations);
}
#[Route('/api/add-location-to-itinerary', name: 'add_location_to_itinerary')]
public function addLocationToItinerary(Request $request, Session $session): Response
{
$case = $this->entityManager->getRepository(MemberCase::class)->find($request->getPayload()->get('caseId'));
$origin = $this->entityManager->getRepository(Location::class)->find($request->getPayload()->get('origin'));
$destination = $this->entityManager->getRepository(Location::class)->find($request->getPayload()->get('destination'));
$departure = $request->getPayload()->get('departure');
$caseMileage = (bool) $request->getPayload()->get('caseMileage');
$date = new DateTime($request->getPayload()->get('date'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
$route = Libs::getRouteDistance($origin, $destination);
if (!$route) {
return $this->json([
'success' => false,
'message' => 'No route found'
]);
}
$ci = new CaseItinerary();
$ci->setMemberCase($case)
->setDate($date)
->setCaseMileage($caseMileage)
->setOriginLocation($origin)
->setDestLocation($destination)
->setDeparture(new \DateTimeImmutable($departure))
->setDistance($route->getDistance())
->setDuration($route->getDuration())
->setGpsRoute($route->getGeometry())
;
$this->entityManager->persist($ci);
$this->entityManager->flush();
$session->getFlashBag()->add(
'success',
'Location added to itinerary'
);
return $this->json([
'success' => true,
'message' => 'Location added to itinerary'
]);
}
#[Route('/api/filter-itinerary-by-case', name: 'ajax_filter_itinerary_by_case')]
public function filterItineraryByCase(Request $request, #[CurrentUser()] ?User $user): Response
{
$case = null;
$startDate = null;
$endDate = null;
//dd($request->getPayload());
if ($request->getPayload()->get('caseId')) {
$caseId = $request->getPayload()->get('caseId');
$case = $this->entityManager->getRepository(MemberCase::class)->find($caseId);
}
if ($request->getPayload()->get('startDate')) {
$startDate = new DateTime($request->getPayload()->get('startDate'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
}
if ($request->getPayload()->get('endDate')) {
$endDate = new DateTime($request->getPayload()->get('endDate'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
}
$itineraries = $this->entityManager->getRepository(CaseItinerary::class)->getRecentTravel($user, [
'case' => $case,
'from' => $startDate,
'to' => $endDate,
]);
$ret = [];
foreach ($itineraries as $itinerary) {
/** @var CaseItinerary $itinerary */
$ret[] = [
'id' => $itinerary->getId()->toString(),
'date' => $itinerary->getDate()->format('F j, Y'),
'origin' => $itinerary->getOriginLocation(),
'destination' => $itinerary->getDestLocation(),
'distance' => $itinerary->getDistance(),
'duration' => $itinerary->getDuration()->format("%h:%i'%s''"),
'case' => $itinerary->getMemberCase()->getCaseName(),
];
}
return $this->json($ret);
}
#[Route('/api/filter-notes', name: 'api_filter_notes')]
public function filterNotes(#[CurrentUser()] User $user, Request $request): Response
{
$startDate = null;
$endDate = null;
$referral = null;
$case = null;
if ($request->getPayload()->get('startDate')) {
$startDate = new DateTime($request->getPayload()->get('startDate'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
}
if ($request->getPayload()->get('endDate')) {
$endDate = new DateTime($request->getPayload()->get('endDate'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
}
if ($request->getPayload()->get('referral')) {
$referral = $this->entityManager->getRepository(Referral::class)->find($request->getPayload()->get('referral'));
}
if ($request->getPayload()->get('case')) {
$case = $this->entityManager->getRepository(MemberCase::class)->find($request->getPayload()->get('case'));
}
$params = [
'startDate' => $startDate,
'endDate' => $endDate,
'referral' => $referral,
'case' => $case,
];
$notes = array_merge(
$this->entityManager->getRepository(VisitNote::class)->filterNotes($user, $params),
$this->entityManager->getRepository(StandardNote::class)->filterNotes($user, $params),
);
foreach ($notes as $idx => $note) {
/** @var VisitNote|StandardNote $note */
/** @var VisitNoteMember[]|StandardNoteMember[] $members */
if ($note instanceof VisitNote) {
$members = $this->entityManager->getRepository(VisitNoteMembers::class)->findBy(['note' => $note]);
} elseif ($note instanceof StandardNote) {
$members = $this->entityManager->getRepository(StandardNoteMember::class)->findBy(['note' => $note]);
} else {
continue;
}
$notes[$idx]->setMembers($members);
}
return new Response(json_encode($notes, 0, 3));
}
}

View File

@ -0,0 +1,237 @@
<?php
namespace App\Controller\System;
use App\Entity\System\User;
use App\Libs\Breadcrumb;
use App\Libs\Dashboard;
use App\Libs\Libs;
use App\Libs\NavList;
use DateInterval;
use DateTime;
use DateTimeInterface;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TelType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\Component\String\Slugger\SluggerInterface;
class DefaultController extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly UserPasswordHasherInterface $userPasswordHasher,
private array $navLinks = []
) {
$this->navLinks = NavList::LIST;
}
#[Route('/up', name: 'app_up')]
public function up(): Response
{
$cnx = $this->entityManager->getConnection();
$cnx->connect();
$connected = $cnx->isConnected();
if ($connected) {
return $this->json(true, Response::HTTP_OK);
} else {
return $this->json(false, Response::HTTP_SERVICE_UNAVAILABLE);
}
}
#[Route('/dashboard', name: 'app_dashboard')]
public function dashboard(Request $request, #[CurrentUser()] ?User $user): Response
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
if (!$user->getCompany()) {
return $this->redirectToRoute('app_register_step', ['step' => RegistrationController::REGISTER_STEP_TWO]);
}
$oldPasswordDate = new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
$oldPasswordDate->sub(DateInterval::createFromDateString('120 days'));
if (is_a($user->getPasswordChanged(), DateTimeInterface::class) && $user->getPasswordChanged() < $oldPasswordDate) {
$this->addFlash('danger', 'You must change your password');
return $this->redirectToRoute('app_profile');
}
if(isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] == "{$_SERVER['HTTP_X_FORWARDED_PROTO']}://{$_SERVER['HTTP_HOST']}/") {
$this->entityManager->getRepository(User::class)->updateLastLogin($user);
}
$dashboard = new Dashboard($this->entityManager, $user);
$this->navLinks['user_dashboard'] = NavList::PRESENT_LINK;
return $this->render(
'internal/dashboard.html.twig',
array_merge(
$this->navLinks,
$dashboard->toArray(),
[
'breadcrumbs' => [
new Breadcrumb('', 'Dashboard')
],
'notifications' => Libs::getMessages($user, $this->entityManager),
]
)
);
}
#[Route('/profile', name: 'app_profile')]
public function profile(
Request $request,
#[CurrentUser()] User $user,
SluggerInterface $slugger
): Response {
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$this->navLinks['profile'] = NavList::PRESENT_LINK;
$form = $this->createFormBuilder($user)
->add('name', TextType::class, [
'label' => 'Name',
'label_attr' => ['class' => 'form-label'],
'attr' => ['class' => 'form-control'],
])
->add('email', EmailType::class, [
'label' => 'Email',
'label_attr' => ['class' => 'form-label'],
'attr' => ['class' => 'form-control'],
])
->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'The password fields must match.',
'required' => false,
'mapped' => false,
'first_options' => ['label' => 'Password', 'label_attr' => ['class' => 'form-label']],
'second_options' => ['label' => 'Repeat Password', 'label_attr' => ['class' => 'form-label']],
])
->add('personalPhone', TelType::class, [
'label' => 'Personal Phone',
])
->add('workPhone', TelType::class, [
'label' => 'Work Phone',
])
->add('imageName', FileType::class, [
'label' => 'Profile Picture',
'required' => false,
'mapped' => false
])
->add('signature', HiddenType::class)
->add('submit', SubmitType::class, [
'label' => 'Save Profile',
'attr' => ['class' => 'btn btn-lg bg-gradient-dark btn-lg w-100 mt-4 mb-0']
])
->getForm()
;
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($form->get('signature')->getData()) {
$signature = $form->get('signature')->getData();
$user->setSignature($signature);
}
$firstPassword = $form->get('password')['first']->getData();
$secondPassword = $form->get('password')['second']->getData();
if ($firstPassword !== $secondPassword) {
$this->addFlash('danger', 'The password fields must match.');
return $this->redirectToRoute('app_profile');
}
$plainPassword = $form->get('password')['first']->getData();
if ($plainPassword) {
$user->setPassword(
$this->userPasswordHasher->hashPassword(
$user,
$plainPassword
)
);
$user->setPasswordChanged(new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE'])));
}
if ($form['imageName']->getData()) {
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
$file = $form['imageName']->getData();
$destination = $this->getParameter('kernel.project_dir').'/public/uploads/user_images/';
if (!file_exists($destination)) {
mkdir($destination, 0775);
}
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$newFilename = $slugger->slug($originalFilename).'-'.uniqid().'.'.$file->guessExtension();
$file->move(
$destination,
$newFilename
);
$user->setImageName($newFilename);
}
if ($form['personalPhone']->getData()) {
$phone = Libs::Phone($form['personalPhone']->getData());
$user->setPersonalPhone($phone);
}
if ($form['workPhone']->getData()) {
$phone = Libs::Phone($form['workPhone']->getData());
$user->setWorkPhone($phone);
}
$this->entityManager->persist($user);
$this->entityManager->flush();
return $this->redirectToRoute('app_dashboard');
} elseif ($form->isSubmitted() && !$form->isValid()) {
$this->addFlash('danger', 'The form contains errors.');
}
return $this->render(
'internal/profile.html.twig',
array_merge(
$this->navLinks,
[
'breadcrumbs' => [
new Breadcrumb('', 'Profile')
],
'notifications' => Libs::getMessages($user, $this->entityManager),
'currentUser' => $user,
'signaturePresent' => ($user->getSignature() ? true : false),
'signature' => $user->getSignature(),
'form' => $form->createView(),
]
)
);
}
#[Route('/uploads/user_images/{imageName}', name: 'app_user_profile_image')]
public function displayUserImage(string $imageName): Response
{
return new BinaryFileResponse("{$this->getParameter('kernel.project_dir')}/public/{$_ENV['USER_IMAGE_PATH']}/{$imageName}");
}
#[Route('/uploads/company_images/{companyLogo}', name: 'app_company_logo')]
public function displayCompanyLogo(string $companyLogo): Response
{
return new BinaryFileResponse("{$this->getParameter('kernel.project_dir')}/public/{$_ENV['COMPANY_IMAGE_PATH']}/{$companyLogo}");
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Controller\System;
use App\Entity\System\Messages;
use App\Entity\Staff\Supervision;
use App\Entity\System\User;
use App\Enums\System\MessageType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
class MessageController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager
) {
}
#[Route('/api/notifications/{msgId}', name: 'app_read_message')]
public function readMessage(string $msgId): Response
{
/** @var Messages $message */
$message = $this->entityManager->getRepository(Messages::class)->find($msgId);
$message->setReceived(new \DateTimeImmutable());
$this->entityManager->flush();
return $this->json([
'success' => true,
'message' => 'Message marked as read',
'link' => $message->getLink(),
]);
}
#[Route('/api/send-message', name: 'app_send_message')]
public function sendMessage(Request $request, #[CurrentUser()] User $user): Response
{
$sup = $this->entityManager->getRepository(Supervision::class)->getSupervisorByWorker($user);
$data = json_decode($request->getContent(), true);
$message = new Messages();
$message->setSender($user);
$message->setSent(new \DateTimeImmutable());
$message->setRecipient($sup);
$message->setTitle('New Message');
$message->setMessage($data['message']);
$message->setType(MessageType::GENERAL);
$this->entityManager->persist($message);
$this->entityManager->flush();
return $this->json([
'success' => true,
'message' => 'Message sent',
]);
}
}

View File

@ -1,12 +1,12 @@
<?php
namespace App\Controller;
namespace App\Controller\System;
use App\Entity\Messages;
use App\Entity\ReferralSource;
use App\Entity\User;
use App\Entity\System\ReferralSource;
use App\Entity\System\User;
use App\Form\ReferralSourceFormType;
use App\Libs\Breadcrumb;
use App\Libs\Libs;
use App\Libs\NavList;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -24,8 +24,6 @@ class ReferralSourceController extends AbstractController
*/
private array $msgs;
private int $notificationCount;
public function __construct(
private EntityManagerInterface $entityManager,
private array $navList = []
@ -38,8 +36,7 @@ class ReferralSourceController extends AbstractController
public function listReferralSources(#[CurrentUser()] User $user): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$sources = $this->entityManager->getRepository(ReferralSource::class)->retrieveOrderedList();
@ -50,7 +47,6 @@ class ReferralSourceController extends AbstractController
[
'sources' => $sources,
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_referral_source'), 'Referral Sources')
]
@ -63,8 +59,7 @@ class ReferralSourceController extends AbstractController
public function addSource(Request $request, #[CurrentUser()] User $user): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$rs = new ReferralSource();
$form = $this->createForm(ReferralSourceFormType::class, $rs);
@ -89,7 +84,6 @@ class ReferralSourceController extends AbstractController
[
'form' => $form,
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_referral_source'), 'Referral Sources'),
new Breadcrumb($this->generateUrl('app_add_source'), 'Add Source')
@ -103,8 +97,7 @@ class ReferralSourceController extends AbstractController
public function editSource(Request $request, #[CurrentUser()] User $user, string $id): Response
{
$this->denyAccessUnlessGranted('ROLE_ADMIN');
$this->msgs = $this->entityManager->getRepository(Messages::class)->getUnreadMessages($user);
$this->notificationCount = $this->entityManager->getRepository(Messages::class)->getUnreadMessageCount($user);
$this->msgs = Libs::getMessages($user, $this->entityManager);
$rs = $this->entityManager->getRepository(ReferralSource::class)->find($id);
@ -130,7 +123,6 @@ class ReferralSourceController extends AbstractController
'form' => $form,
'rs' => $rs,
'notifications' => $this->msgs,
'notificationCount' => $this->notificationCount,
'breadcrumbs' => [
new Breadcrumb($this->generateUrl('app_referral_source'), 'Referral Sources'),
new Breadcrumb($this->generateUrl('app_edit_source', ['id' => $id]), 'Edit Source')

View File

@ -1,12 +1,11 @@
<?php
namespace App\Controller;
namespace App\Controller\System;
use App\DataTransferObject\CompanyDetailsDto;
use App\Entity\User;
use App\Enums\CaseLevel;
use App\Enums\JobType;
use App\Enums\RateType;
use App\Entity\System\User;
use App\Enums\Case\CaseLevel;
use App\Enums\System\RateType;
use App\Factory\CompanyFactory;
use App\Form\CompanyFormType;
use App\Form\RegistrationFormType;
@ -80,11 +79,7 @@ class RegistrationController extends AbstractController
)
);
$user->setCaseWorker(true)
->setCaseManager(true)
->setTherapist(true)
->setSu(true)
->setRateType(RateType::FIXED)
$user->setRateType(RateType::FIXED)
->setRate('0.00')
->setRoles(['ROLE_ADMIN'])
->setLevel(CaseLevel::ADMIN);

View File

@ -1,6 +1,6 @@
<?php
namespace App\Controller;
namespace App\Controller\System;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

View File

@ -2,12 +2,12 @@
namespace App\DataFixtures;
use App\Entity\MemberCase;
use App\Entity\ReferralSource;
use App\Entity\User;
use App\Entity\UserCase;
use App\Enums\CaseLevel;
use App\Enums\County;
use App\Entity\Case\MemberCase;;
use App\Entity\System\ReferralSource;
use App\Entity\System\User;
use App\Entity\System\UserCase;
use App\Enums\Case\CaseLevel;
use App\Enums\System\County;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
@ -16,13 +16,15 @@ class MemberCaseFixture extends Fixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager): void
{
if(!$_ENV['CREATE_CASES']) {
return;
}
$sources = $manager->getRepository(ReferralSource::class)->findAll();
$users = $manager->getRepository(User::class)->findAll();
$gen = \Faker\Factory::create();
for ($x = 0; $x < 50; $x++) {
for ($x = 0; $x < $_ENV['CREATE_CASES']; $x++) {
$case = new MemberCase();
$case->setCaseNumber($gen->numberBetween(1000000, 9999999))
->setDcsCaseId($gen->numberBetween(1000000, 9999999))

View File

@ -2,12 +2,12 @@
namespace App\DataFixtures;
use App\Entity\Member;
use App\Entity\MemberCase;
use App\Enums\GenderType;
use App\Enums\RaceType;
use App\Enums\RelationshipType;
use App\Enums\State;
use App\Entity\Case\Member;
use App\Entity\Case\MemberCase;;
use App\Enums\System\GenderType;
use App\Enums\Case\RaceType;
use App\Enums\Case\RelationshipType;
use App\Enums\System\State;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
@ -16,7 +16,9 @@ class MemberFixture extends Fixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager): void
{
if (!$_ENV['CREATE_MEMBERS']) {
return;
}
$gen = \Faker\Factory::create();
$cases = $manager->getRepository(MemberCase::class)->findAll();
@ -24,7 +26,7 @@ class MemberFixture extends Fixture implements DependentFixtureInterface
/** @var MemberCase $case */
$caseLastName = $case->getLastName();
print "Adding members for case {$case->getCaseName()}".PHP_EOL;
$memCount = $gen->numberBetween(0, 5);
$memCount = $gen->numberBetween(0, $_ENV['CREATE_MEMBERS']);
for ($x = 0; $x < $memCount; $x++) {
$isChild = $gen->boolean();
$isParent = ($isChild ? false : $gen->boolean());

View File

@ -2,15 +2,15 @@
namespace App\DataFixtures;
use App\Entity\MemberCase;
use App\Entity\Referral;
use App\Entity\StandardNote;
use App\Entity\VisitNote;
use App\Enums\NoteLocation;
use App\Enums\NoteMethod;
use App\Enums\NoteStatus;
use App\Enums\ReferralServiceType;
use App\Enums\VisitQualityLevel;
use App\Entity\Case\MemberCase;;
use App\Entity\Case\Referral;
use App\Entity\Case\StandardNote;
use App\Entity\Case\VisitNote;
use App\Enums\Case\NoteLocation;
use App\Enums\Case\NoteMethod;
use App\Enums\Case\NoteStatus;
use App\Enums\Case\ReferralServiceType;
use App\Enums\Case\VisitQualityLevel;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
@ -19,14 +19,16 @@ class NoteFixture extends Fixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager): void
{
if(!$_ENV['CREATE_NOTES']) {
return;
}
$gen = \Faker\Factory::create();
$refs = $manager->getRepository(Referral::class)->findAll();
foreach ($refs as $ref) {
/** @var Referral $ref */
print "Adding notes for referral {$ref->getReferralId()}".PHP_EOL;
$noteCount = $gen->numberBetween(0, 10);
$noteCount = $gen->numberBetween(0, $_ENV['CREATE_NOTES']);
$case = $ref->getMemberCase();
$caseMembers = $case->getMembers();

View File

@ -2,9 +2,9 @@
namespace App\DataFixtures;
use App\Entity\MemberCase;
use App\Entity\Referral;
use App\Enums\ReferralServiceType;
use App\Entity\Case\MemberCase;;
use App\Entity\Case\Referral;
use App\Enums\Case\ReferralServiceType;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
@ -13,13 +13,15 @@ class ReferralFixture extends Fixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager): void
{
if(!$_ENV['CREATE_REFERRALS']) {
return;
}
$gen = \Faker\Factory::create();
$cases = $manager->getRepository(MemberCase::class)->findAll();
foreach ($cases as $case) {
print "Adding referrals for case {$case->getCaseNumber()}".PHP_EOL;
$refCount = $gen->numberBetween(0, 2);
$refCount = $gen->numberBetween(0, $_ENV['CREATE_REFERRALS']);
for ($x = 0; $x < $refCount; $x++) {
$ref = new Referral();
$ref->setReferralId($gen->numberBetween(1000000, 9999999))

View File

@ -2,8 +2,8 @@
namespace App\DataFixtures;
use App\Entity\ReferralSource;
use App\Enums\County;
use App\Entity\System\ReferralSource;
use App\Enums\System\County;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Faker\Factory;
@ -12,10 +12,12 @@ class ReferralSourceFixture extends Fixture
{
public function load(ObjectManager $manager): void
{
if(!$_ENV['CREATE_SOURCES']) {
return;
}
$gen = Factory::create();
for ($x = 0; $x < 20; $x++) {
for ($x = 0; $x < $_ENV['CREATE_REFERRALS']; $x++) {
$src = new ReferralSource();
$name = "{$gen->firstName()} {$gen->lastName()}";
$username = strtolower(str_replace(' ', '.', $name));

View File

@ -0,0 +1,65 @@
<?php
namespace App\DataFixtures;
use App\Entity\Case\MemberCase;;
use App\Entity\Staff\StaffNote;
use App\Enums\Case\ReferralServiceType;
use DateTime;
use DateTimeZone;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
class StaffNoteFixture extends Fixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager): void
{
if(!$_ENV['CREATE_STAFF_NOTES']) {
return;
}
$cases = $manager->getRepository(MemberCase::class)->findAll();
$gen = \Faker\Factory::create();
foreach ($cases as $case) {
/** @var MemberCase $case */
$note = new StaffNote();
$admitDate = new DateTime($case->getAdmitDate()?->format('Y-m-d').' '.$gen->time('H:i:s'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
$admitDate->add(\DateInterval::createFromDateString('7 day'));
$note->setDate($admitDate);
$note->setMemberCase($case);
$note->setServicesProvided($gen->randomElements(ReferralServiceType::class, $gen->numberBetween(1, 3)));
while ($admitDate->getTimestamp() < time()) {
$workerSignDatetime = clone $admitDate;
$workerSignDatetime->setTime($gen->time('H'), $gen->time('i'), $gen->time('s'));
$workerSignDatetime->add(\DateInterval::createFromDateString('1 day'));
$note->setWorkerSignDatetime($workerSignDatetime);
$supervisorSignDatetime = clone $admitDate;
$supervisorSignDatetime->setTime($gen->time('H'), $gen->time('i'), $gen->time('s'));
$supervisorSignDatetime->add(\DateInterval::createFromDateString('1 day'));
$note->setSupervisorSignDatetime($supervisorSignDatetime);
$note->setNote($gen->text(200));
$note->setRecommendations($gen->text(20));
$manager->persist($note);
$admitDate->add(\DateInterval::createFromDateString('14 days'));
$note = clone $note;
$note->setDate(clone $admitDate);
}
}
$manager->flush();
}
public function getDependencies(): array
{
return [
MemberCaseFixture::class,
];
}
}

View File

@ -2,10 +2,10 @@
namespace App\DataFixtures;
use App\Entity\Company;
use App\Entity\User;
use App\Enums\CaseLevel;
use App\Enums\RateType;
use App\Entity\Company\Company;
use App\Entity\System\User;
use App\Enums\Case\CaseLevel;
use App\Enums\System\RateType;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
@ -20,10 +20,12 @@ class UserFixture extends Fixture
public function load(ObjectManager $manager): void
{
if(!$_ENV['CREATE_USERS']) {
return;
}
$comp = $manager->getRepository(Company::class)->findOneBy(['name' => 'Counseling Partners, LLC']);
$gen = \Faker\Factory::create();
for ($x = 0; $x < 20; $x++) {
for ($x = 0; $x < $_ENV['CREATE_USERS']; $x++) {
$user = new User();
$name = $gen->firstName().' '.$gen->lastName();
$username = strtolower(str_replace(' ', '.', $name));
@ -45,10 +47,6 @@ class UserFixture extends Fixture
$user->setName($name)
->setUsername($username)
->setEmail($username.'@counselingpartnersllc.com')
->setCaseManager($cm)
->setCaseWorker($cw)
->setTherapist($t)
->setSu($su)
->setRoles($roles)
->setRateType($gen->randomElement(RateType::class))
->setRate($gen->numberBetween(0, 100))

View File

@ -0,0 +1,202 @@
<?php
namespace App\Entity\Case;
use App\Entity\System\Location;
use App\Repository\Case\CaseItineraryRepository;
use DateTime;
use DateInterval;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
use Symfony\UX\Map\Point;
#[ORM\Entity(repositoryClass: CaseItineraryRepository::class)]
class CaseItinerary
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\Column(type: Types::DATE_MUTABLE)]
private ?\DateTimeInterface $date = null;
#[ORM\Column(type: Types::TIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $departure = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Location $originLocation = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Location $destLocation = null;
#[ORM\Column]
private ?bool $caseMileage = null;
#[ORM\Column]
private ?DateInterval $duration = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?MemberCase $memberCase = null;
#[ORM\Column(nullable: true)]
private ?float $distance = null;
#[ORM\Column(nullable: true)]
private ?array $gpsRoute = null;
public function getId(): ?Uuid
{
return $this->id;
}
public function getDeparture(): ?\DateTimeInterface
{
return $this->departure;
}
public function setDeparture(?\DateTimeInterface $departure): static
{
$this->departure = $departure;
return $this;
}
public function getOriginLocation(): ?Location
{
return $this->originLocation;
}
public function setOriginLocation(?Location $originLocation): static
{
$this->originLocation = $originLocation;
return $this;
}
public function getDestLocation(): ?Location
{
return $this->destLocation;
}
public function setDestLocation(?Location $destLocation): static
{
$this->destLocation = $destLocation;
return $this;
}
public function isCaseMileage(): ?bool
{
return $this->caseMileage;
}
public function setCaseMileage(bool $caseMileage): static
{
$this->caseMileage = $caseMileage;
return $this;
}
public function getDuration(): ?DateInterval
{
return $this->duration;
}
public function setDuration(?DateInterval $duration): static
{
//$this->calcDuration();
$this->duration = $duration;
return $this;
}
public function calcDuration()
{
//$this->duration = $this->departure - $this->arrival;
}
public function getMemberCase(): ?MemberCase
{
return $this->memberCase;
}
public function setMemberCase(?MemberCase $memberCase): static
{
$this->memberCase = $memberCase;
return $this;
}
public function getDate(): ?\DateTimeInterface
{
return $this->date;
}
public function setDate(\DateTimeInterface $date): static
{
$this->date = $date;
return $this;
}
public function getDistance(): ?float
{
return $this->distance;
}
public function setDistance(?float $distance): static
{
$this->distance = $distance;
return $this;
}
public function getGpsRoute(): ?array
{
return $this->gpsRoute;
}
public function setGpsRoute(?array $gpsRoute): static
{
$this->gpsRoute = $gpsRoute;
return $this;
}
public function getGPSPolyLines(): array
{
$points = [];
foreach ($this->gpsRoute as $route) {
$points[] = new Point($route['lat'], $route['lon']);
}
return $points;
}
public function originInfoWindow(): string
{
return <<<EOL
{$this->originLocation->getName()}<br/>
<a href='http://maps.google.com/?q={$this->originLocation->getLat()},{$this->originLocation->getLon()}'>{$this->originLocation->getFormattedAddress()}</a><br/>
{$this->departure->format("g:i a")}
EOL;
}
public function destinationInfoWindow(): string
{
/** @var DateTime $arrival */
$arrival = $this->departure;
$arrival->add($this->duration);
return <<<EOL
{$this->destLocation->getName()}<br/>
<a href='http://maps.google.com/?q={$this->destLocation->getLat()},{$this->destLocation->getLon()}'>{$this->destLocation->getFormattedAddress()}</a><br/>
{$arrival->format("g:i a")}
EOL;
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace App\Entity\Case;
use App\Entity\System\Location;
use App\Repository\Case\CaseLocationRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: CaseLocationRepository::class)]
class CaseLocation
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?MemberCase $memberCase = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Location $location = null;
public function getId(): ?int
{
return $this->id;
}
public function getMemberCase(): ?MemberCase
{
return $this->memberCase;
}
public function setMemberCase(?MemberCase $memberCase): static
{
$this->memberCase = $memberCase;
return $this;
}
public function getLocation(): ?Location
{
return $this->location;
}
public function setLocation(?Location $location): static
{
$this->location = $location;
return $this;
}
}

View File

@ -1,11 +1,11 @@
<?php
namespace App\Entity;
namespace App\Entity\Case;
use App\Enums\GenderType;
use App\Enums\RaceType;
use App\Enums\RelationshipType;
use App\Repository\MemberRepository;
use App\Enums\System\GenderType;
use App\Enums\Case\RaceType;
use App\Enums\Case\RelationshipType;
use App\Repository\Case\MemberRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
@ -23,7 +23,7 @@ class Member
#[ORM\ManyToOne(inversedBy: 'members')]
#[ORM\JoinColumn(nullable: false)]
private ?MemberCase $caseId = null;
private ?MemberCase $memberCase = null;
#[ORM\Column(length: 45)]
private ?string $lastName = null;
@ -103,19 +103,27 @@ class Member
#[ORM\Column]
private ?bool $dcsApproved = null;
private ?bool $checked = false;
public function getId(): ?Uuid
{
return $this->id;
}
public function setId(?Uuid $id): static
{
$this->id = $id;
return $this;
}
public function getCaseId(): ?MemberCase
{
return $this->caseId;
return $this->memberCase;
}
public function setCaseId(?MemberCase $caseId): static
{
$this->caseId = $caseId;
$this->memberCase = $caseId;
return $this;
}
@ -451,4 +459,16 @@ class Member
return $this;
}
public function isChecked(): bool
{
return $this->checked;
}
public function setChecked(bool $checked): static
{
$this->checked = $checked;
return $this;
}
}

View File

@ -1,10 +1,14 @@
<?php
namespace App\Entity;
namespace App\Entity\Case;
use App\Enums\CaseLevel;
use App\Enums\County;
use App\Repository\MemberCaseRepository;
use App\Entity\Staff\StaffNote;
use App\Entity\System\ReferralSource;
use App\Entity\System\UserCase;
use App\Enums\Case\CaseLevel;
use App\Enums\System\County;
use App\Enums\Case\ReferralType;
use App\Repository\Case\MemberCaseRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
@ -31,7 +35,7 @@ class MemberCase
private ?string $lastName = null;
#[ORM\Column(length: 45)]
private ?string $referralType = null;
private ?ReferralType $referralType = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
@ -109,6 +113,9 @@ class MemberCase
#[ORM\OneToMany(targetEntity: StaffNote::class, mappedBy: 'memberCase')]
private Collection $staffNotes;
#[ORM\Column]
private ?int $rate = null;
public function __construct()
{
$this->userCases = new ArrayCollection();
@ -164,12 +171,12 @@ class MemberCase
return "{$this->lastName}, {$this->firstName}";
}
public function getReferralType(): ?string
public function getReferralType(): ?ReferralType
{
return $this->referralType;
}
public function setReferralType(string $referralType): static
public function setReferralType(ReferralType $referralType): static
{
$this->referralType = $referralType;
@ -505,4 +512,22 @@ class MemberCase
return $this;
}
public function emptyStaffNotes(): static
{
$this->staffNotes->clear();
return $this;
}
public function getRate(): ?int
{
return $this->rate;
}
public function setRate(int $rate): static
{
$this->rate = $rate;
return $this;
}
}

View File

@ -0,0 +1,149 @@
<?php
namespace App\Entity\Case;
use App\Entity\Company\CompanyDocument;
use App\Entity\System\User;
use App\Repository\Case\MemberDocumentRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: MemberDocumentRepository::class)]
class MemberDocument
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Member $client = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?User $caseWorker = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $clientSigned = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $workerSigned = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?CompanyDocument $document = null;
#[ORM\Column(nullable: true)]
private ?array $clientSignature = null;
#[ORM\Column(nullable: true)]
private ?array $workerSignature = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $docData = null;
public function getId(): ?Uuid
{
return $this->id;
}
public function getClient(): ?Member
{
return $this->client;
}
public function setClient(?Member $client): static
{
$this->client = $client;
return $this;
}
public function getCaseWorker(): ?User
{
return $this->caseWorker;
}
public function setCaseWorker(?User $caseWorker): static
{
$this->caseWorker = $caseWorker;
return $this;
}
public function getClientSigned(): ?\DateTimeInterface
{
return $this->clientSigned;
}
public function setClientSigned(?\DateTimeInterface $clientSigned): static
{
$this->clientSigned = $clientSigned;
return $this;
}
public function getWorkerSigned(): ?\DateTimeInterface
{
return $this->workerSigned;
}
public function setWorkerSigned(?\DateTimeInterface $workerSigned): static
{
$this->workerSigned = $workerSigned;
return $this;
}
public function getDocument(): ?CompanyDocument
{
return $this->document;
}
public function setDocument(?CompanyDocument $document): static
{
$this->document = $document;
return $this;
}
public function getClientSignature(): ?array
{
return $this->clientSignature;
}
public function setClientSignature(?array $clientSignature): static
{
$this->clientSignature = $clientSignature;
return $this;
}
public function getWorkerSignature(): ?array
{
return $this->workerSignature;
}
public function setWorkerSignature(?array $workerSignature): static
{
$this->workerSignature = $workerSignature;
return $this;
}
public function getDocData(): ?string
{
return $this->docData;
}
public function setDocData(?string $docData): static
{
$this->docData = $docData;
return $this;
}
}

View File

@ -0,0 +1,115 @@
<?php
namespace App\Entity\Case;
use App\Repository\Case\MonthlyCaseNoteRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: MonthlyCaseNoteRepository::class)]
class MonthlyCaseNote
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $reason = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $familyStrength = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $recAndProgress = null;
#[ORM\ManyToOne(inversedBy: 'monthlyCaseNotes')]
#[ORM\JoinColumn(nullable: false)]
private ?MemberCase $memberCase = null;
#[ORM\Column(type: Types::DATE_MUTABLE)]
private ?\DateTimeInterface $date = null;
#[ORM\Column(type: Types::DATE_MUTABLE)]
private ?\DateTimeInterface $nextVisit = null;
public function getId(): ?Uuid
{
return $this->id;
}
public function getReason(): ?string
{
return $this->reason;
}
public function setReason(?string $reason): static
{
$this->reason = $reason;
return $this;
}
public function getFamilyStrength(): ?string
{
return $this->familyStrength;
}
public function setFamilyStrength(?string $familyStrength): static
{
$this->familyStrength = $familyStrength;
return $this;
}
public function getRecAndProgress(): ?string
{
return $this->recAndProgress;
}
public function setRecAndProgress(?string $recAndProgress): static
{
$this->recAndProgress = $recAndProgress;
return $this;
}
public function getMemberCase(): ?MemberCase
{
return $this->memberCase;
}
public function setMemberCase(?MemberCase $memberCase): static
{
$this->memberCase = $memberCase;
return $this;
}
public function getDate(): ?\DateTimeInterface
{
return $this->date;
}
public function setDate(\DateTimeInterface $date): static
{
$this->date = $date;
return $this;
}
public function getNextVisit(): ?\DateTimeInterface
{
return $this->nextVisit;
}
public function setNextVisit(\DateTimeInterface $nextVisit): static
{
$this->nextVisit = $nextVisit;
return $this;
}
}

View File

@ -1,13 +1,11 @@
<?php
namespace App\Entity;
namespace App\Entity\Case;
use App\Enums\NoteLocation;
use App\Enums\NoteMethod;
use App\Enums\NoteStatus;
use App\Repository\NoteRepository;
use DateTime;
use Doctrine\Common\Collections\Collection;
use App\Enums\Case\NoteLocation;
use App\Enums\Case\NoteMethod;
use App\Enums\Case\NoteStatus;
use App\Repository\Case\NoteRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\MappedSuperclass;
@ -39,18 +37,19 @@ class Note
#[ORM\Column(enumType: NoteStatus::class)]
private ?NoteStatus $status = null;
/**
* @var Collection<int, Member>
*/
#[ORM\OneToMany(targetEntity: Member::class, mappedBy: 'note')]
public Collection $members;
#[ORM\Column(enumType: NoteLocation::class)]
private ?NoteLocation $location = null;
#[ORM\Column(enumType: NoteMethod::class)]
private ?NoteMethod $method = null;
private ?array $members = null;
public function __construct()
{
$this->members = [];
}
public function getId(): ?UUid
{
return $this->id;
@ -116,37 +115,6 @@ class Note
return $this;
}
/**
* @return Collection<int, Member>
*/
public function getMembers(): Collection
{
return $this->members;
}
public function addUser(Member $member): static
{
if (!$this->members->contains($member)) {
$this->members->add($member);
}
return $this;
}
public function removeUser(Member $member): static
{
$this->members->removeElement($member);
return $this;
}
public function setMembers(?array $members): static
{
$this->members = $members;
return $this;
}
public function getLocation(): ?NoteLocation
{
return $this->location;
@ -171,6 +139,25 @@ class Note
return $this;
}
public function getMembers(): ?array
{
return $this->members;
}
public function setMembers(?array $members): static
{
$this->members = $members;
return $this;
}
public function addMember(Member $member): static
{
$this->members[] = $member;
return $this;
}
/**
* Method to calculate the number of minutes used for a visit rounded to the nearest 15 min increment
*

View File

@ -1,12 +1,10 @@
<?php
namespace App\Entity;
namespace App\Entity\Case;
use App\Enums\DischargeReason;
use App\Enums\ReferralServiceType;
use App\Repository\ReferralRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use App\Enums\Case\DischargeReason;
use App\Enums\Case\ReferralServiceType;
use App\Repository\Case\ReferralRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
@ -43,18 +41,6 @@ class Referral
#[ORM\Column(type: Types::DATE_MUTABLE, nullable: true)]
private ?\DateTimeInterface $dischargeDate = null;
/**
* @var Collection<int, Note>
*/
#[ORM\OneToMany(targetEntity: Note::class, mappedBy: 'referral', orphanRemoval: true)]
private Collection $notes;
/**
* @var Collection<int, Member>
*/
#[ORM\ManyToMany(targetEntity: Member::class)]
private Collection $present;
/**
* @var float $hoursUsed
*/
@ -65,8 +51,6 @@ class Referral
*/
public function __construct()
{
$this->notes = new ArrayCollection();
$this->present = new ArrayCollection();
$this->hoursUsed = 0.0;
}
@ -159,74 +143,13 @@ class Referral
return $this;
}
/**
* @return Collection<int, Note>
*/
public function getNotes(): Collection
{
return $this->notes;
}
public function addNote(Note $note): static
{
if (!$this->notes->contains($note)) {
$this->notes->add($note);
$note->setReferral($this);
$this->hoursUsed += ($note->calcTimeUsed() / 60);
}
return $this;
}
public function removeNote(Note $note): static
{
if ($this->notes->removeElement($note)) {
$this->hoursUsed -= $note->calcTimeUsed();
// set the owning side to null (unless already changed)
if ($note->getReferral() === $this) {
$note->setReferral(null);
}
}
return $this;
}
public function setNotes(ArrayCollection $notes): void
{
$this->notes = $notes;
$this->hoursUsed = 0.0;
foreach ($this->notes as $note) {
$this->hoursUsed += ($note->calcTimeUsed() / 60);
}
}
/**
* @return Collection<int, Member>
*/
public function getPresent(): Collection
{
return $this->present;
}
public function addPresent(Member $present): static
{
if (!$this->present->contains($present)) {
$this->present->add($present);
}
return $this;
}
public function removePresent(Member $present): static
{
$this->present->removeElement($present);
return $this;
}
public function getHoursRemaining(): float
{
return $this->hours - $this->hoursUsed;
}
public function getHoursUsed(): float
{
return $this->hoursUsed;
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Entity\Case;
use App\Enums\Case\ReferralServiceType;
use App\Repository\Case\StandardNoteRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable;
#[ORM\Entity(repositoryClass: StandardNoteRepository::class)]
class StandardNote extends Note implements JsonSerializable
{
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $note = null;
public function getNote(): ?string
{
return $this->note;
}
public function setNote(?string $note): static
{
$this->note = $note;
return $this;
}
public function jsonSerialize(): array
{
$members = [];
foreach ($this->getMembers() as $member) {
/** @var StandardNoteMember $member */
$members[] = $member->getPerson()->getName();
}
return [
'id' => $this->getId()->toString(),
'date' => $this->getDate()->format('M j, Y'),
'startTime' => $this->getStartTime()->format('g:i a'),
'endTime' => $this->getEndTime()->format('g:i a'),
'serviceCode' => $this->getReferral()->getServiceCode()->value,
'noteType' => ($this->getReferral()->getServiceCode() == ReferralServiceType::VS_THBB ? 'visit' : 'standard'),
'status' => $this->getStatus()->value,
'location' => $this->getLocation()->value,
'method' => ucwords(str_replace('_', ' ', strtolower($this->getMethod()->name))),
'members' => implode(', ', $members),
'duration' => $this->calcTimeUsed(),
];
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Entity\Case;
use App\Repository\Case\StandardNoteMemberRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: StandardNoteMemberRepository::class)]
class StandardNoteMember
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?StandardNote $note = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Member $person = null;
public function getId(): ?Uuid
{
return $this->id;
}
public function getStandardNote(): ?StandardNote
{
return $this->note;
}
public function setStandardNote(?StandardNote $note): static
{
$this->note = $note;
return $this;
}
public function getPerson(): ?Member
{
return $this->person;
}
public function setPerson(?Member $person): static
{
$this->person = $person;
return $this;
}
}

View File

@ -1,14 +1,16 @@
<?php
namespace App\Entity;
namespace App\Entity\Case;
use App\Enums\VisitQualityLevel;
use App\Repository\VisitNoteRepository;
use App\Enums\Case\ReferralServiceType;
use App\Enums\Case\VisitQualityLevel;
use App\Repository\Case\VisitNoteRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use JsonSerializable;
#[ORM\Entity(repositoryClass: VisitNoteRepository::class)]
class VisitNote extends Note
class VisitNote extends Note implements JsonSerializable
{
#[ORM\Column(type: Types::TEXT)]
private ?string $narrative = null;
@ -159,4 +161,36 @@ class VisitNote extends Note
return $this;
}
public function jsonSerialize(): array
{
$members = [];
foreach ($this->getMembers() as $member) {
/** @var VisitNoteMembers $member */
$members[] = $member->getPerson()->getName();
}
return [
'id' => $this->getId()->toString(),
'date' => $this->getDate()->format('M j, Y'),
'startTime' => $this->getStartTime()->format('g:i a'),
'endTime' => $this->getEndTime()->format('g:i a'),
'serviceCode' => $this->getReferral()->getServiceCode()->value,
'noteType' => ($this->getReferral()->getServiceCode() == ReferralServiceType::VS_THBB ? 'visit' : 'standard'),
'status' => $this->getStatus()->value,
'location' => $this->getLocation()->value,
'method' => ucwords(str_replace('_', ' ', strtolower($this->getMethod()->name))),
'narrative' => $this->getNarrative(),
'strengths' => $this->getStrengths(),
'issues' => $this->getIssues(),
'recommendation' => $this->getRecommendation(),
'parentalRole' => $this->getParentalRole(),
'childDevelopment' => $this->getChildDevelopment(),
'appropriateResponse' => $this->getAppropriateResponse(),
'childAheadOfSelf' => $this->getChildAheadOfSelf(),
'showsEmpathy' => $this->getShowsEmpathy(),
'childFocused' => $this->getChildFocused(),
'members' => implode(', ', $members),
'duration' => $this->calcTimeUsed(),
];
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Entity\Case;
use App\Repository\Case\VisitNoteMembersRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: VisitNoteMembersRepository::class)]
class VisitNoteMembers
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?VisitNote $note = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Member $person = null;
public function getId(): ?int
{
return $this->id;
}
public function getVisitNote(): ?VisitNote
{
return $this->note;
}
public function setVisitNote(?VisitNote $note): static
{
$this->note = $note;
return $this;
}
public function getPerson(): ?Member
{
return $this->person;
}
public function setPerson(?Member $person): static
{
$this->person = $person;
return $this;
}
}

View File

@ -1,13 +1,17 @@
<?php
namespace App\Entity;
namespace App\Entity\Company;
use App\Repository\CompanyRepository;
use App\Entity\System\User;
use App\Repository\Company\CompanyRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
use Vich\UploaderBundle\Entity\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
#[ORM\Entity(repositoryClass: CompanyRepository::class)]
class Company
@ -42,6 +46,15 @@ class Company
#[ORM\Column(length: 255, nullable: true)]
private ?string $url = null;
#[Vich\UploadableField(mapping: 'profile_image', fileNameProperty: 'imageName', size: 'size', mimeType: 'mimeType', originalName: 'originalName', dimensions: 'dimensions')]
private ?File $imageFile = null;
#[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
private ?string $companyLogo = null;
#[ORM\Column(length: 64)]
private ?string $vendorId = null;
/**
* @var Collection<int, User>
*/
@ -200,6 +213,42 @@ class Company
return $this;
}
public function getImageFile(): ?File
{
return $this->imageFile;
}
public function setImageFile(?File $imageFile): static
{
$this->imageFile = $imageFile;
return $this;
}
public function getCompanyLogo(): ?string
{
return $this->companyLogo;
}
public function setCompanyLogo(?string $companyLogo): static
{
$this->companyLogo = $companyLogo;
return $this;
}
public function getVendorId(): ?string
{
return $this->vendorId;
}
public function setVendorId(string $vendorId): static
{
$this->vendorId = $vendorId;
return $this;
}
public function __toString(): string
{
$url = ($this->url ? "<br/><a href='$this->url' target='_blank'>$this->url</a>" : '');

View File

@ -0,0 +1,139 @@
<?php
namespace App\Entity\Company;
use App\Enums\Company\DocumentExtras;
use App\Repository\Company\CompanyDocumentRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: CompanyDocumentRepository::class)]
class CompanyDocument
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Company $company = null;
#[ORM\Column(length: 255)]
private ?string $title = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $text = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $updated = null;
#[ORM\Column(type: Types::JSON, enumType: DocumentExtras::class, nullable: true)]
private array $extras = [];
private bool $selected = false;
public function getId(): ?Uuid
{
return $this->id;
}
public function getCompany(): ?Company
{
return $this->company;
}
public function setCompany(?Company $company): static
{
$this->company = $company;
return $this;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
public function getText(): ?string
{
return $this->text;
}
public function setText(?string $text): static
{
$this->text = $text;
return $this;
}
public function getUpdated(): ?\DateTimeInterface
{
return $this->updated;
}
public function setUpdated(\DateTimeInterface $updated): static
{
$this->updated = $updated;
return $this;
}
public function isSelected(): bool
{
return $this->selected;
}
public function setSelected(): static
{
$this->selected = true;
return $this;
}
public function getExtras(): array
{
return $this->extras;
}
public function setExtras(array $extras): static
{
$this->extras = $extras;
return $this;
}
public function inExtras(DocumentExtras $field): bool
{
return in_array($field, $this->extras);
}
public function renderHtml(): string
{
$text = $this->text;
if ($this->inExtras(DocumentExtras::EMAIL)) {
$text = str_replace('{{ email }}', "<input type='email' name='email' id='email' value='{{ doc.client.email }}'/>", $text);
$text = str_replace('{{ checkbox|email }}', "<input type='checkbox' name='emailClient' id='emailClient' value='1'/>", $text);
}
if ($this->inExtras(DocumentExtras::PHONE)) {
$text = str_replace('{{ phone }}', "<input type='tel' name='phone' id='phone' value='{{ doc.client.phone }}'/>", $text);
$text = str_replace('{{ checkbox|phone }}', "<input type='checkbox' name='callClient' id='callClient' value='1'/>", $text);
$text = str_replace('{{ checkbox|text }}', "<input type='checkbox' name='textClient' id='textClient' value='1'/>", $text);
}
return <<<HTML
$text
HTML;
}
}

View File

@ -1,11 +1,13 @@
<?php
namespace App\Entity;
namespace App\Entity\Resources;
use App\Enums\County;
use App\Enums\ResourceType;
use App\Enums\State;
use App\Repository\CommunityResourceRepository;
use App\Entity\System\Location;
use App\Enums\System\County;
use App\Enums\Case\ResourceType;
use App\Enums\System\State;
use App\Libs\Libs;
use App\Repository\Resources\CommunityResourceRepository;
use DateTime;
use DateTimeZone;
use Doctrine\DBAL\Types\Types;
@ -110,7 +112,7 @@ class CommunityResource
private ?float $lon = null;
public function __construct(
private DateTime $today = new DateTime('now', new DateTimeZone('America/New_York'))
private DateTime $today = new DateTime('now', new DateTimeZone('America/Indiana/Indianapolis'))
) {
}
@ -258,7 +260,7 @@ class CommunityResource
public function getContactCard(): ?string
{
$formattedPhone = ($this->phone ? '(' . substr($this->phone, 0, 3) . ') ' . substr($this->phone, 3, 3) . '-' . substr($this->phone, 6) : '');
$formattedPhone = ($this->phone ? Libs::formatPhone($this->phone) : '');
return ($this->email ? "<a href='mailto:$this->email'>$this->email</a><br/>" : '') .
($this->phone ? "<a href='tel:$this->phone'>$formattedPhone</a>" : '');
}
@ -309,8 +311,8 @@ class CommunityResource
return 'C';
}
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->monClose->format('H:i:s'));
if ($closeAt <= new DateTime()) {
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->monClose->format('H:i:s'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
if ($closeAt <= new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE']))) {
return 'C';
}
@ -347,8 +349,8 @@ class CommunityResource
return 'C';
}
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->tueClose->format('H:i:s'));
if ($closeAt <= new DateTime()) {
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->tueClose->format('H:i:s'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
if ($closeAt <= new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE']))) {
return 'C';
}
@ -385,8 +387,8 @@ class CommunityResource
return 'C';
}
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->wedClose->format('H:i:s'));
if ($closeAt <= new DateTime()) {
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->wedClose->format('H:i:s'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
if ($closeAt <= new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE']))) {
return 'C';
}
@ -423,8 +425,8 @@ class CommunityResource
return 'C';
}
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->thuClose->format('H:i:s'));
if ($closeAt <= new DateTime()) {
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->thuClose->format('H:i:s'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
if ($closeAt <= new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE']))) {
return 'C';
}
@ -461,8 +463,8 @@ class CommunityResource
return 'C';
}
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->friClose->format('H:i:s'));
if ($closeAt <= new DateTime()) {
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->friClose->format('H:i:s'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
if ($closeAt <= new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE']))) {
return 'C';
}
@ -499,8 +501,8 @@ class CommunityResource
return 'C';
}
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->satClose->format('H:i:s'));
if ($closeAt <= new DateTime()) {
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->satClose->format('H:i:s'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
if ($closeAt <= new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE']))) {
return 'C';
}
@ -537,8 +539,8 @@ class CommunityResource
return 'C';
}
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->sunClose->format('H:i:s'));
if ($closeAt <= new DateTime()) {
$closeAt = new DateTime($this->today->format('Y-m-d') . ' ' . $this->sunClose->format('H:i:s'), new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
if ($closeAt <= new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE']))) {
return 'C';
}
@ -547,7 +549,7 @@ class CommunityResource
public function getHours(): ?string
{
$this->today = new DateTime('now', new DateTimeZone('America/New_York'));
$this->today = new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE']));
switch ($this->today->format('w')) {
case 0:
return $this->sun();
@ -671,4 +673,30 @@ class CommunityResource
return $this;
}
public function _toInfoWindow(): string
{
return <<<EOL
{$this->name}<br/>
<a href='http://maps.google.com/?q={$this->lat},{$this->lon}'>{$this->address}<br/>
{$this->city}, {$this->state->value} {$this->zip}</a><br/>
{$this->servicesAvailable}<br/>
{$this->getContactCard()}
EOL;
}
public function toLocation(): Location
{
$loc = new Location();
$loc->setName($this->name)
->setAddress($this->address)
->setCity($this->city)
->setState($this->state)
->setZip($this->zip)
->setLat($this->lat)
->setLon($this->lon)
;
return $loc;
}
}

View File

@ -1,9 +1,10 @@
<?php
namespace App\Entity;
namespace App\Entity\Staff;
use App\Enums\ReferralServiceType;
use App\Repository\StaffNoteRepository;
use App\Entity\Case\MemberCase;
use App\Enums\Case\ReferralServiceType;
use App\Repository\Staff\StaffNoteRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

View File

@ -1,8 +1,9 @@
<?php
namespace App\Entity;
namespace App\Entity\Staff;
use App\Repository\SupervisionRepository;
use App\Entity\System\User;
use App\Repository\Staff\SupervisionRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;

View File

@ -1,26 +0,0 @@
<?php
namespace App\Entity;
use App\Repository\StandardNoteRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: StandardNoteRepository::class)]
class StandardNote extends Note
{
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $note = null;
public function getNote(): ?string
{
return $this->note;
}
public function setNote(?string $note): static
{
$this->note = $note;
return $this;
}
}

View File

@ -0,0 +1,140 @@
<?php
namespace App\Entity\System;
use App\Enums\System\State;
use App\Repository\System\LocationRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: LocationRepository::class)]
class Location
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\Column(length: 45)]
private ?string $name = null;
#[ORM\Column(length: 255)]
private ?string $address = null;
#[ORM\Column(length: 100, nullable: true)]
private ?string $city = null;
#[ORM\Column(length: 10, nullable: true)]
private ?State $state = null;
#[ORM\Column(nullable: true)]
private ?int $zip = null;
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 6, nullable: true)]
private ?string $lat = null;
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 6, nullable: true)]
private ?string $lon = null;
public function getId(): ?Uuid
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(string $address): static
{
$this->address = $address;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(?string $city): static
{
$this->city = $city;
return $this;
}
public function getState(): ?State
{
return $this->state;
}
public function setState(?State $state): static
{
$this->state = $state;
return $this;
}
public function getZip(): ?int
{
return $this->zip;
}
public function setZip(?int $zip): static
{
$this->zip = $zip;
return $this;
}
public function getFormattedAddress(): string
{
return "{$this->address}<br/>{$this->city}, {$this->state->value} {$this->zip}";
}
public function getLat(): ?string
{
return $this->lat;
}
public function setLat(?string $lat): static
{
$this->lat = $lat;
return $this;
}
public function getLon(): ?string
{
return $this->lon;
}
public function setLon(?string $lon): static
{
$this->lon = $lon;
return $this;
}
public function __toString(): string
{
return "{$this->address} {$this->city}, {$this->state->value} {$this->zip}";
}
}

View File

@ -1,9 +1,9 @@
<?php
namespace App\Entity;
namespace App\Entity\System;
use App\Enums\MessageType;
use App\Repository\MessagesRepository;
use App\Enums\System\MessageType;
use App\Repository\System\MessagesRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
@ -41,6 +41,9 @@ class Messages
#[ORM\JoinColumn(nullable: false)]
private ?User $sender = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $link = null;
public function getId(): ?Uuid
{
return $this->id;
@ -141,4 +144,16 @@ class Messages
'message' => $this->message
];
}
public function getLink(): ?string
{
return $this->link;
}
public function setLink(?string $link): static
{
$this->link = $link;
return $this;
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Entity;
namespace App\Entity\System;
use App\Repository\ReferralSourceRepository;
use App\Repository\System\ReferralSourceRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;

View File

@ -0,0 +1,86 @@
<?php
namespace App\Entity\System;
use App\Enums\System\UserSubscriptions;
use App\Repository\System\SubscriptionRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity(repositoryClass: SubscriptionRepository::class)]
class Subscription
{
#[ORM\Id]
#[ORM\Column(type: UuidType::NAME, unique: true)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private ?Uuid $id = null;
#[ORM\ManyToOne(inversedBy: 'subscriptions')]
#[ORM\JoinColumn(nullable: false)]
private ?User $user = null;
#[ORM\Column]
private ?bool $active = null;
#[ORM\Column(type: Types::DATE_MUTABLE)]
private ?\DateTimeInterface $expiration = null;
#[ORM\Column(enumType: UserSubscriptions::class)]
private ?UserSubscriptions $level = null;
public function getId(): ?Uuid
{
return $this->id;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): static
{
$this->user = $user;
return $this;
}
public function isActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): static
{
$this->active = $active;
return $this;
}
public function getExpiration(): ?\DateTimeInterface
{
return $this->expiration;
}
public function setExpiration(\DateTimeInterface $expiration): static
{
$this->expiration = $expiration;
return $this;
}
public function getLevel(): ?UserSubscriptions
{
return $this->level;
}
public function setLevel(UserSubscriptions $level): static
{
$this->level = $level;
return $this;
}
}

View File

@ -1,10 +1,11 @@
<?php
namespace App\Entity;
namespace App\Entity\System;
use App\Repository\UserRepository;
use App\Enums\RateType;
use App\Enums\CaseLevel;
use App\Entity\Company\Company;
use App\Repository\System\UserRepository;
use App\Enums\System\RateType;
use App\Enums\Case\CaseLevel;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
@ -14,10 +15,13 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Uid\Uuid;
use Vich\UploaderBundle\Entity\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_USERNAME', fields: ['username'])]
#[UniqueEntity(fields: ['username'], message: 'There is already an account with this username')]
#[Vich\Uploadable]
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
#[ORM\Id]
@ -60,29 +64,48 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Column(enumType: CaseLevel::class)]
private ?CaseLevel $level = null;
private ?User $supervisor = null;
#[ORM\Column]
private ?bool $caseWorker = null;
#[ORM\Column]
private ?bool $caseManager = null;
#[ORM\Column]
private ?bool $therapist = null;
#[ORM\Column]
private ?bool $su = null;
/**
* @var Collection<int, UserCase>
*/
#[ORM\OneToMany(targetEntity: UserCase::class, mappedBy: 'user')]
private Collection $userCases;
#[Vich\UploadableField(mapping: 'profile_image', fileNameProperty: 'imageName', size: 'size', mimeType: 'mimeType', originalName: 'originalName', dimensions: 'dimensions')]
private ?File $imageFile = null;
#[ORM\Column(type: Types::STRING, length: 255, nullable: true)]
private ?string $imageName = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $passwordChanged = null;
#[ORM\Column(length: 15, nullable: true)]
private ?string $personalPhone = null;
#[ORM\Column(length: 15)]
private ?string $workPhone = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $signature = null;
#[ORM\Column]
private ?bool $active = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $lastLogin = null;
private ?User $supervisor = null;
/**
* @var Collection<int, Subscription>
*/
#[ORM\OneToMany(targetEntity: Subscription::class, mappedBy: 'user', orphanRemoval: true)]
private Collection $subscriptions;
public function __construct()
{
$this->userCases = new ArrayCollection();
$this->subscriptions = new ArrayCollection();
}
public function getId(): ?Uuid
@ -240,36 +263,6 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
public function retrieveUnreadNotifications(): array
{
return [
[
'id' => 1,
'title' => 'Welcome',
'from' => 'Admin',
'type' => 'info',
'message' => 'Welcome to the dashboard.',
'timestamp' => new \DateTime('2024-11-12 10:00:00'),
],
[
'id' => 2,
'title' => 'New Case',
'from' => 'Admin',
'type' => 'info',
'message' => 'You have a new case.',
'timestamp' => new \DateTime('2024-11-13 10:19:56'),
],
[
'id' => 3,
'title' => 'New Message',
'from' => 'Admin',
'type' => 'warning',
'message' => 'You have a new message.',
'timestamp' => new \DateTime('2024-11-16 11:13:25'),
],
];
}
public function getSupervisor(): ?User
{
return $this->supervisor;
@ -284,71 +277,206 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
public function isCaseWorker(): ?bool
{
return $this->caseWorker;
}
public function setCaseWorker(bool $caseWorker): static
{
$this->caseWorker = $caseWorker;
return $this;
return in_array('ROLE_CASE_WORKER', $this->roles);
}
public function isCaseManager(): ?bool
{
return $this->caseManager;
}
public function setCaseManager(bool $caseManager): static
{
$this->caseManager = $caseManager;
return $this;
return in_array('ROLE_CASE_MANAGER', $this->roles);
}
public function isTherapist(): ?bool
{
return $this->therapist;
return in_array('ROLE_THERAPIST', $this->roles);
}
public function setTherapist(bool $therapist): static
public function isAdmin(): ?bool
{
$this->therapist = $therapist;
return $this;
}
public function isSu(): ?bool
{
return $this->su;
}
public function setSu(bool $su): static
{
$this->su = $su;
return $this;
return in_array('ROLE_ADMIN', $this->roles);
}
public function getJobs(): array
{
$jobs = [];
if ($this->caseWorker) {
if (in_array('ROLE_CASE_WORKER', $this->roles)) {
$jobs[] = 'Case Worker';
}
if ($this->caseManager) {
if (in_array('ROLE_CASE_MANAGER', $this->roles)) {
$jobs[] = 'Case Manager';
}
if ($this->therapist) {
if (in_array('ROLE_THERAPIST', $this->roles)) {
$jobs[] = 'Therapist';
}
if ($this->su) {
if (in_array('ROLE_ADMIN', $this->roles)) {
$jobs[] = 'Admin';
}
return $jobs;
}
public function getImageFile(): ?File
{
return $this->imageFile;
}
public function setImageFile(?File $imageFile): static
{
$this->imageFile = $imageFile;
return $this;
}
public function getImageName(): ?string
{
return $this->imageName;
}
public function setImageName(?string $imageName): static
{
$this->imageName = $imageName;
return $this;
}
public function getPasswordChanged(): ?\DateTimeInterface
{
return $this->passwordChanged;
}
public function setPasswordChanged(\DateTimeInterface $passwordChanged): static
{
$this->passwordChanged = $passwordChanged;
return $this;
}
public function getPersonalPhone(): ?string
{
return $this->personalPhone;
}
public function setPersonalPhone(?string $personalPhone): static
{
$this->personalPhone = $personalPhone;
return $this;
}
public function getWorkPhone(): ?string
{
return $this->workPhone;
}
public function setWorkPhone(string $workPhone): static
{
$this->workPhone = $workPhone;
return $this;
}
public function getFormattedPhone(): ?string
{
$ret = '';
if ($this->workPhone) {
$ret = '(' . substr($this->workPhone, 0, 3) . ') ' . substr($this->workPhone, 3, 3) . '-' . substr($this->workPhone, 6);
}
return $ret;
}
public function getSignature(): ?string
{
return $this->signature;
}
public function setSignature(?string $signature): static
{
$this->signature = $signature;
return $this;
}
public function isActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): static
{
$this->active = $active;
return $this;
}
public function getLastLogin(): ?\DateTimeInterface
{
return $this->lastLogin;
}
public function setLastLogin(?\DateTimeInterface $lastLogin): static
{
$this->lastLogin = $lastLogin;
return $this;
}
public function generateVCard(): string
{
list($fname, $lname) = explode(' ', $this->name, 2);
$b64image = null;
$fileExt = null;
if ($this->imageName) {
$fullFileName = dirname(dirname(__DIR__))."/public/{$_ENV['USER_IMAGE_PATH']}/{$this->imageName}";
$fileExt = strtoupper(pathinfo($fullFileName, PATHINFO_EXTENSION));
$b64image = base64_encode(
file_get_contents($fullFileName)
);
}
return 'BEGIN:VCARD' .
"\nVERSION:3.0" .
"\nN:{$lname};{$fname}" .
"\nFN:$this->name" .
"\nORG:{$this->company->getName()}" .
($this->workPhone ? "\nTEL;TYPE=WORK,VOICE:$this->workPhone" : null) .
($this->email ? "\nEMAIL;TYPE=WORK,INTERNET:$this->email" : null) .
"\nREV:" . date('c') .
($this->imageName ? "\nPHOTO;TYPE={$fileExt};ENCODING=b:{$b64image}" : null) .
"\nEND:VCARD";
}
/**
* @return Collection<int, Subscription>
*/
public function getSubscriptions(): Collection
{
return $this->subscriptions;
}
public function addSubscription(Subscription $subscription): static
{
if (!$this->subscriptions->contains($subscription)) {
$this->subscriptions->add($subscription);
$subscription->setUser($this);
}
return $this;
}
public function removeSubscription(Subscription $subscription): static
{
if ($this->subscriptions->removeElement($subscription)) {
// set the owning side to null (unless already changed)
if ($subscription->getUser() === $this) {
$subscription->setUser(null);
}
}
return $this;
}
}

View File

@ -1,9 +1,9 @@
<?php
namespace App\Entity;
namespace App\Entity\System;
use App\Enums\CaseLevel;
use App\Repository\UserCaseRepository;
use App\Entity\Case\MemberCase;
use App\Repository\System\UserCaseRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: UserCaseRepository::class)]

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum CaseLevel: int
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum DischargeReason: string
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum NoteLocation: string
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum NoteMethod: int
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum NoteStatus: string
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum RaceType: string
{

View File

@ -1,10 +1,11 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum ReferralServiceType: string
{
case FE_FF = 'FE-FF';
case VS_THBB = 'VS-THBB';
case VS_THBBT = 'VS-THBBT';
case VS_THBBCT = 'VS-THBBCT';
}

View File

@ -0,0 +1,9 @@
<?php
namespace App\Enums\Case;
enum ReferralType: string
{
case DCS = 'DCS';
case PO = 'PO';
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum RelationshipType: string
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum ResourceType: int
{
@ -9,4 +9,5 @@ enum ResourceType: int
case JOB_OPENINGS = 2;
case HOUSING = 3;
case PARENT_SUPPORT = 4;
case PLAY_AREA = 5;
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\Case;
enum VisitQualityLevel: int
{

View File

@ -0,0 +1,19 @@
<?php
namespace App\Enums\Company;
enum DocumentExtras: int
{
case CLIENT_NAME = 0;
case CLIENT_SIGNATURE = 1;
case NAMES = 2;
case EMAIL = 3;
case PHONE = 4;
case RELATIONSHIP = 5;
case DATE = 6;
case EVENT_DETAILS = 7;
case ACTION_TAKEN = 8;
case COMMENTS = 9;
case PROVIDER_NAME = 10;
case PROVIDER_SIGNATURE = 11;
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\System;
enum County: string
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\System;
enum GenderType: string
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\System;
enum JobType: string
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\System;
enum MessageType: int
{
@ -11,6 +11,7 @@ enum MessageType: int
case NEW_CASE = 4;
case USER = 5;
case NEW_REFERRAL = 6;
case STAFF_NOTE = 7;
case CALENDAR = 97;
case REMINDER = 98;
case UNKNOWN = 99;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\System;
enum RateType: string
{

View File

@ -1,6 +1,6 @@
<?php
namespace App\Enums;
namespace App\Enums\System;
enum State: string
{

View File

@ -0,0 +1,10 @@
<?php
namespace App\Enums\System;
enum UserSubscriptions: int
{
case Free = 0;
case Basic = 1;
case Pro = 2;
}

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