浏览代码

Add a page to modify patient information

Fabrice 2 年之前
父节点
当前提交
28f8842d22

+ 4 - 0
api.ipsocloud.com/api/v1/IIMTAPI.class.php

@@ -673,6 +673,8 @@ class IIMTAPI extends API {
             return array_merge($resArray, $this->PatientInterface->patientFilesNewGet($this->User, $this->request['lang']));
             return array_merge($resArray, $this->PatientInterface->patientFilesNewGet($this->User, $this->request['lang']));
           case 'files-pacs':
           case 'files-pacs':
             return array_merge($resArray, $this->PatientInterface->patientFilesPacsGet($this->User));
             return array_merge($resArray, $this->PatientInterface->patientFilesPacsGet($this->User));
+          case 'fix':
+            return array_merge($resArray, $this->PatientInterface->patientFixGet($this->User, $this->args[0], $this->args[1]));
           case 'risks':
           case 'risks':
             return array_merge($resArray, $this->PatientInterface->patientRisksGet($this->User, $this->args[0]));
             return array_merge($resArray, $this->PatientInterface->patientRisksGet($this->User, $this->args[0]));
           case 'history':
           case 'history':
@@ -692,6 +694,8 @@ class IIMTAPI extends API {
             return array_merge($resArray, $this->PatientInterface->patientFilesExistingPost($this->User, $this->request));
             return array_merge($resArray, $this->PatientInterface->patientFilesExistingPost($this->User, $this->request));
           case 'create':
           case 'create':
             return array_merge($resArray, $this->PatientInterface->patientCreatePost($this->User, $this->request));
             return array_merge($resArray, $this->PatientInterface->patientCreatePost($this->User, $this->request));
+          case 'modify':
+            return array_merge($resArray, $this->PatientInterface->patientModifyPost($this->User, $this->request));
           case 'create-visit':
           case 'create-visit':
             return array_merge($resArray, $this->PatientInterface->patientCreateVisitPost($this->User, $this->request));
             return array_merge($resArray, $this->PatientInterface->patientCreateVisitPost($this->User, $this->request));
           case 'context':
           case 'context':

+ 124 - 0
api.ipsocloud.com/api/v1/Models/PatientInterface.class.php

@@ -312,6 +312,88 @@ namespace Models {
         'fk_visit' => $fk_visit
         'fk_visit' => $fk_visit
       ];
       ];
     }
     }
