From 1788e8ddd756eec3b356b4fc091a03751822dda4 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 7 Oct 2022 12:49:05 +0200 Subject: [PATCH 1/5] db dump job --- .docker/Dockerfile | 6 +- src/server/server/config/boot_local.php | 2 +- .../job/TB_Server_Job_DailyDbBackup.php | 80 +++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 src/server/server/job/TB_Server_Job_DailyDbBackup.php diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 94210cb..733a4f0 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -12,13 +12,17 @@ RUN apt-get install -y \ libjpeg62-turbo-dev \ libpng-dev \ libicu-dev \ + libzip-dev \ + zip \ && docker-php-ext-install -j$(nproc) iconv \ && docker-php-ext-configure gd --with-jpeg=/usr/include/ --with-freetype=/usr/include/ \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install -j$(nproc) intl \ - && docker-php-ext-install -j$(nproc) pdo_mysql + && docker-php-ext-install -j$(nproc) pdo_mysql \ + && docker-php-ext-install zip RUN apt-get install -y git zip +RUN apt-get install mariadb-client -y RUN apt install nano diff --git a/src/server/server/config/boot_local.php b/src/server/server/config/boot_local.php index 67bbc4d..ce3c70f 100644 --- a/src/server/server/config/boot_local.php +++ b/src/server/server/config/boot_local.php @@ -21,7 +21,7 @@ Francis_Utils_Config::set( 'db.tbteamdata.pass', 'root' ); // Paths Francis_Utils_Config::set( 'path.logfile', '/var/www/html/logs/tbserver-log.txt' ); Francis_Utils_Config::set( 'path.cron_logfile', '/var/www/html/logs/tbserver-cron-log.txt' ); -Francis_Utils_Config::set( 'path.backup_folder', '/temp' ); +Francis_Utils_Config::set( 'path.backup_folder', '/var/www/html/temp' ); Francis_Utils_Config::set( 'path.root', realpath( dirname( __FILE__ ) . '/../../../..' ) ); Francis_Core_Autoloader::attachLocator( new Francis_Core_Locator( 'TB', Francis_Utils_Config::get( 'path.root' ) . '/src/server' ) ); Francis_Utils_Config::set( 'path.server.controller', Francis_Utils_Config::get( 'path.root' ) . '/src/server/server/control' ); diff --git a/src/server/server/job/TB_Server_Job_DailyDbBackup.php b/src/server/server/job/TB_Server_Job_DailyDbBackup.php new file mode 100644 index 0000000..2c1f86f --- /dev/null +++ b/src/server/server/job/TB_Server_Job_DailyDbBackup.php @@ -0,0 +1,80 @@ +entity = $jobEntity; + } + + public function execute() + { + // Remove old DB dumps + $dayInSeconds = 60 * 60 * 24; + $pastDays = 7; + $dumpFile = Francis_Utils_Config::get( 'path.backup_folder' ) . '/dbdump'; + while ( file_exists( $dumpFile . date( 'Y-m-d', ( time() - ( $pastDays * $dayInSeconds ) ) ) . '.zip' ) ) { + unlink( $dumpFile . date( 'Y-m-d', ( time() - ( $pastDays * $dayInSeconds ) ) ) . '.zip' ); + $pastDays++; + } + + // DB Core + $db_host = Francis_Utils_Config::get( 'db.tbcore.host' ); + $db_user = Francis_Utils_Config::get( 'db.tbcore.user' ); + $db_name = Francis_Utils_Config::get( 'db.tbcore.name' ); + $db_passwd = Francis_Utils_Config::get( 'db.tbcore.pass' ); + + $sql_file = Francis_Utils_Config::get( 'path.backup_folder' ) . "/tbcore.sql"; + //exec("mysql -u $db_name -p'$db_passwd' --allow-keywords --add-drop-table --complete-insert --quote-names --routines $db_name > $sql_file"); + exec("mysqldump -h $db_host -u $db_user -p'$db_passwd' $db_name > $sql_file"); + + // DB Teamdata + $db_host = Francis_Utils_Config::get( 'db.tbteamdata.host' ); + $db_user = Francis_Utils_Config::get( 'db.tbteamdata.user' ); + $db_name = Francis_Utils_Config::get( 'db.tbteamdata.name' ); + $db_passwd = Francis_Utils_Config::get( 'db.tbteamdata.pass' ); + + $sql_file = Francis_Utils_Config::get( 'path.backup_folder' ) . "/tbteamdata.sql"; + exec("mysqldump -h $db_host -u $db_user -p'$db_passwd' $db_name > $sql_file"); + //exec("mysql -u $db_name -p'$db_passwd' --allow-keywords --add-drop-table --complete-insert --quote-names --routines $db_name > $sql_file"); + + // Zip + $zipFilename = Francis_Utils_Config::get( 'path.backup_folder' ) . '/dbdump' . date( 'Y-m-d' ) . '.zip'; + $zip = new ZipArchive(); + if ( !$zip->open( $zipFilename, ZipArchive::CREATE ) ) { + TB_Server_Utils_Log::get()->log( "Cannot zip db dump." ); + return; + } + $zip->addFile( Francis_Utils_Config::get( 'path.backup_folder' ) . '/tbcore.sql' , 'tbcore.sql' ); + $zip->addFile( Francis_Utils_Config::get( 'path.backup_folder' ) . '/tbteamdata.sql' , 'tbteamdata.sql' ); + $zip->close(); + + // Cleanup + $sql_file = Francis_Utils_Config::get( 'path.backup_folder' ) . "/tbcore.sql"; + unlink( $sql_file ); + $sql_file = Francis_Utils_Config::get( 'path.backup_folder' ) . "/tbteamdata.sql"; + unlink( $sql_file ); + echo 'bla'; + } + + public function onDone() + { + // Reset event to start the next day + $nowDt = new DateTime( 'now', new \DateTimeZone( "UTC" ) ); + $nowDt->setTime( 2, 0, 0 ); + $nowDt->modify( '+1 day' ); + $this->entity->trigger_dt = $nowDt; + $this->entity->job_status = TB_Shared_Ent_TeamData_Job::JOB_STATUS_READY; + $this->entity->touch( 'job_status' ); + $this->entity->save(); + } + + public static function getRefId() + { + return 'system-daily-db-backup'; + } +} \ No newline at end of file From 9d674532038e01d9d690a06065f189c2965f44db Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 1 Nov 2022 15:34:40 +0100 Subject: [PATCH 2/5] conflict solved --- src/server/server/config/boot_local.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/server/config/boot_local.php b/src/server/server/config/boot_local.php index ce3c70f..840811e 100644 --- a/src/server/server/config/boot_local.php +++ b/src/server/server/config/boot_local.php @@ -21,7 +21,9 @@ Francis_Utils_Config::set( 'db.tbteamdata.pass', 'root' ); // Paths Francis_Utils_Config::set( 'path.logfile', '/var/www/html/logs/tbserver-log.txt' ); Francis_Utils_Config::set( 'path.cron_logfile', '/var/www/html/logs/tbserver-cron-log.txt' ); + Francis_Utils_Config::set( 'path.backup_folder', '/var/www/html/temp' ); + Francis_Utils_Config::set( 'path.root', realpath( dirname( __FILE__ ) . '/../../../..' ) ); Francis_Core_Autoloader::attachLocator( new Francis_Core_Locator( 'TB', Francis_Utils_Config::get( 'path.root' ) . '/src/server' ) ); Francis_Utils_Config::set( 'path.server.controller', Francis_Utils_Config::get( 'path.root' ) . '/src/server/server/control' ); From 799be5c41ea0f1c9c431d612d42a444f6432a4ea Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 2 Nov 2022 17:51:00 +0100 Subject: [PATCH 3/5] manager stuff --- README.md | 4 +- src/client/app/js/app/core/Dict.js | 3 +- .../ContractAppointmentAssignDualList.js | 9 +++ .../js/app/views/contract/ContractCharging.js | 1 - .../js/app/views/contract/ContractEdit.js | 73 +++++++++++++++++-- .../js/app/views/contract/contract-edit.html | 52 +++++++++++++ .../views/contract/contract-master-data.html | 43 +++++++++++ .../control/TB_Server_Control_Contract.php | 28 ++++++- .../server/control/TB_Server_Control_Team.php | 11 ++- .../TB_Shared_Ent_TeamData_Appointment.php | 2 +- .../TB_Shared_Ent_TeamData_Contract.php | 6 ++ 11 files changed, 221 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f556ba1..85f54e0 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,6 @@ - info@coaching4dogs.xx (kein Admin-Account) - benny@probuddy.de - timo@tbuddy.de - - tretslag@gmail.com \ No newline at end of file + - tretslag@gmail.com +- `docker exec -it pb-php /bin/bash` +- SELECT * FROM profile WHERE JSON_CONTAINS( `teams_js`, '{"team_id":"75"}' ); \ No newline at end of file diff --git a/src/client/app/js/app/core/Dict.js b/src/client/app/js/app/core/Dict.js index b6964a5..ba385ed 100644 --- a/src/client/app/js/app/core/Dict.js +++ b/src/client/app/js/app/core/Dict.js @@ -541,7 +541,8 @@ app.core.Dict = { "APPOINTMENT_CATEGORIES_MISSING_FOR_ADMIN" : "Deinem Gruppenprofil wurden keine Kategorien zugewiesen. Bitte benachrichtige den Gruppeninhaber.", "NOTE_NO_SERIAL_APPOINTMENT_EDITING_AFTER_PUBLISHING" : "Hinweis: Serientermine können nach ihrer Veröffentlichung nur noch einzelnd bearbeitet werden.", "STATS_REPORTING" : 'Reporting', - 'STATS_PLANNING' : 'Planung' + 'STATS_PLANNING' : 'Planung', + "DO_YOU_REALLY_WANT_TO_DELETE_THIS_CONTRACT" : "Möchtest Du diesen Vertrag wirklich löschen?", }, "en" : { } diff --git a/src/client/manager/js/app/components/contract/ContractAppointmentAssignDualList.js b/src/client/manager/js/app/components/contract/ContractAppointmentAssignDualList.js index e119ee6..ef84a3a 100644 --- a/src/client/manager/js/app/components/contract/ContractAppointmentAssignDualList.js +++ b/src/client/manager/js/app/components/contract/ContractAppointmentAssignDualList.js @@ -12,6 +12,11 @@ const ContractAppointmentAssignDualList = { self.contracts = props.get( 'contracts'); self.attendedAppointments = props.get( 'attendedAppointments' ); + self.childObj = {}; + for (const prop in profile.child_profile_js) { + self.childObj[profile.child_profile_js[prop]['id']] = profile.child_profile_js[prop]['name']; + } + this.render( { profile : profile, @@ -131,6 +136,10 @@ const ContractAppointmentAssignDualList = { } aSubject += a.subject + ', ' + moment( a.start_dt ).format( 'DD.MM.YYYY' ); + if (a.attendee_child_id !== null) { + aSubject += ' (' + self.childObj[a.attendee_child_id] + ')'; + } + if ( self.selectedContractId && self.attendedAppointments[ aai ].contractId == self.selectedContractId ) { $select.append( diff --git a/src/client/manager/js/app/views/contract/ContractCharging.js b/src/client/manager/js/app/views/contract/ContractCharging.js index d3f9fd5..ef3b0d6 100644 --- a/src/client/manager/js/app/views/contract/ContractCharging.js +++ b/src/client/manager/js/app/views/contract/ContractCharging.js @@ -30,7 +30,6 @@ const ContractCharging = { break; } } - return m; } diff --git a/src/client/manager/js/app/views/contract/ContractEdit.js b/src/client/manager/js/app/views/contract/ContractEdit.js index fcf97a9..f504ea0 100644 --- a/src/client/manager/js/app/views/contract/ContractEdit.js +++ b/src/client/manager/js/app/views/contract/ContractEdit.js @@ -21,8 +21,7 @@ const ContractEdit = { self = this; self.contract = null; - - this.render( { groupId : groupId } ); + self.contractIsDeletable = false; app.rpc.call( 'Contract', @@ -32,11 +31,16 @@ const ContractEdit = { }, function( res ) { - if ( res && res.hasOwnProperty( 'data' ) && res.data.hasOwnProperty( 'contractData' ) ) + if ( res && res.hasOwnProperty( 'data' )) { - self.contract = self.createInstance( 'Contract', res.data.contractData ); + if ( res.data.hasOwnProperty( 'contractData' ) ) { + self.contract = self.createInstance( 'Contract', res.data.contractData ); + } + if ( res.data.hasOwnProperty( 'contractIsDeletable' ) ) { + self.contractIsDeletable = res.data.contractIsDeletable; + } } - + this.render( { groupId : groupId, contractIsDeletable: self.contractIsDeletable } ); const $compContractForm = self.createComponent( 'contract-form', $container.find( '[f-id="container-contract-form"]' ).first().get( 0 ), @@ -89,10 +93,69 @@ const ContractEdit = { } }); + if (self.contractIsDeletable) { + $container.find( '[data-id="btnDeleteContract"]').click( function() + { + + let $modalRoot = $container.find( '[data-id="modal-confirm-delete-contract"]' ).first(); + $modalRoot.find( '[data-id="section-confirm-delete-contract"]' ).first().show(); + $modalRoot.find( '[data-id="section-loader"]' ).first().hide(); + $modalRoot.on( 'shown.bs.modal', function() + { + $modalRoot.find( '[data-id="btnDelete"]' ).first().off( "click" ); + $modalRoot.find( '[data-id="btnDelete"]' ).first().click( function() + { + $(this).off( "click" ); + + $modalRoot.find( '[data-id="section-confirm-delete-contract"]' ).first().hide(); + $modalRoot.find( '[data-id="section-loader"]' ).first().show(); + + app.rpc.call( + 'Contract', + 'delete', + { + contractId : contractId + }, + function( resp ) + { + if ( resp && resp.hasOwnProperty( 'code' ) && resp.code == 200 ) + { + app.UI.toastSuccess( 'Vertrag wurde erfolgreich gelöscht.', 'Vertrag gelöscht' ); + if ( redirectPath ) + { + app.redirect( redirectPath ); + } + else + { + app.redirect( 'contract/list/' + groupId ); + } + } + else + { + app.UI.toastError( 'Der Vertrag konnte nicht gelöscht werden, ' + + 'da er entweder mindestens eine verknüpfte Verrechnung oder bereits ' + + 'eine Einzahlung stattgefunden hat', + 'Fehler' ); + } + $modalRoot.modal( 'hide' ); + } + ); + }); + }); + $modalRoot.on( 'hidden.bs.modal', function() + { + $modalRoot.modal( 'dispose' ); + }); + $modalRoot.modal( 'show' ); + } + ); + } + $container.find( '.sk-loading' ).toggleClass( 'sk-loading' ); }.bind ( this ) ); + }, destroy : function() diff --git a/src/client/manager/js/app/views/contract/contract-edit.html b/src/client/manager/js/app/views/contract/contract-edit.html index 175c69c..63669f3 100644 --- a/src/client/manager/js/app/views/contract/contract-edit.html +++ b/src/client/manager/js/app/views/contract/contract-edit.html @@ -40,10 +40,62 @@ href="javascript:history.back()"> Abbrechen + <% if ( true === contractIsDeletable ) { %> + + <% } %> + + + \ No newline at end of file diff --git a/src/client/manager/js/app/views/contract/contract-master-data.html b/src/client/manager/js/app/views/contract/contract-master-data.html index 9cce9fb..95dd320 100644 --- a/src/client/manager/js/app/views/contract/contract-master-data.html +++ b/src/client/manager/js/app/views/contract/contract-master-data.html @@ -118,6 +118,49 @@ +
+ +
+ +
+
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
diff --git a/src/server/server/control/TB_Server_Control_Contract.php b/src/server/server/control/TB_Server_Control_Contract.php index 5e6dece..1c6fdfc 100644 --- a/src/server/server/control/TB_Server_Control_Contract.php +++ b/src/server/server/control/TB_Server_Control_Contract.php @@ -151,7 +151,7 @@ class TB_Server_Control_Contract { $resp->addData( 'contractAppointments', [] ); } - + $resp->addData('contractIsDeletable', $contract->isDeletable()); return $resp; } @@ -515,6 +515,32 @@ class TB_Server_Control_Contract return $resp; } + public static function delete( TB_Server_Core_RequestData $params ) + { + $resp = new TB_Server_Core_Response(); + + $sessionProfile = TB_Server_Core_Session::get()->getProfile(); + $contractId = $params->get('contractId' ); + $contract = TB_Shared_Ent_TeamData_Contract::get( $contractId ); + if ( NULL === $contract ) + { + throw new \Exception( 'Contract not found.' ); + } + + if ( false === $sessionProfile->isAdminOfTeam( $contract->team_id ) && $sessionProfile->id != $contract->profile_id ) + { + throw new \Exception('Profile is not allowed to delete contract'); + } + if ( !$contract->isDeletable() ) + { + throw new \Exception('Contract is not deletable'); + } + + $contract->delete(); + + return $resp; + } + public static function updateAttendances( TB_Server_Core_RequestData $params ) { $resp = new TB_Server_Core_Response(); diff --git a/src/server/server/control/TB_Server_Control_Team.php b/src/server/server/control/TB_Server_Control_Team.php index 0103561..1f1c89c 100644 --- a/src/server/server/control/TB_Server_Control_Team.php +++ b/src/server/server/control/TB_Server_Control_Team.php @@ -912,6 +912,11 @@ class TB_Server_Control_Team { $cZipCode = $params->get( 'zip_code' ); $cCity = $params->get( 'city' ); $cCountry = $params->get( 'country' ); + $cBankCode = $params->get( 'bank_code' ); + $cAccountNumber = $params->get( 'account_number' ); + $cBankName = $params->get( 'bank_name' ); + $cPaypalMe = $params->get( 'paypal_me' ); + if ( !$cName || !$cStreet || !$cZipCode || !$cCity || !$cCountry ) { @@ -923,7 +928,11 @@ class TB_Server_Control_Team { 'street' => $cStreet, 'zip_code' => $cZipCode, 'city' => $cCity, - 'country' => $cCountry + 'country' => $cCountry, + 'bank_code' => $cBankCode, + 'account_number' => $cAccountNumber, + 'bank_name' => $cBankName, + 'paypal_me' => $cPaypalMe ); $team->save(); diff --git a/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php b/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php index aca5285..a552eee 100644 --- a/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php +++ b/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php @@ -514,7 +514,7 @@ class TB_Shared_Ent_TeamData_Appointment extends Francis_Db_Row public static function getTeamAppointmentsForAttendedProfileId( $teamId, $profileId ) { - $sql = 'SELECT a.id AS `attendee_id`, a.contract_id AS `attendee_contract_id`, app.* FROM `attendee` AS a '; + $sql = 'SELECT a.id AS `attendee_id`, a.contract_id AS `attendee_contract_id`, a.`profile_child_id` AS `attendee_child_id`, app.* FROM `attendee` AS a '; $sql .= 'LEFT JOIN appointment AS `app` ON a.appointment_id = app.id '; $sql .= 'WHERE '; $sql .= 'app.team_id = :team_id AND a.profile_id = :profile_id AND '; diff --git a/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Contract.php b/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Contract.php index f39e39d..1c82151 100644 --- a/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Contract.php +++ b/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Contract.php @@ -218,6 +218,12 @@ class TB_Shared_Ent_TeamData_Contract extends Francis_Db_Row TB_Shared_Ent_TeamData_Attendee::removeContractId( $this->id ); } + public function isDeletable() + { + $attendees = TB_Shared_Ent_TeamData_Attendee::getAttendancesForContractId( $this->id ); + return (int) $this->price_payed === 0 && count($attendees) === 0; + } + /** * Return table name * From 9f071c26a5d8b6fe8079d089bdb713c0e7cc2546 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 7 Nov 2022 18:00:30 +0100 Subject: [PATCH 4/5] manager console contract management improvements --- .../ContractUnchargedMemberDataTable.js | 24 +++++- .../contract-uncharged-member-data-table.html | 10 ++- .../components/settings/AccessDataTable.js | 2 +- .../js/app/views/contract/ContractCharging.js | 85 +++++++++++-------- .../TB_Shared_Ent_TeamData_Contract.php | 1 - 5 files changed, 82 insertions(+), 40 deletions(-) diff --git a/src/client/manager/js/app/components/contract/ContractUnchargedMemberDataTable.js b/src/client/manager/js/app/components/contract/ContractUnchargedMemberDataTable.js index c01d50b..729f8f9 100644 --- a/src/client/manager/js/app/components/contract/ContractUnchargedMemberDataTable.js +++ b/src/client/manager/js/app/components/contract/ContractUnchargedMemberDataTable.js @@ -8,7 +8,7 @@ const ContractUnchargedMemberDataTable = { this.render( { ui: props.get( 'unchargedItems' ), activeGroup : groupId } ); - $container.find( '.datatable' ).DataTable( { + let table = $container.find( '.datatable' ).DataTable( { pageLength: 50, responsive: true, dom: '<"html5buttons"B>lTfgitp', @@ -49,6 +49,28 @@ const ContractUnchargedMemberDataTable = { { app.redirect( '/contract/charge-appointment/' + groupId + '/' + $( e.currentTarget ).attr( 'data-member-id' ) ); }); + + $('input.filterContract').on('change', function() { + table.draw(); + }); + + $('input.filterOpenClaim').on('change', function() { + table.draw(); + }); + + $.fn.dataTable.ext.search.push( + function(settings, searchData, index, rowData, counter) { + if ($('.filterContract:checked').length === 1) { + // @Todo: this hardcoded index is sth to refactor (but haven't column as object yet) + return rowData[6] === 'nein'; + } + if ($('.filterOpenClaim:checked').length === 1) { + // @Todo: this hardcoded index is sth to refactor (but haven't column as object yet) + return parseInt(rowData[5]) !== 0 ; + } + return true; + } + ); }, destroy : function() diff --git a/src/client/manager/js/app/components/contract/contract-uncharged-member-data-table.html b/src/client/manager/js/app/components/contract/contract-uncharged-member-data-table.html index 4936142..c6cee46 100644 --- a/src/client/manager/js/app/components/contract/contract-uncharged-member-data-table.html +++ b/src/client/manager/js/app/components/contract/contract-uncharged-member-data-table.html @@ -1,4 +1,6 @@
+ + @@ -8,6 +10,7 @@ + @@ -19,7 +22,7 @@ <%= ui[ i ].member ? ui[ i ].member.id : '-' %> - + <% } %> diff --git a/src/client/manager/js/app/components/settings/AccessDataTable.js b/src/client/manager/js/app/components/settings/AccessDataTable.js index 0131ea9..ab34db3 100644 --- a/src/client/manager/js/app/components/settings/AccessDataTable.js +++ b/src/client/manager/js/app/components/settings/AccessDataTable.js @@ -36,7 +36,7 @@ const AccessDataTable = { }, }, buttons: [ - { extend: 'copy'}, + {extend: 'copy'}, {extend: 'csv'}, {extend: 'excel', title: 'Mitgliederliste'}, {extend: 'pdf', title: 'Mitgliederliste'}, diff --git a/src/client/manager/js/app/views/contract/ContractCharging.js b/src/client/manager/js/app/views/contract/ContractCharging.js index ef3b0d6..8ec54e1 100644 --- a/src/client/manager/js/app/views/contract/ContractCharging.js +++ b/src/client/manager/js/app/views/contract/ContractCharging.js @@ -16,6 +16,7 @@ const ContractCharging = { app = this.app, members = [], groupId = p.get( 'groupId' ), + profileIdsWithActiveContract = [], self = this; function getMemberById( mId ) @@ -55,49 +56,63 @@ const ContractCharging = { app.rpc.call( 'Contract', - 'getUnchargedProfileIds', + 'getList', { - teamId : groupId + teamId : groupId, + state : 'active' }, - function( res ) - { - let unchargedItems = [], - memberIdsInList = []; - if ( res && res.hasOwnProperty( 'data' ) && res.data.hasOwnProperty( 'unchargedProfileIds' ) ) - { - const up = res.data.unchargedProfileIds; - for( let upi = 0; upi < up.length; upi++ ) - { - memberIdsInList.push( +up[ upi ].profile_id ); - unchargedItems.push({ - member : getMemberById( up[ upi ].profile_id ), - count : up[ upi ].cnt - }); + function( res ) { + if (res && res.hasOwnProperty('data') && res.data.hasOwnProperty('contractData')) { + const cs = res.data.contractData; + for (let ci = 0; ci < cs.length; ci++) { + profileIdsWithActiveContract[cs[ci]['profile_id']] = 1; } } - for ( let mi = 0; mi < members.length; mi++ ) - { - if ( -1 === memberIdsInList.indexOf( +members[ mi ].id ) ) + app.rpc.call( + 'Contract', + 'getUnchargedProfileIds', { - unchargedItems.push({ - member : members[ mi ], - count : 0 - }); - } - } + teamId: groupId + }, + function (res) { + let unchargedItems = [], + memberIdsInList = []; + if (res && res.hasOwnProperty('data') && res.data.hasOwnProperty('unchargedProfileIds')) { + const up = res.data.unchargedProfileIds; + for (let upi = 0; upi < up.length; upi++) { + memberIdsInList.push(+up[upi].profile_id); + unchargedItems.push({ + member: getMemberById(up[upi].profile_id), + count: up[upi].cnt, + hasActiveContract: profileIdsWithActiveContract.hasOwnProperty(up[upi].profile_id) + }); + } + } - let st = self.createComponent( - 'contract-uncharged-member-data-table', - $container.find( '[f-id="container-contract-uncharged-member-table"]' ).first().get( 0 ), - { - unchargedItems : unchargedItems, - groupId : groupId - } - ); + for (let mi = 0; mi < members.length; mi++) { + if (-1 === memberIdsInList.indexOf(+members[mi].id)) { + unchargedItems.push({ + member: members[mi], + count: 0, + hasActiveContract: -1 !== profileIdsWithActiveContract.indexOf(+members[mi].id) + }); + } + } - $container.find( '.sk-loading' ).toggleClass( 'sk-loading' ); - }.bind ( this ) + let st = self.createComponent( + 'contract-uncharged-member-data-table', + $container.find('[f-id="container-contract-uncharged-member-table"]').first().get(0), + { + unchargedItems: unchargedItems, + groupId: groupId + } + ); + + $container.find('.sk-loading').toggleClass('sk-loading'); + }.bind(this) + ); + } ); } } diff --git a/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Contract.php b/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Contract.php index 1c82151..e948c83 100644 --- a/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Contract.php +++ b/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Contract.php @@ -168,7 +168,6 @@ class TB_Shared_Ent_TeamData_Contract extends Francis_Db_Row $sql .= "AND app.state = 'open' "; $sql .= 'AND app.start_dt < NOW() '; $sql .= 'AND a.has_attended = "attended" AND a.contract_id IS NULL GROUP BY a.profile_id'; - $dbh = self::getDbh(); $stmt = $dbh->prepare( $sql ); From 90e96ddbe099e840d15584fef0d26b1621568974 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 8 Nov 2022 16:57:45 +0100 Subject: [PATCH 5/5] filter appointments --- .../appointments/AppointmentSelectTable.js | 53 ++++++++++++++++++- .../appointment-select-table.html | 2 + .../ContractUnchargedMemberDataTable.js | 20 ++++--- .../contract-uncharged-member-data-table.html | 8 +-- .../app/views/appointments/AppointmentList.js | 2 + .../TB_Shared_Ent_TeamData_Appointment.php | 2 + 6 files changed, 74 insertions(+), 13 deletions(-) diff --git a/src/client/manager/js/app/components/appointments/AppointmentSelectTable.js b/src/client/manager/js/app/components/appointments/AppointmentSelectTable.js index 3fdd8c4..50fbedb 100644 --- a/src/client/manager/js/app/components/appointments/AppointmentSelectTable.js +++ b/src/client/manager/js/app/components/appointments/AppointmentSelectTable.js @@ -5,9 +5,33 @@ const AppointmentSelectTable = { var app = this.app, $container = $( this.container ); - this.render( { apps: appointments.getAll(), activeGroup : this.app.user.getActiveGroup() } ); + let date = new Date(); + let strFrom = ''; + date.setMonth(date.getMonth() - 3); + let dd = String(date.getDate()).padStart(2, '0'); + let mm = String(date.getMonth() + 1).padStart(2, '0'); //January is 0! + let yyyy = date.getFullYear(); + strFrom = yyyy + '-' + mm + '-' + dd; - $container.find( '.datatable' ).DataTable( { + date = new Date(); + let strTo = ''; + date.setMonth(date.getMonth() + 3); + dd = String(date.getDate()).padStart(2, '0'); + mm = String(date.getMonth() + 1).padStart(2, '0'); //January is 0! + yyyy = date.getFullYear(); + strTo = yyyy + '-' + mm + '-' + dd; + + let appointmentItems = appointments.getAll(); + + this.render( + { apps: appointmentItems, + activeGroup : this.app.user.getActiveGroup(), + strFrom: strFrom, + strTo: strTo + } + ); + + let table = $container.find( '.datatable' ).DataTable( { pageLength: 50, responsive: true, dom: '<"html5buttons"B>lTfgitp', @@ -78,6 +102,31 @@ const AppointmentSelectTable = { app.openInApp( '/#/appointment/' + $( this ).attr( 'data-appointment-id' ) + '/chat' ); e.stopPropagation(); }); + + $('input.dateStart').on('change', function() { + table.draw(); + }); + + $('input.dateEnd').on('change', function() { + table.draw(); + }); + + $.fn.dataTable.ext.search.push( + function(settings, searchData, index, rowData, counter) { + const dateFrom = $('input.dateStart').val(); + const dateTo = $('input.dateEnd').val(); + const item = appointmentItems[index]; + const startDate = item['start_dt']; + const strStartDate = startDate.date.substring(0,10); + + if (strStartDate >= dateFrom && strStartDate <= dateTo) { + return true; + } + return false; + } + ); + // Initial drawing needed to filter by date interval + table.draw(); }, getSelectedIds : function() diff --git a/src/client/manager/js/app/components/appointments/appointment-select-table.html b/src/client/manager/js/app/components/appointments/appointment-select-table.html index e18f43e..21812c8 100644 --- a/src/client/manager/js/app/components/appointments/appointment-select-table.html +++ b/src/client/manager/js/app/components/appointments/appointment-select-table.html @@ -1,4 +1,6 @@
+ +
PLZ Stadt Offene VerrechnungenAktiver Vertrag vorhanden
- <%= ui[ i ].member ? ui[ i ].member.getName() : '[gelöscht]' %> + <%= ui[ i ].member ? ui[ i ].member.getName() : '[gelöscht - nicht mehr Mitglied der Gruppe]' %> <%= ui[ i ].member && ui[ i ].member.street ? ui[ i ].member.street : '---' %> @@ -30,9 +33,12 @@ <%= ui[ i ].member && ui[ i ].member.city ? ui[ i ].member.city : '---' %> + <%= ui[ i ].count %> + <%= ui[ i ].hasActiveContract ? 'ja' : 'nein' %> +
diff --git a/src/client/manager/js/app/components/contract/ContractUnchargedMemberDataTable.js b/src/client/manager/js/app/components/contract/ContractUnchargedMemberDataTable.js index 729f8f9..91ba5f7 100644 --- a/src/client/manager/js/app/components/contract/ContractUnchargedMemberDataTable.js +++ b/src/client/manager/js/app/components/contract/ContractUnchargedMemberDataTable.js @@ -4,9 +4,11 @@ const ContractUnchargedMemberDataTable = { { var app = this.app, groupId = props.get( 'groupId' ), + items = props.get( 'unchargedItems' ), $container = $( this.container ); - this.render( { ui: props.get( 'unchargedItems' ), activeGroup : groupId } ); + this.render( { ui: items, activeGroup : groupId } ); + let table = $container.find( '.datatable' ).DataTable( { pageLength: 50, @@ -60,13 +62,17 @@ const ContractUnchargedMemberDataTable = { $.fn.dataTable.ext.search.push( function(settings, searchData, index, rowData, counter) { - if ($('.filterContract:checked').length === 1) { - // @Todo: this hardcoded index is sth to refactor (but haven't column as object yet) - return rowData[6] === 'nein'; + const contractChecked = $('.filterContract:checked').length === 1; + const openClaimChecked = $('.filterOpenClaim:checked').length === 1; + const item = items[index]; + if (contractChecked && openClaimChecked) { + return item['hasActiveContract'] === false && parseInt(item['count']) !== 0; + } + if (contractChecked) { + return item['hasActiveContract'] === false; } - if ($('.filterOpenClaim:checked').length === 1) { - // @Todo: this hardcoded index is sth to refactor (but haven't column as object yet) - return parseInt(rowData[5]) !== 0 ; + if (openClaimChecked) { + return parseInt(item['count']) !== 0; } return true; } diff --git a/src/client/manager/js/app/components/contract/contract-uncharged-member-data-table.html b/src/client/manager/js/app/components/contract/contract-uncharged-member-data-table.html index c6cee46..2323a23 100644 --- a/src/client/manager/js/app/components/contract/contract-uncharged-member-data-table.html +++ b/src/client/manager/js/app/components/contract/contract-uncharged-member-data-table.html @@ -1,6 +1,6 @@
- - + +
@@ -10,7 +10,7 @@ - + @@ -36,7 +36,7 @@ - diff --git a/src/client/manager/js/app/views/appointments/AppointmentList.js b/src/client/manager/js/app/views/appointments/AppointmentList.js index 5dee478..40e6a47 100644 --- a/src/client/manager/js/app/views/appointments/AppointmentList.js +++ b/src/client/manager/js/app/views/appointments/AppointmentList.js @@ -59,6 +59,8 @@ const AppointmentList = { } } + + let compAst = this.createComponent( 'appointment-select-table', $container.find( '[f-id="container-appointment-data-table"]' ).first().get( 0 ), diff --git a/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php b/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php index a552eee..fcb2902 100644 --- a/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php +++ b/src/server/shared/ent/teamdata/TB_Shared_Ent_TeamData_Appointment.php @@ -250,6 +250,8 @@ class TB_Shared_Ent_TeamData_Appointment extends Francis_Db_Row if ( false === $filterGetOld ) { $sql .= "AND end_dt > UTC_TIMESTAMP() "; + } else { + $sql .= "AND end_dt > UTC_TIMESTAMP() - INTERVAL 1 MONTH "; } $sql .= "ORDER BY start_dt ASC"; $stmt = $dbh->prepare( $sql );
PLZ Stadt Offene VerrechnungenAktiver Vertrag vorhandenAktiver Vertrag vorhanden
<%= ui[ i ].count %> + <%= ui[ i ].hasActiveContract ? 'ja' : 'nein' %>