Integrating the problem list improvements with the recent fee sheet improvements...
[openemr.git] / interface / forms / fee_sheet / review / fee_sheet_justify_view_model.js
blob27a26f6da62d404eb14092c2a212191476a30814
1 /**
2  * knockout.js view model for fee sheet justification
3  * 
4  * Copyright (C) 2013 Kevin Yeh <kevin.y@integralemr.com> and OEMR <www.oemr.org>
5  *
6  * LICENSE: This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
16  *
17  * @package OpenEMR
18  * @author  Kevin Yeh <kevin.y@integralemr.com>
19  * @link    http://www.open-emr.org
20  */
21 function start_edit(data,event)
23     data.edit_mode(true);
24     var elem=$(event.target).siblings("input").get(0);
26 function end_edit(data,event)
28     data.edit_mode(false);
30 function edit_key(data,event)
32     if(event.keyCode==13)
33         {
34             data.edit_mode(false);
35             return false;
36         }
37    return true;
39 function search_key(data,event)
41     if(event.keyCode==13)
42         {
43             $(event.target).siblings(".search_results").find(".search_result_code:first").click();
44             return false;
45         }
46     return true;
49 function justify_entry(json_object)
51     var retval=new code_entry(json_object);
52     retval.encounter_issue=ko.observable(false);
53     retval.edit_mode=ko.observable(false);
54     retval.prob_id=ko.observable();
55     retval.allowed_to_create_problem_from_diagnosis=ko.observable();
56     retval.create_problem=ko.observable(false);
57     retval.jsonify=function()
58     {
59         var json={};
60         json.code=this.code();
61         json.code_type=this.code_type();
62         json.description=this.description();
63         json.allowed_to_create_problem_from_diagnosis=this.allowed_to_create_problem_from_diagnosis();
64         json.prob_id=this.prob_id();
65         json.create_problem=this.create_problem();
66         return json;
67     };
68     return retval;
71 function choose_search_diag(data,event,parent)
73     var code_key=data.code_type+"|"+data.code;
74     var existing=parent.added_keys[code_key];
75     if(typeof existing!='undefined')
76     {
77         parent.search_has_focus(false);
78         if(!existing.selected())
79         {
80              existing.selected(true);
81              update_diagnosis_options(parent.diagnosis_options,existing);
82         }
83     }
84     else
85     {
86         var new_justify=justify_entry({code: data.code, code_type:data.code_type, description:data.description, selected:true});
87         new_justify.source='search';
88         new_justify.source_idx=99999;
89         new_justify.create_problem(true);
90         parent.diagnosis_options.push(new_justify);
91         parent.added_keys[code_key]=new_justify;
92         update_diagnosis_options(parent.diagnosis_options,new_justify);
93         parent.search_has_focus(false);
94         parent.diagnosis_options.sort(priority_order);
95     }
96     parent.search_query("");
97     return true;
100 function search_change(data,model)
102     var search_query=data;
103     model.search_show(true);
104     var search_type= model.searchType().key;
105     var search_type_id=model.searchType().id;
106     if(search_query.length>0)
107         {
108             $.post(ajax_fee_sheet_search,
109                     {
110                         search_query:search_query,
111                         search_type: search_type,
112                         search_type_id: search_type_id
113                     },
114                     function(result)
115                     {
116                         model.search_results.removeAll();
117                         if(result.codes!=null)
118                             {
119                                 for(var idx=0;idx<result.codes.length;idx++)
120                                     {
121                                         var cur_code=result.codes[idx];
122                                         model.search_results.push(cur_code);
123                                     }                                
124                             }
125                     },
126                     "json");                
127         }
128         else
129         {
130             model.search_results.removeAll();
131         }
132    return true;
134 function search_focus(data,event)
136     data.search_show(true);
138 function search_blur(data,event)
140     data.search_show(false);
142 function update_justify(data,event)
144     event.preventDefault();
145     data.diagnosis_options.sort(priority_order);
146     var justify=[];
147     for(var idx=0;idx<data.diagnosis_options().length;idx++)
148     {
149         var cur=data.diagnosis_options()[idx];
150         if(cur.selected())
151         {
152             justify.push(cur.jsonify());
153         }
154     }
155     var skip_issues=data.duplicates().length>0;
156     top.restoreSession();
157     $.post(justify_ajax,{
158         skip_issues: skip_issues,
159         pid: data.patient_id,
160         encounter: data.encounter_id,
161         task: 'update',
162         billing_id: data.billing_id,
163         diags: JSON.stringify(justify)
164     },
165     function(data)
166         {
167             refresh_codes();
168         }
170     ); 
171     data.show(false);
174 function cancel_justify(data,event)
176     event.preventDefault();
177     data.show(false);
179 function sort_justify(data,event)
181     data.diagnosis_options.sort(priority_order);
184 var source_order={current:1,patient:2,common:3,search:4}
185 function priority_order(left,right)
187     if(left.priority()>right.priority())
188     {
189         return 1;
190     }
191     if(left.priority()<right.priority())
192     {
193         return -1;
194     }   
195     else
196     {
197         if(left.source==right.source)
198         {
199             if(left.source=='patient')
200             {
201                 if(left.encounter_issue()!=right.encounter_issue())
202                 {
203                     return left.encounter_issue() ? -1 : 1;
204                 }
205             }
206             if(left.source_idx>right.source_idx)
207             {
208                 return 1;
209             }
210             else
211             {
212                 return -1;
213             }
214         }
215         else
216         {
217             if(source_order[left.source]<source_order[right.source])
218             {
219                 return -1;
220             }
221             return 1;
222         }
223     }
225 function update_diagnosis_options(diagnosis_options,data)
227     var chosen=0;
228     for(var idx=0;idx<diagnosis_options().length;idx++)
229     {
230         var cur=diagnosis_options()[idx];
231         if(cur.selected())
232         {
233             chosen++;
234         }
235     }
236     var old_priority=99999;
237     if(data.selected())
238     {
239         data.priority(chosen);
240     }
241     else
242     {
243         old_priority=data.priority();
244         data.priority(99999);
245     }
246 //    diagnosis_options.sort(priority_order);
247     if(!data.selected())
248     {
249         for(idx=0;idx<diagnosis_options().length;idx++)
250             {
251                 cur=diagnosis_options()[idx];
252                 if((cur.priority()>old_priority) && cur.priority()!=99999)
253                 {
254                     cur.priority(cur.priority()-1);
255                 }
256             }
257     }
259 function check_justify(data,event,model)
261     
262     update_diagnosis_options(model.diagnosis_options,data);
263     return true;
265 function lookup_justify(current_justifications,entry)
267     for(var idx=0;idx<current_justifications.length;idx++)
268         {
269             var cur=current_justifications[idx];
270             if((cur.code()==entry.code())&&(cur.code_type()==entry.code_type()))
271                 {
272                     entry.priority(cur.priority());
273                     entry.selected(true);
274                 }
275         }
277 function setup_justify(model,current,patient,common)
279     model.added_keys={};
280     for(var idx=0;idx<current.length;idx++)
281     {
282         var cur_entry=current[idx];
283         var new_justify=new justify_entry(cur_entry);
284         if(typeof model.added_keys[new_justify.key()]=='undefined')
285         {
286             model.added_keys[new_justify.key()]=new_justify;
287             new_justify.selected(false);
288             lookup_justify(model.current_justify(),new_justify);
289             //new_justify.priority(idx+1);
290             new_justify.source='current';
291             new_justify.source_idx=idx;
292             new_justify.allowed_to_create_problem_from_diagnosis(cur_entry.allowed_to_create_problem_from_diagnosis);
293             model.diagnosis_options.push(new_justify);
294             
295         }
296     }
297     for(idx=0;idx<patient.length;idx++)
298     {
299         cur_entry=patient[idx];
300         if((cur_entry.code!=null) || cur_entry.code_type!="")
301         {         
302             new_justify=new justify_entry(cur_entry);
303             if(typeof model.added_keys[new_justify.key()]=='undefined')
304             {
305                 model.added_keys[new_justify.key()]=new_justify;
306                 if(new_justify.selected())
307                 {
308                     new_justify.encounter_issue(true);
309                 }
310                 new_justify.selected(false);
311                 lookup_justify(model.current_justify(),new_justify);
312                 new_justify.source='patient';
313                 new_justify.source_idx=idx;
314                 new_justify.prob_id(cur_entry.db_id);
315                 new_justify.allowed_to_create_problem_from_diagnosis(cur_entry.allowed_to_create_problem_from_diagnosis);
316                 model.diagnosis_options.push(new_justify);        
317             }
318             else
319             {
320                 var entry=model.added_keys[new_justify.key()];
321                 if((entry.prob_id()!=null) &&(entry.prob_id()!=cur_entry.db_id))
322                 {
323                     new_justify.prob_id(cur_entry.db_id);
324                     new_justify.allowed_to_create_problem_from_diagnosis(cur_entry.allowed_to_create_problem_from_diagnosis);
325                     if(model.duplicates().length==0)
326                         {
327                             model.duplicates.push(entry);
328                         }
329                     model.duplicates.push(new_justify);
330                 }
331                 else
332                 {
333                     entry.prob_id(cur_entry.db_id);
334                     entry.allowed_to_create_problem_from_diagnosis(cur_entry.allowed_to_create_problem_from_diagnosis);
335                     entry.description(cur_entry.description);
336                     if(cur_entry.selected)
337                     {
338                         entry.encounter_issue(true);
339                     }
340                 }
341             }
342         }
343     }
344     for(idx=0;idx<common.length;idx++)
345     {
346         cur_entry=common[idx];
347         new_justify=new justify_entry(cur_entry);
348         if(typeof model.added_keys[new_justify.key()]=='undefined')
349         {
350             model.added_keys[new_justify.key()]=new_justify;
351             new_justify.selected(false);
352             lookup_justify(model.current_justify(),new_justify);
353             new_justify.source='common';
354             new_justify.source_idx=idx;
355             new_justify.allowed_to_create_problem_from_diagnosis(cur_entry.allowed_to_create_problem_from_diagnosis);
356             model.diagnosis_options.push(new_justify);        
357         }
358     }
359     model.diagnosis_options.sort(priority_order);
360     
362 function toggle_warning_details(data,event)
364     data.show_warning_details(!data.show_warning_details());
366 function fee_sheet_justify_view_model(billing_id,enc_id,pat_id,current_justify)
368     this.justify={
369                     billing_id:billing_id
370                     ,encounter_id: enc_id
371                     ,patient_id: pat_id
372                     ,diagnosis_options: ko.observableArray()
373                     ,current: ko.observableArray()
374                     ,patient: ko.observableArray()
375                     ,common: ko.observableArray()
376                     ,show: ko.observable(false)
377                     ,current_justify: ko.observable(current_justify)
378                     ,search_results: ko.observableArray()
379                     ,search_show: ko.observable(false).extend({throttle:300})
380                     ,search_has_focus: ko.observable(false)
381                     ,added_keys: {}
382                     ,search_query: ko.observable()
383                     ,diag_code_types: diag_code_types
384                     ,searchType: ko.observable()
385                     ,duplicates:ko.observableArray()
386                     ,show_warning_details:ko.observable(false)
387                   };
388     var vm=this.justify;
389     vm.search_query_throttled=ko.computed(vm.search_query).extend({throttle:300}).subscribe(function(data){search_change(data,vm)});
390     var mode='common';   
391     $.post(justify_ajax,{
392             pid: pat_id,
393             encounter: enc_id,
394             mode: mode,
395                 task: "retrieve"
396             },function(data){
397                 setup_justify(vm,data.current,data.patient,data.common);
398                 
399                 vm.show(true);
400                 vm.search_has_focus(true);
401             },
402             "json");
403     return this;