+
+    /**
+     * Post patient data modification.
+     */
+    public function patientModifyPost($User, $data) {
+      $statement = $this->DataInterface->DatabaseConnection->prepare(
+        "SELECT JSON_EXTRACT(data, '$.newPatientFields') AS data FROM settings"
+      );
+      if(!$statement->execute()) {
+        return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
+      }
+      $settings = json_decode($statement->fetchAll(\PDO::FETCH_ASSOC)[0]['data']);
+      $patientListFields=[];
+      foreach($settings as $S) {
+        $patientListFields[str_replace(' ', '_', $S->name)] = $S->required;
+      }
+
+      if(empty($data['patient']['patientID'])) {
+        return ['result' => 'ERROR', 'reason' => 'patientID'];
+      }
+      if($patientListFields['Firstname'] && empty($data['patient']['firstname'])) {
+        return ['result' => 'ERROR', 'reason' => 'firstname'];
+      }
+      if(empty($data['patient']['firstname'])) {
+        $data['patient']['firstname']='';
+      }
+      if($patientListFields['Lastname'] && empty($data['patient']['lastname'])) {
+        return ['result' => 'ERROR', 'reason' => 'lastname'];
+      }
+      if(empty($data['patient']['lastname'])) {
+        $data['patient']['lastname']='';
+      }
+      if($patientListFields['Sex'] && empty($data['patient']['gender'])) {
+        return ['result' => 'ERROR', 'reason' => 'gender'];
+      }
+      if($patientListFields['Birthdate'] && empty($data['patient']['birthDate'])) {
+        return ['result' => 'ERROR', 'reason' => 'birthDate'];
+      }
+      if(empty($data['patient']['birthDate'])) {
+        $data['patient']['birthDate']=date('Y-m-d');
+      }
+      if($patientListFields['Birth_country'] && empty($data['patient']['birthCountry'])) {
+        return ['result' => 'ERROR', 'reason' => 'birthCountry'];
+      }
+      if($patientListFields['Residence_country'] && empty($data['patient']['residenceCountry'])) {
+        return ['result' => 'ERROR', 'reason' => 'residenceCountry'];
+      }
+      if($patientListFields['Height'] && empty($data['patient']['height'])) {
+        return ['result' => 'ERROR', 'reason' => 'height'];
+      }
+      if($patientListFields['Weight'] && empty($data['patient']['weight'])) {
+        return ['result' => 'ERROR', 'reason' => 'weight'];
+      }
+      if(empty($data['patient']['height'])) {
+        $data['patient']['height'] = null;
+      }
+      if(empty($data['patient']['weight'])) {
+        $data['patient']['weight'] = null;
+      }
+
+      // Insert patient
+      $patientID = $data['patient']['patientID'];
+      $statement = $this->DataInterface->DatabaseConnection->prepare(
+        "UPDATE patient SET firstname=:firstname, lastname=:lastname, gender=:gender, birthDate=:birthDate, height=:height, weight=:weight, race=:race, fk_birthCountry=:fk_birthCountry, fk_residenceCountry=:fk_residenceCountry WHERE patientID='$patientID'"
+      );
+      $statement->bindParam(':firstname', $data['patient']['firstname']);
+      $statement->bindParam(':lastname', $data['patient']['lastname']);
+      $statement->bindParam(':gender', $data['patient']['gender']);
+      $statement->bindParam(':birthDate', $data['patient']['birthDate']);
+      $statement->bindParam(':height', $data['patient']['height']);
+      $statement->bindParam(':weight', $data['patient']['weight']);
+      $statement->bindParam(':race', $data['patient']['patientRace']);
+      $statement->bindParam(':fk_birthCountry', $data['patient']['birthCountry']);
+      $statement->bindParam(':fk_residenceCountry', $data['patient']['residenceCountry']);
+      // Error check
+      if(!$statement->execute()) {
+        return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
+      }
+      return [
+        'result' => 'OK'
+      ];
+    }
     
     
     /**
     /**
      * Post patient data.
      * Post patient data.
@@ -376,6 +458,48 @@ namespace Models {
       ];
       ];
     }
     }
 
 
+    /**
+     * Get patient fix data.
+     */
+    public function patientFixGet($User, $patientID, $lang) {
+      $statement = $this->DataInterface->DatabaseConnection->prepare(
+        "SELECT JSON_EXTRACT(data, '$.newPatientFields') AS data FROM settings"
+      );
+      if(!$statement->execute()) {
+        return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
+      }
+      $settings = json_decode($statement->fetchAll(\PDO::FETCH_ASSOC)[0]['data']);
+      $patientListFields=[];
+      foreach($settings as $S) {
+        $patientListFields[str_replace(' ', '_', $S->name)] = $S->display;
+        $patientListFields[str_replace(' ', '_', $S->name).'_required'] = $S->required;
+      }
+
+      $statement = $this->DataInterface->DatabaseConnection->prepare(
+        "SELECT *, name_$lang AS name FROM country ORDER BY name_$lang"
+      );
+      if(!$statement->execute()) {
+        return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
+      }
+      $countries = $statement->fetchAll(\PDO::FETCH_ASSOC);
+
+      $statement = $this->DataInterface->DatabaseConnection->prepare(
+        "SELECT patient.* FROM patient WHERE patient.ID = $patientID"
+      );
+      if(!$statement->execute()) {
+        return ['result' => 'ERROR', 'reason' => 'internal_error', 'message' => 'Database error', 'data' => $statement->errorInfo()];
+      }
+      $patient = $statement->fetchAll(\PDO::FETCH_ASSOC)[0];
+
+      // 
+      return [
+        'result' => 'OK',
+        'patientListFields' => $patientListFields,
+        'countries' => $countries,
+        'patient' => $patient
+      ];
+    }
+
     /**
     /**
      * Get patient risks data.
      * Get patient risks data.
      */
      */

