diff --git a/netforce_clinic/actions/clinic_patient_categ.xml b/netforce_clinic/actions/clinic_patient_categ.xml
new file mode 100644
index 0000000..56e94c1
--- /dev/null
+++ b/netforce_clinic/actions/clinic_patient_categ.xml
@@ -0,0 +1,6 @@
+
+ Patient Categories
+ multi_view
+ clinic.patient.categ
+ clinic_menu
+
diff --git a/netforce_clinic/layouts/clinic_cycle_item_form.xml b/netforce_clinic/layouts/clinic_cycle_item_form.xml
index de77231..a8f8901 100644
--- a/netforce_clinic/layouts/clinic_cycle_item_form.xml
+++ b/netforce_clinic/layouts/clinic_cycle_item_form.xml
@@ -2,59 +2,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/netforce_clinic/layouts/clinic_cycle_item_list.xml b/netforce_clinic/layouts/clinic_cycle_item_list.xml
index b1dcf8f..d7c6422 100644
--- a/netforce_clinic/layouts/clinic_cycle_item_list.xml
+++ b/netforce_clinic/layouts/clinic_cycle_item_list.xml
@@ -1,12 +1,6 @@
-
-
-
-
-
-
diff --git a/netforce_clinic/layouts/clinic_menu.xml b/netforce_clinic/layouts/clinic_menu.xml
index 3c06500..ff56fd5 100644
--- a/netforce_clinic/layouts/clinic_menu.xml
+++ b/netforce_clinic/layouts/clinic_menu.xml
@@ -13,6 +13,7 @@
+
diff --git a/netforce_clinic/layouts/clinic_patient_categ_form.xml b/netforce_clinic/layouts/clinic_patient_categ_form.xml
new file mode 100644
index 0000000..6a8ab1c
--- /dev/null
+++ b/netforce_clinic/layouts/clinic_patient_categ_form.xml
@@ -0,0 +1,4 @@
+
diff --git a/netforce_clinic/layouts/clinic_patient_categ_list.xml b/netforce_clinic/layouts/clinic_patient_categ_list.xml
new file mode 100644
index 0000000..218b948
--- /dev/null
+++ b/netforce_clinic/layouts/clinic_patient_categ_list.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/netforce_clinic/layouts/clinic_patient_form.xml b/netforce_clinic/layouts/clinic_patient_form.xml
index e9c32bc..6022cb0 100644
--- a/netforce_clinic/layouts/clinic_patient_form.xml
+++ b/netforce_clinic/layouts/clinic_patient_form.xml
@@ -14,6 +14,7 @@
+
diff --git a/netforce_clinic/models/__init__.py b/netforce_clinic/models/__init__.py
index 6c35c87..5569853 100644
--- a/netforce_clinic/models/__init__.py
+++ b/netforce_clinic/models/__init__.py
@@ -9,6 +9,7 @@ from . import nation
from . import nurse
from . import address
from . import patient
+from . import patient_categ
from . import patient_cause_line
from . import patient_comorbidity_line
from . import patient_morbidity_line
diff --git a/netforce_clinic/models/cycle_item.py b/netforce_clinic/models/cycle_item.py
index 6e64f1c..32dcd7b 100644
--- a/netforce_clinic/models/cycle_item.py
+++ b/netforce_clinic/models/cycle_item.py
@@ -1,9 +1,7 @@
-import re
import time
-from netforce.model import Model, fields, get_model
+from netforce.model import Model, fields
from netforce.access import get_active_company
-from netforce.utils import get_data_path
class CycleItem(Model):
_name="clinic.cycle.item"
@@ -14,25 +12,8 @@ class CycleItem(Model):
res={}
for obj in self.browse(ids):
name="%s-%s"%(obj.cycle_id.name,obj.date)
- hd_total=len([hd_case for hd_case in obj.hd_cases if hd_case.state=='completed']) # XXX
- pt=(hd_total or 0.0)
- k=(obj.var_k or 0.0)
- pt_k=pt*k
- x=(pt_k + 1275)/13.5
- total=0.0
- for line in obj.nurse_lines:
- total+=(line.amount or 0.0)
- total2=0.0
- for line in obj.doctor_lines:
- total2+=(line.amount or 0.0)
res[obj.id]={
'name': name,
- 'var_x': x,
- 'total_pt': hd_total,
- 'total_amount': hd_total*k,
- 'total': total,
- 'total2': total2,
- 'total_balance': (hd_total*k)-total,
}
return res
@@ -41,296 +22,15 @@ class CycleItem(Model):
'company_id': fields.Many2One("company", "Company"),
'cycle_id': fields.Many2One("clinic.cycle", "Cycle",search=True),
'date': fields.Date("Date",search=True),
- 'var_k': fields.Float("K"),
- 'var_x': fields.Float("X", function="_get_all",function_multi=True),
- 'total_pt': fields.Float("PT", function="_get_all",function_multi=True),
- 'total_amount': fields.Float("PT*K", function="_get_all",function_multi=True),
- 'total_balance': fields.Float("Total Balance", function="_get_all",function_multi=True),
- 'total': fields.Float("Total", function="_get_all",function_multi=True),
- 'total2': fields.Float("Total", function="_get_all",function_multi=True),
"state": fields.Selection([("draft","Draft"),("done","Done")],"Status",required=True),
'hd_cases': fields.One2Many("clinic.hd.case","cycle_item_id", "HD Cases"),
- 'nurse_lines': fields.One2Many('clinic.cycle.item.line', 'cycle_item_id', 'Nurse Lines',domain=[['type','=','nurse']]),
- 'doctor_lines': fields.One2Many('clinic.cycle.item.line', 'cycle_item_id', 'Doctor Lines',domain=[['type','=','doctor']]),
- 'var_doctor': fields.Float("K Doctor"),
+ 'visits': fields.One2Many("clinic.visit","cycle_item_id", "Visits"),
}
_defaults={
'state': 'draft',
'company_id': lambda *a: get_active_company(),
'date': lambda *a: time.strftime("%Y-%m-%d"),
- 'var_k': 450,
- 'var_doctor': 450,
}
-
- def compute(self,ids,context={}):
- # XXX should compute after hd case done
- for obj in self.browse(ids):
- vals={
- 'nurse_lines': [],
- 'doctor_lines': [],
- }
- nurse_dict={}
- doctor_dict={}
- for hd_case in obj.hd_cases:
- if hd_case.state=='completed':
- nurse_code=hd_case.nurse_id.categ_id.code or ""
- if not nurse_dict.get(nurse_code):
- nurse_dict[nurse_code]=0
- nurse_dict[nurse_code]+=1
-
- doctor_categ=hd_case.doctor_id.categ_id or ""
- if not doctor_categ:
- continue
- doctor_name=hd_case.doctor_id.name or ""
- key=(doctor_categ,doctor_name)
- if not doctor_dict.get(key):
- doctor_dict[key]=0
- doctor_dict[key]+=1
-
- for line in obj.nurse_lines:
- line.delete()
- for line in obj.doctor_lines:
- line.delete()
-
- for k, v in doctor_dict.items():
- categ=k[0]
- name=k[1]
- qty=v
- vals['doctor_lines'].append(('create',{
- 'personal_categ': categ.id,
- 'description': name,
- 'type': 'doctor',
- 'formular': categ.formular,
- 'qty': qty,
- 'rate': obj.var_doctor or 0.0,
- 'amount': qty*obj.var_doctor,
- }))
-
- print(nurse_dict)
- for personal_categ in get_model("clinic.personal.categ").search_browse([]):
- if personal_categ.type=='nurse':
- formular=personal_categ.formular or ""
- rate=0
- try:
- var_x="%s"%(round(obj.var_x,2))
- formulared=formular.replace("x",var_x)
- rate=eval(formulared)
- except:
- rate=0
- qty=nurse_dict.get(personal_categ.code,0)
- vals['nurse_lines'].append(('create',{
- 'personal_categ': personal_categ.id,
- 'type': 'nurse',
- 'formular': formular,
- 'qty': qty,
- 'rate': rate,
- 'amount': qty*rate,
- }))
- print("qty * rate ", qty, ' ', rate)
- # x=(pt*k+n2*100+n3*250-n4*25-n5*25+n6*75)/(n1+n2+n3+0.5*(n4+n5+n6))
-
- obj.write(vals)
-
- return {
- 'next': {
- 'name': 'clinic_cycle_item',
- 'mode': 'form',
- 'active_id': obj.id,
- },
- 'flash': 'Compute OK',
- }
-
- def reduce_formular(self,line_strs=None):
- def get_lines(line_str):
- return line_strs.replace("\n","").replace(" ","").split(",")
- line2=[]
- m='/(\d+)'
- for line in get_lines(line_strs):
- res=re.findall(m,line)
- if res:
- x1=res[0]
- line=line.replace("/%s"%x1,"")
- line=line.replace("(","")
- line=line.replace(")","")
- p1='x'
- res=re.findall(p1,line)
- if res:
- line=line.replace("x",'x/%s'%x1)
- p2='[-,+,*]\d+'
- res=re.findall(p2,line)
- if res:
- for r in res:
- x2=float(r)/float(x1)
- x2=x2> 0 and '+%s'%x2 or x2
- line=line.replace(r,str(x2))
- if line:
- line2.append(line)
- return line2
-
- def match_value(self,items):
- for qty, f in items:
- p1='x'
- res=re.findall(p1,f)
- if res:
- f=f.replace("x",'%sx'%qty)
-
- p2='([-,+,*])(\d+)'
- res=re.findall(p2,f)
- #XXX
- if res:
- #print('res ', res)
- sym=res[0][0]
- v=res[0][1]
- sym_v=''.join([sym,str(int(v)*int(qty))])
- old_v=''.join([sym,str(int(v))])
- #print('-'*50)
- #print(f)
- #print(old_v, " ", sym_v)
- f=f.replace('%s'%str(old_v),'%s'%str(sym_v))
- #print(f)
- #print('-'*50)
- print(f)
-
- def onchange_line(self,context={}):
- data=context['data']
- path=context["path"]
- line=get_data_path(data,path,parent=True)
- #pt=data['pt'] or 0.0
- #k=data['var_k'] or 0.0
- #x=(pt*k+n2*100+n3*250-n4*25-n5*25+n6*75)/(n1+n2+n3+0.5*(n4+n5+n6))
- #qty=line.get("qty")
- #rate=line.get("rate")
- total=0.0
- items=[]
- values=[]
- for line in data['nurse_lines']:
- formular=line['formular']
- values.append(line['qty'])
- items.append(formular)
- qty=line['qty']
- rate=line['rate']
- line['amount']=qty*rate
- total+=line['amount']
- formulars=self.reduce_formular(','.join(items))
- res=self.match_value(list(zip(values,formulars)))
- data['total']=total
- data['total_amount']=data['total_pt']*(data['var_k'] or 0)
- data['total_balance']=data['total_amount']-data['total']
- return data
-
- def create_payment(self,ids,context={}):
- obj=self.browse(ids)[0]
- settings=get_model("settings").browse(1)
- account_id=settings.ap_nurse_id.id
- if not account_id:
- raise Exception("No Account payment for Nurse")
- vals={
- "company_id": obj.company_id.id,
- "type": "out",
- "pay_type": "direct",
- "date": obj.date or time.strftime("%Y-%m-%d"),
- "account_id": account_id,
- 'related_id': "clinic.cycle.item,%s"%obj.id,
- 'direct_lines': [],
- }
- for line in obj.nurse_lines:
- if not line.amount:
- continue
- vals['direct_lines'].append(('create',{
- 'description': 'Payment; %s'%line.personal_categ.name,
- 'account_id': account_id,
- 'qty': 1,
- 'unit_price': line.amount,
- 'amount': line.amount,
- }))
- account_id=settings.ap_doctor_id.id
- if not account_id:
- raise Exception("No Account payment for Doctor")
- for line in obj.doctor_lines:
- if not line.amount:
- continue
- vals['direct_lines'].append(('create',{
- 'description': 'Payment; %s'%line.description,
- 'account_id': account_id,
- 'qty': line.qty,
- 'unit_price': line.amount,
- 'amount': line.amount,
- }))
-
- payment_id=get_model("account.payment").create(vals,context={"type":"out"})
- #get_model("account.payment").browse(payment_id).post()
- obj.write({
- 'state': 'done',
- })
- if context.get('called'):
- return obj.id
- return {
- 'next': {
- 'name': 'payment',
- 'mode': 'form',
- 'active_id': payment_id,
- },
- 'flash': 'Create journal successfully',
- }
-
- def to_draft(self,ids,context={}):
- obj=self.browse(ids)[0]
- related_id="clinic.cycle.item,%s"%obj.id
- for payment in get_model("account.payment").search_browse([['related_id','=',related_id]]):
- payment.to_draft()
- payment.delete()
- obj.write({
- 'state': 'draft',
- })
- if context.get('called'):
- return obj.id
- return {
- 'next': {
- 'name': 'clinic_cycle_item',
- 'mode': 'form',
- 'active_id': obj.id,
- },
- 'flash': 'Cycle item is set to draft',
- }
-
- def to_drafts(self,ids,context={}):
- for obj in self.browse(ids):
- context['called']=True
- obj.to_draft(context=context)
- return {
- 'next': {
- 'name': 'clinic_cycle_item',
- 'mode': 'list',
- },
- 'flash': 'Cycle item is set to draft',
- }
-
- def view_payment(self,ids,context={}):
- obj=self.browse(ids)[0]
- related_id="clinic.cycle.item,%s"%obj.id
- payment_ids=get_model("account.payment").search([['related_id','=',related_id]])
- if payment_ids:
- payment_id=payment_ids[0]
- return {
- 'next': {
- 'name': 'payment',
- 'mode': 'form',
- 'active_id': payment_id,
- },
- }
-
-
- def pay(self,ids,context={}):
- context['called']=True
- for obj in self.browse(ids):
- obj.create_payment(context)
- return {
- 'next': {
- 'name': 'clinic_cycle_item',
- 'mode': 'list',
- },
- 'flash': 'Paid',
- }
CycleItem.register()
diff --git a/netforce_clinic/models/gen_visit.py b/netforce_clinic/models/gen_visit.py
index 6e92c6c..60a7183 100644
--- a/netforce_clinic/models/gen_visit.py
+++ b/netforce_clinic/models/gen_visit.py
@@ -2,7 +2,6 @@ from datetime import datetime, timedelta
from netforce.access import get_active_user
from netforce.model import Model, fields, get_model
-from netforce.database import get_connection
FMT_DATE="%Y-%m-%d"
FMT_DATETIME="%Y-%m-%d %H:%M:%S"
@@ -118,6 +117,7 @@ class GenVisit(Model):
if not patients and obj.patient_type:
patients=get_model("clinic.patient").search([['type','=',obj.patient_type]])
elif patients:
+ # continue to generate with condition
pass
else:
raise Exception("Please select some patient or patient type")
@@ -217,6 +217,8 @@ class GenVisit(Model):
visit_ids=[]
date_from=datetime.strptime(obj.date_from,FMT_DATETIME)
date_to=datetime.strptime(obj.date_to,FMT_DATETIME)
+ # FIXME add more 1 week for make sure
+ date_to2=(date_to+timedelta(days=7)).strftime(FMT_DATETIME)
visit_obj=get_model("clinic.visit")
schedule_obj=get_model("clinic.schedule")
@@ -224,16 +226,16 @@ class GenVisit(Model):
if not patients and obj.patient_type:
patients=get_model("clinic.patient").search([['type','=',obj.patient_type]])
elif patients:
+ # continue to create with critiria
pass
else:
- #XXX search date to
dom=[]
dom.append(['time_start','>=','%s %s'%(obj.date_from[0:10],' 00:00:00')])
- dom.append(['time_stop','<=','%s %s'%(obj.date_to[0:10],' 23:59:59')])
+ dom.append(['time_stop','<=','%s %s'%(date_to2[0:10],' 23:59:59')])
dom.append(['cycle_id','=',obj.cycle_id.id])
dom.append(['state','=','draft'])
vids=visit_obj.search(dom)
- visit_ids.append(vids)
+ visit_obj.delete(vids)
schedule_obj=get_model("clinic.schedule")
schedule_ids=schedule_obj.search(dom)
schedule_obj.delete(schedule_ids)
@@ -271,7 +273,6 @@ class GenVisit(Model):
dom.append(['patient_id','=','%s'%patient_id])
dom.append(['state','=','draft'])
count+=7
- print(dom)
vids=visit_obj.search(dom)
if vids:
visit_ids.append(vids[0])
@@ -292,7 +293,7 @@ class GenVisit(Model):
get_model("clinic.visit").delete(visit_ids)
dom=[]
dom.append(['time_start','>=','%s %s'%(obj.date_from[0:10],' 00:00:00')])
- dom.append(['time_stop','<=','%s %s'%(start_date.strftime(FMT_DATE)[0:10],' 23:59:59')])
+ dom.append(['time_stop','<=','%s %s'%(date_to2[0:10],' 23:59:59')])
dom.append(['cycle_id','=',obj.cycle_id.id])
schedule_ids=schedule_obj.search(dom)
schedule_obj.delete(schedule_ids)
diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py
index d5e225c..f7a5de5 100644
--- a/netforce_clinic/models/hd_case.py
+++ b/netforce_clinic/models/hd_case.py
@@ -67,7 +67,7 @@ class HDCase(Model):
'fee_paid': fields.Boolean("Fee Paid"),
'note': fields.Text("Note"),
"cycle_id": fields.Many2One("clinic.cycle","Cycle"),
- "cycle_item_id": fields.Many2One("clinic.cycle.item","Cycle Item",on_delete="cascade"), # compute labor cost
+ 'cycle_item_id': fields.Many2One("clinic.cycle.item","Cycle Item"), # on_delete="cascade" -> rm visit from cycle item
'pay_amount': fields.Float("Amount",function="get_pay_amount"),
'pay_date': fields.Date("Pay Date"),
'pay_account_id': fields.Many2One("account.account","Account"),
diff --git a/netforce_clinic/models/patient.py b/netforce_clinic/models/patient.py
index e8e6aa7..d988e6e 100644
--- a/netforce_clinic/models/patient.py
+++ b/netforce_clinic/models/patient.py
@@ -78,6 +78,7 @@ class Patient(Model):
"dialyzers": fields.One2Many("clinic.dialyzer","patient_id","Dialyzers"),
"active":fields.Boolean("Active"),
'note': fields.Text("Note"),
+ 'categ_id': fields.Many2One("clinic.patient.categ","Category"),
}
diff --git a/netforce_clinic/models/patient_categ.py b/netforce_clinic/models/patient_categ.py
new file mode 100644
index 0000000..d9070f7
--- /dev/null
+++ b/netforce_clinic/models/patient_categ.py
@@ -0,0 +1,12 @@
+from netforce.model import Model, fields
+
+class PatientCateg(Model):
+ _name="clinic.patient.categ"
+ _string="Patient Category"
+
+ _fields={
+ "name": fields.Char("Name",required=True,search=True),
+ "code": fields.Char("Code",search=True),
+ }
+
+PatientCateg.register()
diff --git a/netforce_clinic/models/visit.py b/netforce_clinic/models/visit.py
index 6070379..6a845b9 100644
--- a/netforce_clinic/models/visit.py
+++ b/netforce_clinic/models/visit.py
@@ -25,12 +25,6 @@ class Visit(Model):
res[obj.id]=datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return res
- def _get_color(self,ids,context={}):
- res={}
- for obj in self.browse(ids):
- res[obj.id]='red'
- return res
-
_fields={
"number": fields.Char("Number",required=True,search=True),
"time_start": fields.DateTime("Time Start",required=True),
@@ -47,7 +41,7 @@ class Visit(Model):
"comments": fields.One2Many("message","related_id","Comments"),
'visit_date': fields.Date('Visit Date',function="_get_visit_date"),
'print_date': fields.Date('Print Date',function="_get_print_date"),
- 'cycle_color': fields.Char("Cycle Color", function="_get_color"), # FIXME
+ 'cycle_item_id': fields.Many2One("clinic.cycle.item","Cycle Item"), # on_delete="cascade" -> rm visit from cycle item
}
def _get_number(self,context={}):
@@ -288,5 +282,26 @@ class Visit(Model):
},
'flash': 'Gen No OK',
}
+
+ def create(self, vals,**kw):
+ date=vals['time_start'][0:10]
+ cycle_id=vals['cycle_id']
+ dom=[]
+ dom.append(['date','=',date])
+ dom.append(['cycle_id','=',cycle_id])
+ item_obj=get_model('clinic.cycle.item')
+ item_ids=item_obj.search(dom)
+ item_id=None
+ if not item_ids:
+ item_id=item_obj.create({
+ 'cycle_id': cycle_id,
+ 'date': date,
+ })
+ else:
+ item_id=item_ids[0]
+ print("item_id ",item_id)
+ vals['cycle_item_id']=item_id
+ obj_id=super().create(vals,**kw)
+ return obj_id
Visit.register()
diff --git a/netforce_clinic/todo.txt b/netforce_clinic/todo.txt
index 49a51bf..06ce71e 100644
--- a/netforce_clinic/todo.txt
+++ b/netforce_clinic/todo.txt
@@ -1,7 +1,24 @@
+cycle item:
+ cycle_id
+ list's nurse
+ list's patient & doctor
+
after finish hd case -> show popup to check nurse and doctor after finish
-many2many -> domain
formalar
tick:
find all -> replace -> multiple x
+order
+ - visit
+ - by datenow, cycle sequence, state
+ - solution: maybe make some dashboard to that
+ - like a table treatment in 1 day
+
+widget
+ -
+ - summary hd case for each month (see. account dashboard)
+ bar char
+tick
+ many2many=> add, set
+ one2many=> create, write