diff --git a/netforce_clinic/actions/clinic_cycle.xml b/netforce_clinic/actions/clinic_cycle.xml
new file mode 100644
index 0000000..73cc3c4
--- /dev/null
+++ b/netforce_clinic/actions/clinic_cycle.xml
@@ -0,0 +1,7 @@
+
+ Cycles
+ multi_view
+ clinic.cycle
+ list,form
+ clinic_menu
+
diff --git a/netforce_clinic/layouts/clinic_cycle_form.xml b/netforce_clinic/layouts/clinic_cycle_form.xml
new file mode 100644
index 0000000..771b278
--- /dev/null
+++ b/netforce_clinic/layouts/clinic_cycle_form.xml
@@ -0,0 +1,4 @@
+
diff --git a/netforce_clinic/layouts/clinic_cycle_list.xml b/netforce_clinic/layouts/clinic_cycle_list.xml
new file mode 100644
index 0000000..9d2ffcd
--- /dev/null
+++ b/netforce_clinic/layouts/clinic_cycle_list.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/netforce_clinic/layouts/clinic_hd_case_form.xml b/netforce_clinic/layouts/clinic_hd_case_form.xml
index ec8885a..0e78584 100644
--- a/netforce_clinic/layouts/clinic_hd_case_form.xml
+++ b/netforce_clinic/layouts/clinic_hd_case_form.xml
@@ -2,25 +2,33 @@
-
-
-
+
+
+
-
-
+
+
-
+
+
+
+
+
+
+
+
@@ -35,53 +43,52 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/netforce_clinic/layouts/clinic_hd_case_list.xml b/netforce_clinic/layouts/clinic_hd_case_list.xml
index 637e2b4..89ca460 100644
--- a/netforce_clinic/layouts/clinic_hd_case_list.xml
+++ b/netforce_clinic/layouts/clinic_hd_case_list.xml
@@ -2,6 +2,7 @@
+
diff --git a/netforce_clinic/layouts/clinic_menu.xml b/netforce_clinic/layouts/clinic_menu.xml
index 58de40f..b228f17 100644
--- a/netforce_clinic/layouts/clinic_menu.xml
+++ b/netforce_clinic/layouts/clinic_menu.xml
@@ -19,9 +19,6 @@
-
-
-
-
@@ -30,6 +27,7 @@
-
+
diff --git a/netforce_clinic/layouts/clinic_visit_calendar.xml b/netforce_clinic/layouts/clinic_visit_calendar.xml
index 252622f..d2a6ec1 100644
--- a/netforce_clinic/layouts/clinic_visit_calendar.xml
+++ b/netforce_clinic/layouts/clinic_visit_calendar.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/netforce_clinic/layouts/clinic_visit_form.xml b/netforce_clinic/layouts/clinic_visit_form.xml
index 70997f7..6062d71 100644
--- a/netforce_clinic/layouts/clinic_visit_form.xml
+++ b/netforce_clinic/layouts/clinic_visit_form.xml
@@ -5,53 +5,25 @@
-
-
+
+
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/netforce_clinic/layouts/clinic_visit_list.xml b/netforce_clinic/layouts/clinic_visit_list.xml
index 60b2d33..770c53b 100644
--- a/netforce_clinic/layouts/clinic_visit_list.xml
+++ b/netforce_clinic/layouts/clinic_visit_list.xml
@@ -1,10 +1,18 @@
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
+
diff --git a/netforce_clinic/models/__init__.py b/netforce_clinic/models/__init__.py
index d74d01e..2e4f14b 100644
--- a/netforce_clinic/models/__init__.py
+++ b/netforce_clinic/models/__init__.py
@@ -16,11 +16,14 @@ from . import department
from . import doctor
from . import nurse
from . import visit
+from . import visit_line
from . import visit_plan
from . import hd_case
from . import hd_case_line
+from . import hd_case_gmline
from . import hd_case_discont
from . import dialyzer
from . import dialyzer_line
from . import import_payment
from . import file_sheet
+from . import cycle
diff --git a/netforce_clinic/models/cycle.py b/netforce_clinic/models/cycle.py
new file mode 100644
index 0000000..970dfc5
--- /dev/null
+++ b/netforce_clinic/models/cycle.py
@@ -0,0 +1,37 @@
+from datetime import datetime, timedelta
+
+from netforce.model import Model, fields
+
+FMT_DATE="%Y-%m-%d %H:%M:%S"
+
+class Cycle(Model):
+ _name="clinic.cycle"
+ _string="Cycle"
+
+ _fields={
+ "name": fields.Char("Name",required=True,search=True),
+ #"time_start": fields.DateTime("Time Start"),
+ #"time_stop": fields.DateTime("Time Stop"),
+ 'duration': fields.Integer("Duration (hrs)"),
+ }
+
+ def _get_time_stop(self,context):
+ time_stop=datetime.now()+timedelta(seconds=3600)
+ return time_stop.strftime(FMT_DATE)
+
+ _defaults={
+ #'time_start': lambda *a: datetime.now().strftime(FMT_DATE),
+ #'time_stop': _get_time_stop,
+ 'duration': 1,
+ }
+
+ def onchange_duration(self,context={}):
+ data=context['data']
+ duration=data['duration']
+ seconds=duration*3600
+ time_start=data['time_start']
+ data['time_stop']=(datetime.strptime(time_start,FMT_DATE)+timedelta(seconds=seconds)).strftime(FMT_DATE)
+ return data
+
+
+Cycle.register()
diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py
index 2da2eeb..566187f 100644
--- a/netforce_clinic/models/hd_case.py
+++ b/netforce_clinic/models/hd_case.py
@@ -24,8 +24,11 @@ class HDcase(Model):
_fields={
"number": fields.Char("Number",required=True,search=True),
+ "time_start": fields.DateTime("Time start",required=True,search=True),
+ "time_stop": fields.DateTime("Time stop",required=True,search=True),
+ "date": fields.Date("Time stop",required=True,search=True),
"patient_id": fields.Many2One("clinic.patient","Patient",required=True,search=True),
- "doctor_id": fields.Many2One("clinic.doctor","Doctor", required=True,search=True),
+ "doctor_id": fields.Many2One("clinic.doctor","Doctor", required=False,search=True),
"nurse_id": fields.Many2One("clinic.nurse","Nurse", required=True,search=True),
"department_id": fields.Many2One("clinic.department", "Department",search=True),
"wh_start": fields.Float("Wt.Kg start"),
@@ -38,9 +41,9 @@ class HDcase(Model):
"state": fields.Selection([("draft","Draft"),("in_progress","In Progress"),("completed","Completed"),("discountinued","Discountinued"),("uncompleted","Uncompleted")],"Status",required=True),
"dialyzers": fields.One2Many("clinic.dialyzer.line","hd_case_id","Dializers"),
"lines": fields.One2Many("clinic.hd.case.line","hd_case_id","Lines"),
+ "gm_lines": fields.One2Many("clinic.hd.case.gm.line","hd_case_id","GM Lines"),
"comments": fields.One2Many("message","related_id","Comments"),
"company_id": fields.Many2One("company","Company"),
- "fee": fields.Float("HD Fee"),
"amount": fields.Float("Due Amount",function="get_total",readonly=True,function_multi=True),
"total": fields.Float("Total",function="get_total",readonly=True,function_multi=True),
"reconcile_id": fields.Many2One("account.reconcile","Reconcile Id",readonly=True),
@@ -48,15 +51,13 @@ class HDcase(Model):
"pickings": fields.One2Many("stock.picking","related_id","Pickings"),
"payments": fields.One2Many("account.payment","related_id","Payments"),
'visit_id': fields.Many2One("clinic.visit", "Visit"),
- 'total_time': fields.Integer("Total Time(Hrs)",function="get_hrs"),
+ 'duration': fields.Integer("Duration (hrs)",function="get_hrs"),
"fee_type": fields.Selection([("mg","Medical Government"),("sc","Social Security"),("nhso","NHSO (30฿)"),("personal","Personal"),("others","Others")],"Fee Type"),
'fee_partner_id': fields.Many2One("partner","Contact Fee"),
- 'paid': fields.Boolean("Paid"),
- "time_start": fields.DateTime("Time start",required=True,search=True),
- "time_stop": fields.DateTime("Time stop",required=True,search=True),
- "date": fields.Date("Date Treatment",required=True),
- 'planes': fields.One2Many("clinic.visit.plane","hd_case_id","Planning"),
+ "fee_amount": fields.Float("Due Amount",function="get_gmtotal",readonly=True,function_multi=True),
+ "fee_total": fields.Float("Total",function="get_gmtotal",readonly=True,function_multi=True),
'note': fields.Text("Note"),
+ "cycle_id": fields.Many2One("clinic.cycle","Cycle"),
}
def _get_number(self,context={}):
@@ -90,6 +91,7 @@ class HDcase(Model):
"number": _get_number,
"company_id": lambda *a: get_active_company(),
"fee": 1500,
+ 'cycle': '1',
}
_order="date desc,number desc"
@@ -156,6 +158,37 @@ class HDcase(Model):
data['total']=total
return data
+ def onchange_gmproduct(self,context={}):
+ data=context['data']
+ path=context["path"]
+ line=get_data_path(data,path,parent=True)
+ product_id=line.get('product_id')
+ if not product_id:
+ return
+ prod=get_model("product").browse(product_id)
+ line['uom_id']=prod.uom_id.id
+ line['description']=prod.name
+ line['qty']=1
+ line['price']=prod.sale_price or 0.0
+ line['amount']=prod.sale_price or 0.0
+ data=self.onchange_gmline(context)
+ return data
+
+ def onchange_gmline(self,context={}):
+ data=context['data']
+ total=0.0
+ for line in data['gm_lines']:
+ price=line.get('price') or 0
+ qty=line.get('qty') or 0
+ amt=qty * price
+ product_id=line.get("product_id")
+ if product_id:
+ line['amount']=amt
+ total+=amt
+ data['fee_total']=total
+ data['fee_amount']=total
+ return data
+
def make_invoices(self,ids,context={}):
setting=get_model("settings").browse(1)
currency_id=setting.currency_id.id
@@ -313,11 +346,12 @@ class HDcase(Model):
def complete(self,ids,context={}):
obj=self.browse(ids)[0]
+ if not obj.dialyzers:
+ raise Exception("Please enter dialyzer!")
obj.make_invoices()
obj.post_invoices()
obj.write({
"state":"completed",
- #'paid': True,
})
return {
'next': {
@@ -357,6 +391,22 @@ class HDcase(Model):
}
return vals
+ def get_gmtotal(self,ids,context={}):
+ vals={}
+ for obj in self.browse(ids):
+ total=0
+ amt=0
+ fee=obj.fee or 0
+ for line in obj.gm_lines:
+ total+=line.amount or 0
+ fee=0 # XXX
+ amt=total+fee
+ vals[obj.id]={
+ "fee_total": total,
+ "fee_amount": amt,
+ }
+ return vals
+
def view_hdcase(self,ids,context={}):
return {
'name': 'clinic_hd_case',
diff --git a/netforce_clinic/models/hd_case_gmline.py b/netforce_clinic/models/hd_case_gmline.py
new file mode 100644
index 0000000..9af8d66
--- /dev/null
+++ b/netforce_clinic/models/hd_case_gmline.py
@@ -0,0 +1,16 @@
+from netforce.model import Model, fields
+
+class HDCaseGMline(Model):
+ _name="clinic.hd.case.gm.line"
+ _fields={
+ "hd_case_id": fields.Many2One("clinic.hd.case","HdCase",required=True,on_delete="cascade"),
+ "product_id": fields.Many2One("product","Product",search=True),
+ "description": fields.Char("Description",search=True),
+ "qty":fields.Integer("QTY"),
+ "uom_id": fields.Many2One("uom","UOM",required=True,search=True),
+ "price":fields.Float("Price"),
+ "amount":fields.Float("Amount"),
+ }
+
+HDCaseGMline.register()
+
diff --git a/netforce_clinic/models/patient.py b/netforce_clinic/models/patient.py
index 038937d..6ee521e 100644
--- a/netforce_clinic/models/patient.py
+++ b/netforce_clinic/models/patient.py
@@ -183,14 +183,6 @@ class Patient(Model):
get_model("partner").delete(partner_ids)
super().delete(ids)
- def _delete(self,ids,context={}):
- partner_ids=[]
- for obj in self.browse(ids):
- if obj.type not in ("mg","nhso","sc"):
- partner_ids.append(obj.partner_id.id)
- get_model("partner").delete(partner_ids)
- super().delete(ids)
-
def write(self,ids,vals,**kw):
for obj in self.browse(ids):
partner_id=obj.partner_id
@@ -207,5 +199,9 @@ class Patient(Model):
})
vals['partner_id']=partner_id
super().write(ids,vals,**kw)
+
+ def generate_visit(self,ids,context={}):
+ obj=self.browse(ids)[0]
+ pass
Patient.register()
diff --git a/netforce_clinic/models/visit.py b/netforce_clinic/models/visit.py
index 874c0cb..f008c31 100644
--- a/netforce_clinic/models/visit.py
+++ b/netforce_clinic/models/visit.py
@@ -1,9 +1,11 @@
import time
-import datetime
+from datetime import datetime, timedelta
from netforce.model import Model, fields, get_model
from netforce.access import get_active_company, get_active_user, set_active_user
-from netforce.utils import get_data_path
+#from netforce.utils import get_data_path
+
+FMT_DATE="%Y-%m-%d %H:%M:%S"
class Visit(Model):
_name="clinic.visit"
@@ -14,35 +16,30 @@ class Visit(Model):
def _get_visit_late(self,ids,context={}):
res={}
- #oneday=datetime.timedelta(days=1)
- #yesterday=datetime.datetime.now()-oneday
datenow=time.strftime("%Y-%m-%d")
for obj in self.browse(ids):
late=0
- if datenow > obj.date_visit and obj.state=='waiting_treatment':
+ if datenow > (obj.date_visit or '') and obj.state=='waiting_treatment':
late=1
res[obj.id]=late
return res
-
_fields={
"number": fields.Char("Number",required=True,search=True),
+ "date": fields.Date("Date Visit"),
+ "time_start": fields.DateTime("Time Start"),
+ "time_stop": fields.DateTime("Time Stop"),
"patient_id": fields.Many2One("clinic.patient","Patient",required=True,search=True),
"doctor_id": fields.Many2One("clinic.doctor","Doctor",search=True),
"nurse_id": fields.Many2One("clinic.nurse","Nurse",search=True),
"department_id": fields.Many2One("clinic.department", "Department",search=True),
- "cycle": fields.Selection([("1","One"),("2","Two"),("3","Tree"),("4","Four")],"Cycle",required=True),
- "state": fields.Selection([("draft","Draft"),("waiting_treatment","Waiting Treatment"),('treatment','Treatment'),("cancelled","Cancelled")],"Status",required=True),
- "comments": fields.One2Many("message","related_id","Comments"),
"company_id": fields.Many2One("company","Company"),
'time_use': fields.Integer("Fix Hour"),
- 'late_visit': fields.Integer("Late Vist",function="_get_visit_late"),
- "dialyzers": fields.One2Many("clinic.dialyzer.line","visit_id","Dialyzers"),
- "date_visit": fields.Date("Visit Date",required=True,search=True),
- "time_start": fields.DateTime("Time Start"),
- "time_stop": fields.DateTime("Time Stop"),
- 'planes': fields.One2Many("clinic.visit.plane","visit_id","Planning"),
+ 'late_visit': fields.Integer("Late Vist",function="_get_visit_late", store=True),
'hd_cases': fields.One2Many('clinic.hd.case','visit_id',"HD Cases",readonly=True),
+ "cycle_id": fields.Many2One("clinic.cycle","Cycle"),
+ "state": fields.Selection([("draft","Draft"),("waiting_treatment","Waiting Treatment"),('treatment','Treatment'),("cancelled","Cancelled")],"Status",required=True),
+ "comments": fields.One2Many("message","related_id","Comments"),
}
def _get_number(self,context={}):
@@ -68,25 +65,25 @@ class Visit(Model):
return None
def _get_time_start(self,context={}):
- now=datetime.datetime.now()
+ now=datetime.now()
starttime=now.strftime("%Y-%m-%d %H:%M:%S")
return starttime
def _get_time_stop(self,context={}):
- hr=datetime.timedelta(seconds=3600)
- now=datetime.datetime.now()
+ hr=timedelta(seconds=3600)
+ now=datetime.now()
stoptime=(now+hr).strftime("%Y-%m-%d %H:%M:%S")
return stoptime
_defaults={
"state": "draft",
- "cycle": "1",
- 'date_visit': lambda *a: time.strftime("%Y-%m-%d"),
+ 'date': lambda *a: time.strftime("%Y-%m-%d"),
'time_start': _get_time_start,
'time_stop': _get_time_stop,
"number": "/",
"company_id": lambda *a: get_active_company(),
'nurse_id': _get_nurse,
+ 'cycle': '1',
'time_use': 1,
}
_order="id desc"
@@ -107,19 +104,15 @@ class Visit(Model):
def do_treatment(self,ids,context={}):
hd_case_obj=get_model("clinic.hd.case")
- dt=datetime.datetime
+ dt=datetime
datenow=dt.now().strftime("%Y-%m-%d")
-
obj=self.browse(ids)[0]
+ date_visit=obj.time_start[0:10]
# cannot treatment if current date is not same visit date
- if obj.date_visit!=datenow:
+ if date_visit!=datenow:
raise Exception("Today is not treament date!")
- if not obj.dialyzers:
- raise Exception("Please select dialyzer!")
- if len(obj.dialyzers)>1:
- raise Exception("Can select only 1 dialyzer!")
- include_fee=obj.patient_id.type in ('mg','sc','nhso') and True or False
+ #include_fee=obj.patient_id.type in ('mg','sc','nhso') and True or False
vals={
'patient_id': obj.patient_id.id,
'doctor_id': obj.doctor_id.id,
@@ -128,7 +121,8 @@ class Visit(Model):
'time_start': obj.time_start,
'time_stop': obj.time_stop,
'visit_id': obj.id,
- 'fee': include_fee and 1500.00 or 0.0,
+ 'cycle_id': obj.cycle_id.id,
+ #'fee': include_fee and 1500.00 or 0.0,
'fee_type': obj.patient_id.type,
'lines':[],
'dialyzers': [],
@@ -155,21 +149,7 @@ class Visit(Model):
vals['fee_partner_id']=partner_id
break
- # find dialyser
- if not obj.dialyzers:
- raise Exception("%s don't have dialyzer for treatment yet" % obj.patient_id.name)
hd_case_id=hd_case_obj.create(vals)
- for dlz in obj.dialyzers:
- # TODO check max time and expire day also
- dlz.dialyzer_id.write({'use_time': dlz.use_time}) # count use time
- dlz.write({
- 'hd_case_id': hd_case_id,
- })
-
- for plan in obj.planes:
- plan.write({
- 'hd_case_id': hd_case_id,
- })
obj.write({"state":"treatment"})
return {
'next': {
@@ -193,14 +173,9 @@ class Visit(Model):
patient_id=data['patient_id']
visits=self.search_browse([['patient_id','=',patient_id]],order="number desc")
if visits:
- #print([(v.id, v.date_visit,v.cycle) for v in visits])
visit=visits[0]
data['doctor_id']=visit.doctor_id.id
data['department_id']=visit.department_id.id
- cycle=int(visit.cycle)+1
- data['cycle']=str(cycle)
- if cycle>4:
- data['cycle']='1'
else:
data['doctor_id']=None
data['department_id']=None
@@ -213,15 +188,8 @@ class Visit(Model):
'doctor_id': obj.doctor_id.id,
'nurse_id': obj.nurse_id.id,
'department_id': obj.department_id.id,
+ 'cycle': obj.cycle,
}
- # XXX update cycle
- visits=self.search_browse([['patient_id','=',obj.patient_id.id]],order="number desc")
- if visits:
- visit=visits[0] # order desc already
- cycle=int(visit.cycle)+1
- vals['cycle']=str(cycle)
- if cycle>4:
- vals['cycle']='1'
new_id=self.create(vals,context=context)
new_obj=self.browse(new_id)
return {
@@ -246,7 +214,6 @@ class Visit(Model):
return {}
ref_id=int(ref_id)
obj=self.browse(ref_id)
- cycle_list={'1': 'One','2': 'Two','3': 'Tree','4': 'Four'}
data={
'number': obj.number,
'date_visit': obj.date_visit,
@@ -254,81 +221,23 @@ class Visit(Model):
'patient_name': obj.patient_id.name or "",
'doctor_name': obj.doctor_id.name or "",
'nurse_name': obj.nurse_id.name or "",
- 'cycle': cycle_list.get(obj.cycle,""),
'print_date': time.strftime("%d/%m/%Y"),
}
return data
- def onchange_dialyzer(self,context={}):
- data=context["data"]
- path=context["path"]
- line=get_data_path(data,path,parent=True)
- dialyzer_id=line.get("dialyzer_id")
- if not dialyzer_id:
- return {}
- dialyzer=get_model("clinic.dialyzer").browse(dialyzer_id)
- use_time=dialyzer.use_time or 0
- use_time+=1
- line["description"]=dialyzer.description or ""
- line["use_time"]=use_time
- line["max_use_time"]=dialyzer.max_use_time
- line["member_type"]=dialyzer.member_type
- line["dialyzer_type"]=dialyzer.dialyzer_type
- line["bid_flow_rate"]=dialyzer.bid_flow_rate
- line["ultrafittration"]=dialyzer.ultrafittration
- line["state"]=dialyzer.state
- return data
-
- def onchange_timeuse(self,context={}):
- data=context["data"]
+ def onchange_time(self,context={}):
+ data=context['data']
+ cycle_id=data['cycle_id']
+ duration=1
+ if cycle_id:
+ cycle=get_model('clinic.cycle').browse(cycle_id)
+ duration=cycle.duration or 0
+ seconds=duration*3600
time_start=data['time_start']
- fmt_date="%Y-%m-%d %H:%M:%S"
- time_start=datetime.datetime.strptime(time_start,fmt_date)
- time_use=data['time_use']
- seconds=(time_use or 1)*3600
- time_stop=time_start+datetime.timedelta(seconds=seconds)
- data['time_stop']=time_stop.strftime(fmt_date)
+ data['time_stop']=(datetime.strptime(time_start,FMT_DATE)+timedelta(seconds=seconds)).strftime(FMT_DATE)
return data
+
- def onchange_date_visit(self,context={}):
- data=context["data"]
- timenow=time.strftime("%H:%M:%S")
- date_visit=data['date_visit']
- fmt_date="%Y-%m-%d %H:%M:%S"
- time_start=datetime.datetime.strptime("%s %s"%(date_visit,timenow),fmt_date)
- print("time_start ", time_start)
- time_use=data['time_use']
- seconds=(time_use or 1)*3600
- time_stop=time_start+datetime.timedelta(seconds=seconds)
- data['time_start']=time_start.strftime(fmt_date)
- data['time_stop']=time_stop.strftime(fmt_date)
- return data
-
- def onchange_dateplane(self,context={}):
- data=context["data"]
- path=context["path"]
- line=get_data_path(data,path,parent=True)
- start_date=line.get("date")
- if not start_date:
- return {}
- timenow=time.strftime("%H:%M:%S")
- timevisit=timenow
- # XXX
- timevisit=data['time_start'][11:20]
- if not timevisit:
- timevisit=timenow
- fmt_date="%Y-%m-%d %H:%M:%S"
- fix_hrs=data['time_use'] or 0
- time_start=datetime.datetime.strptime("%s %s"%(start_date,timevisit),fmt_date)
- seconds=fix_hrs*3600
- time_stop=time_start+datetime.timedelta(seconds=seconds)
- line['time_start']=time_start.strftime(fmt_date)
- line['time_stop']=time_stop.strftime(fmt_date)
- if not line.get('state'):
- line['state']='open'
-
- return data
-
def create_dialyzer(self,ids,context={}):
return {
'next': {
@@ -336,6 +245,6 @@ class Visit(Model):
'mode': 'form',
},
}
-
+
Visit.register()
diff --git a/netforce_clinic/models/visit_line.py b/netforce_clinic/models/visit_line.py
new file mode 100644
index 0000000..b79b967
--- /dev/null
+++ b/netforce_clinic/models/visit_line.py
@@ -0,0 +1,15 @@
+from netforce.model import Model, fields, get_model
+
+class VisitLine(Model):
+ _name="clinic.visit.line"
+ _string="Visit Line"
+
+ _fields={
+ 'visit_id': fields.Many2One("clinic.visit","Visit"),
+ 'cycle_id': fields.Many2One("clinic.cycle","Cycle"),
+ 'time_start': fields.DateTime("Time Start"),
+ 'time_stop': fields.DateTime("Time Stop"),
+ "state": fields.Selection([("pending","Pending"),("completed","Completed")],"Status"),
+ }
+
+VisitLine.register()
diff --git a/netforce_clinic/todo.txt b/netforce_clinic/todo.txt
index 5507997..33d8862 100644
--- a/netforce_clinic/todo.txt
+++ b/netforce_clinic/todo.txt
@@ -1,7 +1,30 @@
+=====
+ select diaylizer at treatment page
+
+
+=====
+ step:
+ nurse
+ 1. go to visit calendar
+ - auto gen visit
+ 2. go to visit
+ - confirm
+ - copy data to hd case
+ - patient
+ - doctor
+ - department
+ - nurse
+ - other ...
+ - auto generate cycle (4 cycle)
+ 3. go to hd case
+ - select dialyzer
+ - if not we can no do treament
+
===== todo
- monday:
- - A, B, C, D
- tueday:
+ ######
+ - import payment
+ - visit planing
+ ######
========
Account Receivable -> invoice
find account id