+ 6 - 0
www.ipsocloud.com/webapp_webpack/src/pages/patient-files-existing.f7.html

@@ -123,6 +123,7 @@
       <div class="row" style="position:absolute; bottom: 0px; height: 52px; justify-content: space-around; align-items: center; width:100%;">
       <div class="row" style="position:absolute; bottom: 0px; height: 52px; justify-content: space-around; align-items: center; width:100%;">
         {{#js_if "app.data.user.type!='reader'"}}
         {{#js_if "app.data.user.type!='reader'"}}
         <a href="#" class="button iimt-button disabled" id="button-new-visit" @click="newVisit()">{{js "global.tr[global.lang].existing.newVisit"}}</a>
         <a href="#" class="button iimt-button disabled" id="button-new-visit" @click="newVisit()">{{js "global.tr[global.lang].existing.newVisit"}}</a>
+        <a href="#" class="button iimt-button disabled" id="button-fix-patient" @click="modifyPatient()">{{js "global.tr[global.lang].existing.correction"}}</a>
         {{/js_if}}
         {{/js_if}}
         <div class="item-content item-input">
         <div class="item-content item-input">
           <div class="item-inner" style="flex-direction: row; align-items: center;">
           <div class="item-inner" style="flex-direction: row; align-items: center;">
@@ -191,6 +192,7 @@
         }
         }
         app.data.patient.ID = ID;
         app.data.patient.ID = ID;
         $$('#button-new-visit').removeClass('disabled');
         $$('#button-new-visit').removeClass('disabled');
+        $$('#button-fix-patient').removeClass('disabled');
         $$('#button-open-visit').removeClass('disabled');
         $$('#button-open-visit').removeClass('disabled');
       },
       },
       newVisit: function() {
       newVisit: function() {
@@ -227,6 +229,10 @@
           console.log('error', data);
           console.log('error', data);
         }, 'json');
         }, 'json');
       },
       },
+      modifyPatient: function() {
+        console.log(app.data.patient);
+        app.views.homePatientView.router.navigate('/patient-fix/', { reloadCurrent: true, ignoreCache: true });
+      },
       openVisit: function() {
       openVisit: function() {
         app.data.patient.visitID = parseInt($$('#visit-list').val());
         app.data.patient.visitID = parseInt($$('#visit-list').val());
         console.log(app.data.patient);
         console.log(app.data.patient);

+ 6 - 4
www.ipsocloud.com/webapp_webpack/src/pages/patient-files-new.f7.html

@@ -210,15 +210,16 @@
           });
           });
           const birthDate_picker = datepicker('input[name="birthDate"]', {
           const birthDate_picker = datepicker('input[name="birthDate"]', {
             formatter: (input, date, instance) => {
             formatter: (input, date, instance) => {
+              // Date() + 1 to fix issue on Safari with js-datepicker 5.18
               if(global.lang=='fr') {
               if(global.lang=='fr') {
-                input.value = global.tools.pad(date.getUTCDate()) + '/' +
+                input.value = global.tools.pad(date.getUTCDate() + 1) + '/' +
                         global.tools.pad(date.getUTCMonth() + 1) + '/' +
                         global.tools.pad(date.getUTCMonth() + 1) + '/' +
                         date.getUTCFullYear();
                         date.getUTCFullYear();
               }
               }
               else {
               else {
                 input.value = date.getUTCFullYear() + '-' +
                 input.value = date.getUTCFullYear() + '-' +
                         global.tools.pad(date.getUTCMonth() + 1) + '-' +
                         global.tools.pad(date.getUTCMonth() + 1) + '-' +
-                        global.tools.pad(date.getUTCDate());
+                        global.tools.pad(date.getUTCDate() + 1);
               }
               }
             },          
             },          
           });
           });
@@ -230,15 +231,16 @@
           });
           });
           const visitDate_picker = datepicker('input[name="visitDate"]', {
           const visitDate_picker = datepicker('input[name="visitDate"]', {
             formatter: (input, date, instance) => {
             formatter: (input, date, instance) => {
+              // Date() + 1 to fix issue on Safari with js-datepicker 5.18
               if(global.lang=='fr') {
               if(global.lang=='fr') {
-                input.value = global.tools.pad(date.getUTCDate()) + '/' +
+                input.value = global.tools.pad(date.getUTCDate() + 1) + '/' +
                         global.tools.pad(date.getUTCMonth() + 1) + '/' +
                         global.tools.pad(date.getUTCMonth() + 1) + '/' +
                         date.getUTCFullYear();
                         date.getUTCFullYear();
               }
               }
               else {
               else {
                 input.value = date.getUTCFullYear() + '-' +
                 input.value = date.getUTCFullYear() + '-' +
                         global.tools.pad(date.getUTCMonth() + 1) + '-' +
                         global.tools.pad(date.getUTCMonth() + 1) + '-' +
-                        global.tools.pad(date.getUTCDate());
+                        global.tools.pad(date.getUTCDate() + 1);
               }
               }
             },          
             },          
           });
           });

+ 254 - 0
www.ipsocloud.com/webapp_webpack/src/pages/patient-fix.f7.html

@@ -0,0 +1,254 @@
+<template>
+  <div class="page" data-name="home-patient-fix">
+    
+    <div class="content flex column centerv centerh">
+      
+      <form class="list no-hairlines-md" id="form-patient-fix" autocomplete="off" style="width: 800px; margin:16px 16px;">
+        <ul>
+          <div class="row">
+            {{#js_if "app.data.user.type=='physician'"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-label">{{js "global.tr[global.lang].existing.patientID"}}: <b>{{js "this.patient.patientID"}}</b></div>
+                <input type="hidden" name="patientID" value="{{js "this.patient.patientID"}}">
+              </div>
+            </li>
+            {{/js_if}}
+            {{#js_if "app.data.user.type=='investigator'"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                {{#js_if "app.data.user.type=='physician'"}}
+                <div class="item-title item-label">{{js "global.tr[global.lang].existing.patientID"}} <span class="required">*</span></div>
+                {{else}}
+                <div class="item-title item-label">{{js "global.tr[global.lang].existing.ctPatientID"}} <span class="required">*</span></div>
+                {{/js_if}}
+                <div class="item-input-wrap">
+                  <input type="text" name="patientID" placeholder="{{js "global.tr[global.lang].existing.patientID"}}">
+                </div>
+              </div>
+            </li>
+            {{/js_if}}
+          </div>
+          <div class="row">
+            {{#js_if "global.lang=='en'"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-floating-label">{{js "global.tr[global.lang].race.title"}} <span class="required">*</span></div>
+                <div class="item-input-wrap">
+                  <select name="patientRace">
+                    <option value="white" {{js "this.patient.race=='white'?'selected':''"}}>{{js "global.tr[global.lang].race.white"}}</option>
+                    <option value="african" {{js "this.patient.race=='african'?'selected':''"}}>{{js "global.tr[global.lang].race.african"}}</option>
+                    <option value="asian" {{js "this.patient.race=='asian'?'selected':''"}}>{{js "global.tr[global.lang].race.asian"}}</option>
+                    <option value="other" {{js "this.patient.race=='other'?'selected':''"}}>{{js "global.tr[global.lang].race.other"}}</option>
+                  </select>
+                </div>
+              </div>
+            </li>
+            {{else}}
+            <input type="hidden" name="patientRace" value="white">
+            {{/js_if}}
+          </div>
+          <div class="row">
+            {{#js_if "this.patientListFields.Firstname"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-label">{{js "global.tr[global.lang].existing.firstname"}} <span class="required">{{js "this.patientListFields.Firstname_required?'*':''"}}</span></div>
+                <div class="item-input-wrap">
+                  <input type="text" name="firstname" placeholder="{{js "global.tr[global.lang].form.firstname"}}" autocomplete="off" value="{{js "this.patient.firstname?this.patient.firstname:''"}}">
+                </div>
+              </div>
+            </li>
+            {{/js_if}}
+            {{#js_if "this.patientListFields.Lastname"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-label">{{js "global.tr[global.lang].existing.lastname"}} <span class="required">{{js "this.patientListFields.Lastname_required?'*':''"}}</span></div>
+                <div class="item-input-wrap">
+                  <input type="text" name="lastname" placeholder="{{js "global.tr[global.lang].form.lastname"}}" autocomplete="off" value="{{js "this.patient.lastname?this.patient.lastname:''"}}">
+                </div>
+              </div>
+            </li>
+            {{/js_if}}
+          </div>
+          <div class="row">
+            {{#js_if "this.patientListFields.Sex"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-label">{{js "global.tr[global.lang].existing.sex"}} <span class="required">{{js "this.patientListFields.Sex_required?'*':''"}}</span></div>
+                <div class="item-input-wrap input-dropdown-wrap">
+                  <select name="gender" required validate>
+                    <option value="M" {{js "this.patient.gender=='M'?'selected':''"}}>Male</option>
+                    <option value="F" {{js "this.patient.gender=='F'?'selected':''"}}>Female</option>
+                  </select>
+                </div>
+              </div>
+            </li>
+            {{/js_if}}
+            {{#js_if "this.patientListFields.Birthdate"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-label">{{js "global.tr[global.lang].existing.birth"}} <span class="required">{{js "this.patientListFields.Birthdate_required?'*':''"}}</span></div>
+                <div class="item-input-wrap">
+                  <input autocomplete="false" type="date" placeholder="{{js "global.tr[global.lang].topLevel.dateFormat"}}" name="birthDate" value="{{js "this.patient.birthDate?this.patient.birthDate:''"}}">
+                </div>
+              </div>
+            </li>
+            {{/js_if}}
+          </div>
+          <div class="row">
+            {{#js_if "this.patientListFields.Height"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-label">{{js "global.tr[global.lang].existing.height"}} <span class="required">{{js "this.patientListFields.Height_required?'*':''"}}</span></div>
+                <div class="item-input-wrap">
+                  <input type="number" name="height" autocomplete="off" placeholder="{{js "global.tr[global.lang].existing.height"}}" value="{{js "this.patient.height?this.patient.height:''"}}">
+                </div>
+              </div>
+            </li>
+            {{/js_if}}
+            {{#js_if "this.patientListFields.Weight"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-label">{{js "global.tr[global.lang].existing.weight"}} <span class="required">{{js "this.patientListFields.Weight_required?'*':''"}}</span></div>
+                <div class="item-input-wrap">
+                  <input type="number" name="weight" autocomplete="off" placeholder="{{js "global.tr[global.lang].existing.weight"}}" value="{{js "this.patient.weight?this.patient.weight:''"}}">
+                </div>
+              </div>
+            </li>
+            {{/js_if}}
+          </div>
+          <div class="row">
+            {{#js_if "this.patientListFields.Birth_country"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-floating-label">{{js "global.tr[global.lang].existing.birthCountry"}} <span class="required">{{js "this.patientListFields.Birth_country_required?'*':''"}}</span></div>
+                <div class="item-input-wrap">
+                  <select name="birthCountry">
+                    {{#each countries}}
+                      <option value="{{ID}}" {{js "global.lang=='en'?(this.alpha2.toLowerCase()=='us'?'selected':''):(global.lang==this.alpha2.toLowerCase()?'selected':'')"}}>{{name}}</option>
+                    {{/each}}
+                  </select>
+                </div>
+              </div>
+            </li>
+            {{/js_if}}
+            {{#js_if "this.patientListFields.Residence_country"}}
+            <li class="item-content item-input">
+              <div class="item-inner">
+                <div class="item-title item-floating-label">{{js "global.tr[global.lang].existing.residenceCountry"}} <span class="required">{{js "this.patientListFields.Residence_country_required?'*':''"}}</span></div>
+                <div class="item-input-wrap">
+                  <select name="residenceCountry">
+                    {{#each countries}}
+                      <option value="{{ID}}" {{js "global.lang=='en'?(this.alpha2.toLowerCase()=='us'?'selected':''):(global.lang==this.alpha2.toLowerCase()?'selected':'')"}}>{{name}}</option>
+                    {{/each}}
+                  </select>
+                </div>
+              </div>
+            </li>
+            {{/js_if}}
+          </div>
+        </ul>
+      </form>
+
+      <div class="flex row centerh">
+        <a href="#" class="button iimt-button" @click="modify()">{{js "global.tr[global.lang].topLevel.save"}}</a>
+      </div>
+
+    </div>
+
+  </div>
+</template>
+<script>
+  export default {
+    on: {
+      pageInit: function() {
+        navigator.sayswho= (function(){
+          var ua= navigator.userAgent, tem, 
+          M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
+          if(/trident/i.test(M[1])){
+              tem=  /\brv[ :]+(\d+)/g.exec(ua) || [];
+              return 'IE '+(tem[1] || '');
+          }
+          if(M[1]=== 'Chrome'){
+              tem= ua.match(/\b(OPR|Edge)\/(\d+)/);
+              if(tem!= null) return tem.slice(1).join(' ').replace('OPR', 'Opera');
+          }
+          M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
+          if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
+          return M.join(' ');
+        })();
+        let versionNameTab = navigator.sayswho.split(' ');
+        if(versionNameTab[0] == 'Safari') {
+          $$('input[name="birthDate"]').attr('type','text');
+          $$('input[name="birthDate"]').on('keydown', function(e) {
+            e.preventDefault();
+            return;
+          });
+          const birthDate_picker = datepicker('input[name="birthDate"]', {
+            //onShow: instance => {
+            //},
+            formatter: (input, date, instance) => {
+              // Date() + 1 to fix issue on Safari with js-datepicker 5.18
+              if(global.lang=='fr') {
+                input.value = global.tools.pad(date.getUTCDate() + 1) + '/' +
+                        global.tools.pad(date.getUTCMonth() + 1) + '/' +
+                        date.getUTCFullYear();
+              }
+              else {
+                input.value = date.getUTCFullYear() + '-' +
+                        global.tools.pad(date.getUTCMonth() + 1) + '-' +
+                        global.tools.pad(date.getUTCDate() + 1);
+              }
+            },          
+          });
+        }
+      }
+    },
+    methods: {
+      modify: function() {
+        let patient = app.form.convertToData('#form-patient-fix');
+
+        // Post data
+        let data = {
+          apiKey: '',
+          patient: patient,
+          type: app.data.user.type
+        }
+        // convert date format?
+        if(data.patient.birthDate.indexOf('/')!==-1) {
+          let t = data.patient.birthDate.split('/');
+          data.patient.birthDate = t[2]+'-'+t[1]+'-'+t[0];
+        }
+        console.log(data);
+        app.preloader.show();
+        app.request.post(app.data.config.apiBaseURL + '/patient/modify/', data, function (data) {
+          // Process response
+          console.log("patient/modify", data);
+          app.preloader.hide();
+          if (data.result == 'ERROR') {
+            switch (data.reason) {
+              case 'denied':
+                app.methods.signout(global.tr[global.lang].topLevel.warning.disconnected);
+                break;
+              case 'internal_error':
+                app.dialog.alert(global.tr[global.lang].topLevel.error.internal_error);
+                break;
+              default:
+                $$('#form-patient-fix [name="'+data.reason+'"]').focus();
+                app.dialog.alert(global.tr[global.lang].topLevel.error.missing_fields+" (\""+data.reason+"\").");
+                break;
+            }
+          }
+          else {
+            $$('#toolbar-patient').click();
+          }
+        }, function (data) {
+          console.log('error', data);
+          app.preloader.hide();
+          app.dialog.alert(global.tr[global.lang].topLevel.error.server_unavailable);
+        }, 'json');
+        
+      }
+    }
+  }
+</script>

+ 40 - 0
www.ipsocloud.com/webapp_webpack/src/routes.js

@@ -18,6 +18,7 @@ import PatientFilesPage from './pages/patient-files.f7.html';
 import PatientFilesExistingPage from './pages/patient-files-existing.f7.html';
 import PatientFilesExistingPage from './pages/patient-files-existing.f7.html';
 import PatientFilesNewPage from './pages/patient-files-new.f7.html';
 import PatientFilesNewPage from './pages/patient-files-new.f7.html';
 import PatientFilesPacsPage from './pages/patient-files-pacs.f7.html';
 import PatientFilesPacsPage from './pages/patient-files-pacs.f7.html';
+import PatientFixPage from './pages/patient-fix.f7.html';
 import PatientRisksPage from './pages/patient-risks.f7.html';
 import PatientRisksPage from './pages/patient-risks.f7.html';
 import PatientHistoryPage from './pages/patient-history.f7.html';
 import PatientHistoryPage from './pages/patient-history.f7.html';
 import PatientFamilyPage from './pages/patient-family.f7.html';
 import PatientFamilyPage from './pages/patient-family.f7.html';
@@ -422,6 +423,45 @@ export default [
         });
         });
     }
     }
   },
   },
+  // Patient fix page
+  {
+    path: '/patient-fix/',
+    async: function(routeTo, routeFrom, resolve, reject) {
+      var app = this.app;
+      app.preloader.show();
+      app.request.promise.json(app.data.config.apiBaseURL + '/patient/fix/' + app.data.patient.ID + '/' + global.lang + '/&apiKey=')
+        .then(data => {
+          // Refresh token if needed
+          app.methods.refreshToken(data);
+          // Process response
+          console.log("patient/fix", data);
+          app.preloader.hide();
+          if (data.result == 'ERROR') {
+            reject();
+            switch (data.reason) {
+              case 'denied':
+                app.methods.signout(global.tr[global.lang].topLevel.warning.disconnected);
+                break;
+              default:
+                app.dialog.alert(global.tr[global.lang].topLevel.error.internal_error);
+                break;
+            }
+          }
+          else {
+            resolve({
+              component: PatientFixPage,
+            }, {
+              context: data,
+            });
+          }
+        }).catch(e => {
+          console.log(e);
+          reject();
+          app.preloader.hide();
+          app.dialog.alert(global.tr[global.lang].topLevel.error.server_unavailable);
+        });
+    }
+  },
   // Patient risks page
   // Patient risks page
   {
   {
     path: '/patient-risks/',
     path: '/patient-risks/',

+ 1 - 0
www.ipsocloud.com/webapp_webpack/src/tr-en.js

@@ -397,6 +397,7 @@ export default {
     lastVisit: "Last visit",
     lastVisit: "Last visit",
     visitCount: "Visits",
     visitCount: "Visits",
     newVisit: "Create new visit",
     newVisit: "Create new visit",
+    correction: "Modify",
     visitDate: "Visit date",
     visitDate: "Visit date",
     visitTime: "Visit time",
     visitTime: "Visit time",
     visitNumber: "Visit ID",
     visitNumber: "Visit ID",

+ 1 - 0
www.ipsocloud.com/webapp_webpack/src/tr-fr.js

@@ -397,6 +397,7 @@ export default {
     lastVisit: "Dernière visite",
     lastVisit: "Dernière visite",
     visitCount: "Visites",
     visitCount: "Visites",
     newVisit: "Créer nouvelle visite",
     newVisit: "Créer nouvelle visite",
+    correction: "Modifier",
     visitDate: "Date de visite",
     visitDate: "Date de visite",
     visitTime: "Heure de visite",
     visitTime: "Heure de visite",
     visitNumber: "ID Visite",
     visitNumber: "ID Visite",