conv_bal
chayut.s 2014-10-29 11:56:52 +07:00
commit 3659c07fe1
49 changed files with 727 additions and 249 deletions

View File

@ -1,6 +1,6 @@
<action>
<field name="name">clinic_board</field>
<field name="string">Visit Board</field>
<field name="string">Clinic Board</field>
<field name="view_cls">board</field>
<field name="view_xml">clinic_board</field>
<field name="menu">clinic_menu</field>

View File

@ -0,0 +1,6 @@
<action>
<field name="view_cls">chart_view</field>
<field name="model">clinic.report</field>
<field name="method">cycle_recent_widget</field>
<field name="chart_type">pie</field>
</action>

View File

@ -1,7 +1,7 @@
<action>
<field name="string">Social Security</field>
<field name="view_cls">multi_view</field>
<field name="tabs">[["All",[]],["Success",[["type","=","success"]]],["Fail",[["type","=","fail"]]]]</field>
<field name="tabs">[["All",[]],["Match",[["type","=","match"]]],["Not Match",[["type","=","not_match"]]]]</field>
<field name="model">clinic.data.sc</field>
<field name="menu">account_menu</field>
</action>

View File

@ -2,7 +2,7 @@
<field name="string">Doctors</field>
<field name="view_cls">multi_view</field>
<field name="model">clinic.doctor</field>
<field name="tabs">[["All",[]],["Temporaly",[["type","=","temporary"]]],["Permanent",[["type","=","permanent"]]]]</field>
<field name="tabs">[["All",[]],["Archived",[["active","=",false]]],["Temporaly",[["type","=","temporary"]]],["Permanent",[["type","=","permanent"]]]]</field>
<field name="modes">list,page,form</field>
<field name="menu">clinic_menu</field>
</action>

View File

@ -2,7 +2,7 @@
<field name="string">Nurses</field>
<field name="view_cls">multi_view</field>
<field name="model">clinic.nurse</field>
<field name="tabs">[["All",[]],["Temporaly",[["type","=","temporary"]]],["Permanent",[["type","=","permanent"]]]]</field>
<field name="tabs">[["All",[]],["Archived",[["active","=",false]]],["Temporaly",[["type","=","temporary"]]],["Permanent",[["type","=","permanent"]]]]</field>
<field name="modes">list,page,form</field>
<field name="menu">clinic_menu</field>
</action>

View File

@ -0,0 +1,7 @@
<action>
<field name="view_cls">list_view</field>
<field name="model">clinic.patient</field>
<field name="order">write_time desc</field>
<field name="limit">5</field>
<field name="view_xml">clinic_recent_patient_widget</field>
</action>

View File

@ -0,0 +1,7 @@
<action>
<field name="string">Schedules</field>
<field name="view_cls">multi_view</field>
<field name="model">clinic.schedule</field>
<field name="modes">calendar,list,page,form</field>
<field name="menu">clinic_menu</field>
</action>

View File

@ -3,6 +3,6 @@
<field name="view_cls">multi_view</field>
<field name="model">clinic.visit</field>
<field name="tabs">[["All",[]],["Draft",[["state","=","draft"]]],["Confirmed",[["state","=","confirmed"]]],["Cancelled",[["state","=","cancelled"]]]]</field>
<field name="modes">list,calendar,form</field>
<field name="modes">calendar,list,form</field>
<field name="menu">clinic_menu</field>
</action>

View File

@ -1,5 +1,11 @@
<board>
<hpanel>
<widget action="clinic_visit_cal_widget" string="Visits Calendar" span="12"/>
</hpanel>
<!--<hpanel>-->
<!--<widget action="clinic_visit_cal_widget" string="Visits Calendar" span="12"/>-->
<!--</hpanel>-->
<vpanel>
<widget action="clinic_cycle_widget" string="Average Cycle" span="12"/>
</vpanel>
<vpanel>
<widget action="clinic_recent_patient_widget" string="Recent Patient" span="12"/>
</vpanel>
</board>

View File

@ -6,6 +6,7 @@
<field name="name"/>
<field name="duration"/>
<field name="sequence"/>
<field name="color"/>
<related>
<field name="cycle_items"/>
<field name="visits"/>

View File

@ -2,8 +2,8 @@
<head>
<field name="state"/>
<button string="Options" dropdown="1">
<item string="Create Journal" method="create_journal" states="draft"/>
<item string="View Journal" method="view_journal" states="done"/>
<item string="Create Payment" method="create_payment" states="draft"/>
<item string="View Payment" method="view_payment" states="done"/>
<item string="To Draft" method="to_draft" states="done"/>
</button>
</head>

View File

@ -1,4 +1,8 @@
<list model="clinic.cycle.item" colors='{"#9f9":[["state","=","done"]]}'>
<head>
<button string="Pay" method="pay" icon="ok" type="success" confirm="Are you sure?"/>
<!--<button string="To Draft" method="to_drafts" icon="repeat" type="default" confirm="Are you sure?"/>-->
</head>
<field name="name"/>
<field name="cycle_id"/>
<field name="date"/>

View File

@ -2,4 +2,5 @@
<field name="name"/>
<field name="duration"/>
<field name="sequence"/>
<field name="color"/>
</list>

View File

@ -11,4 +11,5 @@
<field name="st"/>
<field name="allow37"/>
<field name="type"/>
<field name="hd_case_id"/>
</form>

View File

@ -1,4 +1,4 @@
<list model="clinic.data.sc" colors='{"red":[["type","=","fail"]]}'>
<list model="clinic.data.sc" colors='{"red":[["type","=","not_match"]]}'>
<field name="hn"/>
<field name="name14"/>
<field name="hcode18"/>
@ -11,4 +11,5 @@
<field name="st"/>
<field name="allow37"/>
<field name="type"/>
<field name="hd_case_id"/>
</list>

View File

@ -23,6 +23,7 @@
<field name="email"/>
<field name="mobile"/>
<field name="phone"/>
<field name="active"/>
</group>
<separator string="Address Information"/>
<field name="addresses" view="form_list"/>

View File

@ -14,6 +14,8 @@
<field name="wednesday" span="4"/>
<field name="thursday" span="4"/>
<field name="friday" span="4"/>
<field name="sathurday" span="4"/>
<field name="sunday" span="4"/>
<field name="lines" nolabel="1">
<list>
<field name="patient_id"/>

View File

@ -1,6 +0,0 @@
<form model="clinic.input.data">
<field name="doc_date"/>
<field name="name"/>
<field name="hn"/>
<field name="amount"/>
</form>

View File

@ -19,11 +19,12 @@
<item string="Comorbidities" action="clinic_comorbidity"/>
<item string="Morbidities" action="clinic_morbidity"/>
</item>
<item string="Schedules" action="clinic_schedule"/>
<item string="Visits" action="clinic_visit"/>
<item string="Cycles">
<item string="Cycles" action="clinic_cycle"/>
<item string="Cycle Items" action="clinic_cycle_item"/>
</item>
<item string="Visits" action="clinic_visit"/>
<item string="Treatments" action="clinic_hd_case"/>
<item string="Reports">
<header string="HD CASE"/>

View File

@ -23,6 +23,7 @@
<field name="email"/>
<field name="mobile"/>
<field name="phone"/>
<field name="active"/>
</group>
<separator string="Address Information"/>
<field name="addresses" view="form_list"/>

View File

@ -3,7 +3,8 @@
<field name="type"/>
<button string="Options" dropdown="1">
<item string="Generate Visit" action="clinic_gen_visit"/>
<item string="Generate Dialyzer" action="clinic_gen_dialyzer"/>
<item string="New Dialyzer" method="new_dialyzer"/>
<item string="Simple Address" method="simple_address"/>
</button>
</head>
<field name="number"/>
@ -13,6 +14,7 @@
<field name="hn"/>
<field name="reg_date"/>
<field name="partner_id"/>
<field name="active"/>
<tabs>
<tab string="General Information">
<group span="6" columns="1">

View File

@ -0,0 +1,8 @@
<list model="clinic.patient">
<!--<head>-->
<!--<button string="Add Product" icon="plus-sign" noselect="1" action="product" action_options="mode=form"/>-->
<!--</head>-->
<field name="number"/>
<field name="name"/>
<field name="type"/>
</list>

View File

@ -0,0 +1,4 @@
<calendar model="clinic.schedule" start_field="time_start" end_field="time_stop">
<field name="name"/>
<field name="cycle_id"/>
</calendar>

View File

@ -0,0 +1,11 @@
<form model="clinic.schedule">
<head>
<button string="Options" dropdown="1">
<item string="Copy" method="copy"/>
</button>
</head>
<field name="time_start"/>
<field name="time_start"/>
<field name="cycle_id"/>
<field name="nurses"/>
</form>

View File

@ -0,0 +1,5 @@
<list model="clinic.schedule">
<field name="name"/>
<field name="time_start"/>
<field name="time_start"/>
</list>

View File

@ -1,4 +1,17 @@
<form model="clinic.setting" title="Clinic Settings">
<separator string="Labor Cost"/>
<field name="var_k"/>
<tabs>
<tab string="Testing">
<field name="file"/>
<newline/>
</tab>
<tab string="General">
<separator string="Labor Cost"/>
<field name="var_k"/>
</tab>
</tabs>
<foot>
<button string="Make Visit" method="make_visit"/>
<button string="Make HD Case" method="make_done"/>
<button string="Complete HD Case" method="make_complete"/>
</foot>
</form>

View File

@ -9,5 +9,6 @@
<field name="ap_nhso_id"/>
<field name="ap_nurse_id"/>
<field name="ap_doctor_id"/>
<field name="hospital_code"/>
</field>
</inherit>

View File

@ -1,6 +1,7 @@
<form title="Import Social Security">
<group span="6" columns="1">
<field name="file"/>
<field name="hcode"/>
</group>
<group span="6" columns="1">
<separator string="Result"/>
@ -11,5 +12,8 @@
</group>
<foot replace="1">
<button string="Import Data" method="import_sc" type="primary" icon="arrow-right"/>
<!--<button string="Match Invoice" method="match_invoice_sc" icon="retweet" type="default"/>-->
<button string="Approve" method="approve_sc" icon="ok" type="success"/>
<button string="Clear" method="clear_sc" type="danger" icon="remove"/>
</foot>
</form>

View File

@ -25,7 +25,6 @@ from . import hd_case_payment
from . import dialyzer
from . import dialyzer_line
from . import import_payment
from . import file_sheet
from . import cycle
from . import cycle_item
from . import cycle_item_line
@ -34,7 +33,8 @@ from . import gen_visit_line
from . import report_hd_detail
from . import report_hd_summary
from . import report_hd_medical
from . import input_data
from . import report_hd_payment
from . import report_clinic
from . import fin_setting
from . import import_data_mg
from . import import_data_nhso
@ -42,5 +42,6 @@ from . import import_data_sc
from . import translate
from . import payment
from . import account_payment
from . import report_hd_payment
from . import account_invoice
from . import personal_categ
from . import schedule

View File

@ -0,0 +1,24 @@
from netforce.model import Model, fields, get_model
class AccountPayment(Model):
_inherit="account.payment"
def run_report(self,ids,context={}):
obj=self.browse(ids)[0]
hd_case_id=obj.related_id.id
hd_case=get_model("clinic.hd.case").browse(hd_case_id)
# TODO
# set payment_id on hd case
# send to action print form payment
hd_case.write({
'payment_id': obj.id,
})
return {
'next': {
'name': 'report_clinic_payment_form',
'refer_id': hd_case_id,
'payment_id': obj.id,
},
}
AccountPayment.register()

View File

@ -14,6 +14,7 @@ class Cycle(Model):
'visits': fields.One2Many("clinic.visit","cycle_id", "Visits"),
'cycle_items': fields.One2Many("clinic.cycle.item","cycle_id", "Cycle Items"),
'var_k': fields.Float("K"),
'color': fields.Char("Color"),
}
_defaults={

View File

@ -1,3 +1,4 @@
import re
import time
from netforce.model import Model, fields, get_model
@ -20,10 +21,10 @@ class CycleItem(Model):
x=(pt_k + 1275)/13.5
total=0.0
for line in obj.nurse_lines:
total+=line.amount
total+=(line.amount or 0.0)
total2=0.0
for line in obj.doctor_lines:
total2+=line.amount
total2+=(line.amount or 0.0)
res[obj.id]={
'name': name,
'var_x': x,
@ -63,6 +64,7 @@ class CycleItem(Model):
}
def compute(self,ids,context={}):
# XXX should compute after hd case done
for obj in self.browse(ids):
vals={
'nurse_lines': [],
@ -102,6 +104,7 @@ class CycleItem(Model):
'formular': categ.formular,
'qty': qty,
'rate': obj.var_doctor or 0.0,
'amount': qty*obj.var_doctor,
}))
print(nurse_dict)
@ -115,13 +118,17 @@ class CycleItem(Model):
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': nurse_dict.get(personal_categ.code,0),
'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)
@ -133,34 +140,95 @@ class CycleItem(Model):
},
'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']:
line['amount']=(line['qty'] or 0) * (line['rate'] or 0.0)
formular=line['formular']
values.append(line['qty'])
items.append(formular)
qty=line['qty']
rate=line['rate']
line['amount']=qty*rate
total+=line['amount']
print(line)
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_journal(self,ids,context={}):
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")
raise Exception("No Account payment for Nurse")
vals={
"company_id": obj.company_id.id,
"type": "in",
"type": "out",
"pay_type": "direct",
#"date": time.strftime("%Y-%m-%d"),
"date": obj.date or time.strftime("%Y-%m-%d"),
"account_id": account_id,
'related_id': "clinic.cycle.item,%s"%obj.id,
@ -176,6 +244,9 @@ class CycleItem(Model):
'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
@ -187,11 +258,13 @@ class CycleItem(Model):
'amount': line.amount,
}))
payment_id=get_model("account.payment").create(vals,context={"type":"in"})
get_model("account.payment").browse(payment_id).post()
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',
@ -210,6 +283,8 @@ class CycleItem(Model):
obj.write({
'state': 'draft',
})
if context.get('called'):
return obj.id
return {
'next': {
'name': 'clinic_cycle_item',
@ -218,8 +293,20 @@ class CycleItem(Model):
},
'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_journal(self,ids,context={}):
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]])
@ -233,5 +320,17 @@ class CycleItem(Model):
},
}
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()

View File

@ -21,7 +21,8 @@ class CycleItemLine(Model):
'description': fields.Char("Description"),
'qty': fields.Integer("Qty"),
'rate': fields.Float("Rate"),
'amount': fields.Float("Amount",function="all_amount", function_multi=True),
#'amount': fields.Float("Amount",function="all_amount", function_multi=True),
'amount': fields.Float("Amount"),
'company_id': fields.Many2One('company','Company'),
}

View File

@ -45,6 +45,7 @@ class Doctor(Model):
'picture': fields.File("Picture"),
'note': fields.Text("Note"),
'categ_id': fields.Many2One("clinic.personal.categ", "Doctor Category", domain=[['type','=','doctor']]),
'active': fields.Boolean("Active"),
}

View File

@ -1,14 +0,0 @@
from netforce.model import Model, fields
class FileSheet(Model):
_name="clinic.file.sheet"
_string="File Sheet"
_fields={
'name': fields.Char("Name"),
'index': fields.Integer("Index"),
"select": fields.Selection([("yes","Yes"),("no","No")],"Select"),
'imp_id': fields.Many2One("clinic.import.payment","Import Payment"),
}
FileSheet.register()

View File

@ -10,7 +10,8 @@ class Settings(Model):
"ar_nhso_id": fields.Many2One("account.account","Account Recieve NHSO 30B"),
"ar_sc_id": fields.Many2One("account.account","Account Recieve Social Security"),
"ap_nurse_id": fields.Many2One("account.account","Account Payment Nurse"),
"ap_doctor_id": fields.Many2One("account.account","Account Doctor Nurse"),
"ap_doctor_id": fields.Many2One("account.account","Account Payment Doctor"),
'hospital_code': fields.Char("Hospital Code", multi_company=True),
}
Settings.register()

View File

@ -29,6 +29,8 @@ class GenVisit(Model):
'wednesday': fields.Boolean("Wednesdays"),
'thursday': fields.Boolean("Thursdays"),
'friday': fields.Boolean("Fridays"),
'sathurday': fields.Boolean("Sathurday"),
'sunday': fields.Boolean("Sunday"),
'doctor_id': fields.Many2One("clinic.doctor","Doctor"),
'nurse_id': fields.Many2One("clinic.nurse","Nurse"),
'department_id': fields.Many2One("clinic.department","Department"),
@ -96,6 +98,8 @@ class GenVisit(Model):
obj.wednesday and 3 or 0,
obj.thursday and 4 or 0,
obj.friday and 5 or 0,
obj.sathurday and 6 or 0,
obj.sunday and 7 or 0,
]
days=[day for day in days if day]
if not days:

View File

@ -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"), # compute labor cost
"cycle_item_id": fields.Many2One("clinic.cycle.item","Cycle Item",on_delete="cascade"), # compute labor cost
'pay_amount': fields.Float("Amount",function="get_pay_amount"),
'pay_date': fields.Date("Pay Date"),
'pay_account_id': fields.Many2One("account.account","Account"),
@ -465,7 +465,9 @@ class HDCase(Model):
def create_cycle_item(self,ids,context={}):
for obj in self.browse(ids):
cycle_item=get_model("clinic.cycle.item")
datenow=time.strftime('%Y-%m-%d')
datenow=obj.time_start[0:10]
if not datenow:
datenow=time.strftime('%Y-%m-%d')
cycle_id=obj.cycle_id.id
cycle_item_ids=cycle_item.search([['date','=',datenow],['cycle_id','=',cycle_id]])
cycle_item_id=None
@ -489,6 +491,8 @@ class HDCase(Model):
obj.write({
"state":"completed",
})
if context.get("called"):
return obj.id
return {
'next': {
'name': 'clinic_hd_case',
@ -649,7 +653,6 @@ class HDCase(Model):
dlz_vals['company_id']=dlz_vals['company_id'][0]
product_name=dlz_vals['product_id'][1]
dlz_vals['product_id']=dlz_vals['product_id'][0]
dlz_id=get_model('clinic.dialyzer').create(dlz_vals)
dialyzer=get_model("clinic.dialyzer").browse(dlz_id)
dialyzer.confirm()
@ -669,6 +672,8 @@ class HDCase(Model):
'state': dialyzer.state,
}))
obj.write(vals)
if context.get('called'):
return obj.id
return {
'next': {
'name': 'clinic_hd_case',

View File

@ -15,8 +15,11 @@ class ImportDataSC(Model):
'st': fields.Char('st'),
'allow37': fields.Char('allow37'),
'dttran': fields.Date("dttran"),
'type': fields.Selection([['success','Succes'],['fail','Fail']],'Type', search=True),
'type': fields.Selection([['match','Match'],['not_match','Not Match']],'Type', search=True),
'hd_case_id': fields.Many2One("clinic.hd.case","HD Case"),
#'invoice_id': fields.Many2One("clinic.hd.case","HD Case"),
}
_order="type"
ImportDataSC.register()

View File

@ -12,14 +12,22 @@ from netforce.database import get_connection
class ImportPayment(Model):
_name="clinic.import.payment"
_transient=True
_fields={
'date': fields.DateTime("Date"),
'file': fields.File("File"),
'result': fields.Text("Success"),
'hcode': fields.Char("Hospital Code"),
}
def get_hcode(self,context={}):
settings=get_model("settings").browse(1)
hcode=settings.hospital_code or ""
return hcode
_defaults={
'date': lambda *a: time.strftime("%Y-%m-%d %H:%M:%S"),
'hcode': get_hcode,
}
def read_excel(self,fpath=None):
@ -121,6 +129,15 @@ class ImportPayment(Model):
old_patient=[x['hn'] for x in patient.search_read([],['hn']) if x['hn']]
fail_qty=0
success_qty=0
hd_cases=get_model("clinic.hd.case").search_browse([['state','=','completed']])
def get_hdcase(hn,date):
for hd_case in hd_cases:
hd_date=hd_case.time_start[0:10]
if hn==hd_case.patient_id.hn and date==hd_date: #XXX
return hd_case.id
for line in lines:
hn=line.get('hn')
if not hn:
@ -136,11 +153,18 @@ class ImportPayment(Model):
st.update({hn: line.get('name14')})
print("create %s ok"%hn)
hcode=int((line.get('hcode18') or "0")) # XXX
type=hcode==23869 and 'success' or 'fail'
if type=='success':
type='match'
if hcode!=(int(obj.hcode)):
continue
dttran=line.get("dttran","")
hd_case_id=get_hdcase(hn,dttran)
if hd_case_id:
success_qty+=1
else:
fail_qty+=1
type='not_match'
vals={
'hn': hn,
'name14': line.get('name14'),
@ -154,6 +178,7 @@ class ImportPayment(Model):
'allow37': line.get('allow37'),
'dttran': line.get("dttran"),
'type': type,
'hd_case_id': hd_case_id,
}
data_sc.create(vals)
msg=''
@ -171,7 +196,63 @@ class ImportPayment(Model):
fname=obj.file
fpath=get_file_path(fname)
print("fpath ", fpath)
def clear_sc(self,ids,context={}):
sc_ids=get_model("clinic.data.sc").search([])
get_model("clinic.data.sc").delete(sc_ids)
obj=self.browse(ids)[0]
obj.write({
'result': 'Clear OK',
})
def match_invoice_sc(self,ids,context={}):
obj=self.browse(ids)[0]
for sc in get_model("clinic.data.sc").search_browse([['type','=','match']]):
for invoice in sc.hd_case_id.invoices:
print(invoice.number)
obj.write({
'result': 'Match OK',
})
def approve_sc(self,ids,context={}):
settings=get_model("settings").browse(1)
account_id=settings.ap_sc_id.id
if not account_id:
raise Exception("No Account payment for Social Security")
obj=self.browse(ids)[0]
vals={
'partner_id': '',
"company_id": get_active_company(),
"type": "in",
"pay_type": "invoice",
"date": obj.date or time.strftime("%Y-%m-%d"),
"account_id": account_id,
'invoice_lines': [],
}
invoice_ids=[]
partner_id=None
for sc in get_model("clinic.data.sc").search_browse([['type','=','match']]):
if not partner_id:
partner_id=sc.hd_case_id.fee_partner_id.id
for invoice in sc.hd_case_id.invoices:
invoice_ids.append(invoice.id)
vals['invoice_lines'].append(('create',{
'invoice_id': invoice.id,
'amount': invoice.amount_due or 0.0,
}))
sc.delete() #XXX
vals['partner_id']=partner_id
payment_id=get_model("account.payment").create(vals,context={"type":"in"})
#get_model("account.payment").browse(payment_id).post()
return {
'next': {
'name': 'payment',
'mode': 'form',
'active_id': payment_id,
},
'flash': 'Paid',
}
ImportPayment.register()

View File

@ -1,18 +0,0 @@
from netforce.model import Model, fields, get_model
class InputData(Model):
_name="clinic.input.data"
_transient=True
_fields={
'date': fields.Date("Date"),
'name': fields.Char("Patient Name"),
'hn': fields.Char("HN"),
'amount': fields.Char("Amount"),
'hct': fields.Char("HCT"),
'medical_type': fields.Char("Medical Type"),
'medical_cost': fields.Char("Medical Cost"),
'other_cost': fields.Char("Other Cost"),
}
InputData.register()

View File

@ -45,6 +45,7 @@ class Nurse(Model):
'picture': fields.File("Picture"),
'note': fields.Text("Note"),
'categ_id': fields.Many2One("clinic.personal.categ", "Nurse Category", domain=[['type','=','nurse']]),
'active': fields.Boolean("Active"),
}
def _get_number(self,context={}):

View File

@ -77,6 +77,7 @@ class Patient(Model):
"partner_id": fields.Many2One("partner","Contact"),
"dialyzers": fields.One2Many("clinic.dialyzer","patient_id","Dialyzers"),
"active":fields.Boolean("Active"),
}
def _get_number(self,context={}):
@ -93,6 +94,7 @@ class Patient(Model):
return num
get_model("sequence").increment_number(seq_id,context=context)
def _get_cause_line(self,context={}):
cause_ids=get_model("clinic.cause.chronic").search([])
return cause_ids
@ -105,15 +107,14 @@ class Patient(Model):
"company_id": lambda *a: get_active_company(),
#'cause_lines': _get_cause_line,
"active" : True,
}
_order="date desc,number desc"
def void(self,ids,context={}):
def void(self,ids, context={}):
obj=self.browse(ids)[0]
obj.write({"state":"voided"})
def get_partner_id(self,patient_type,data):
def get_partner_id( self,patient_type,data):
partner_obj=get_model("partner")
categ_name=PATIENT_TYPE.get(patient_type)
categ_ids=get_model("partner.categ").search([['name','=',categ_name]])
@ -148,9 +149,9 @@ class Patient(Model):
if patient_type:
partner_id=self.get_partner_id(patient_type,data)
data['partner_id']=partner_id
return data
return data
def create(self,vals,**kw):
def create(self, vals,**kw):
obj_id=super(Patient,self).create(vals,**kw)
obj=self.browse(obj_id)
partner_id=obj.partner_id
@ -251,5 +252,49 @@ class Patient(Model):
ids3=self.search(dom)
ids=list(set(ids1+ids2+ids3))
return self.name_get(ids,context=context)
def simple_address(self,ids,context={}):
print("call simple address ")
for obj in self.browse(ids):
if not obj.addresses:
address_id=get_model("address").create({
'patient_id': obj.id,
'partner_id': obj.partner_id.id,
'type': 'shipping',
'address': 'xxxx',
'address2': 'xxxx',
'city': 'BKK',
'country_id': 1,
'postal_code': '12000',
})
if context.get('called'):
return obj.id
return {
'next': {
'name': 'clinic_patient',
'mode': 'form',
'active_id': obj.id,
},'flash': 'Simple Address OK',
}
def new_dialyzer(self,ids,context={}):
dlz_id=None
for obj in self.browse(ids):
dlz_vals=get_model("clinic.dialyzer").default_get()
dlz_vals['patient_id']=obj.id
dlz_vals['company_id']=dlz_vals['company_id'][0]
dlz_vals['product_id']=dlz_vals['product_id'][0]
dlz_id=get_model('clinic.dialyzer').create(dlz_vals)
dialyzer=get_model("clinic.dialyzer").browse(dlz_id)
dialyzer.confirm()
if context.get('called'):
return dlz_id
return {
'next': {
'name': 'clinic_patient',
'mode': 'form',
'active_id': obj.id,
},'flash': 'New Dialyzer successfully',
}
Patient.register()

View File

@ -17,6 +17,7 @@ class NurseCateg(Model):
"company_id": lambda *a: get_active_company(),
'sequence': 0,
'type': 'doctor',
'formular': '',
}
_order="sequence"

View File

@ -0,0 +1,16 @@
from netforce.model import Model
from netforce.database import get_connection
class Report(Model):
_name="clinic.report"
_store=False
def cycle_recent_widget(self,context={}):
db=get_connection()
res=db.query("select count(cycle_id) as count, c.name from clinic_hd_case as hd inner join clinic_cycle as c on c.id=hd.cycle_id group by c.name;")
data=[]
for r in res:
data.append((r.name,r.count))
return {"value":data}
Report.register()

View File

@ -0,0 +1,29 @@
from netforce.model import Model, fields
from netforce.access import get_active_company
class Schedule(Model):
_name="clinic.schedule"
_string="Schedule"
#_field_name="cycle_id"
def _get_name(self,ids,context={}):
res={}
for obj in self.browse(ids):
total_nurse=len(obj.nurses)
res[obj.id]='Cycle: %s, Nurse: %s'%(obj.cycle_id.name or "", total_nurse)
return res
_fields={
"name": fields.Char("Name",function="_get_name"),
'cycle_id': fields.Many2One("clinic.cycle","Cycle",required=True),
"time_start": fields.DateTime("Time Start",required=True),
"time_stop": fields.DateTime("Time Stop",required=True),
'company_id': fields.Many2One("company","Company"),
'nurses': fields.Many2Many('clinic.nurse','Nurses'),
}
_defaults={
"company_id": lambda *a: get_active_company(),
}
Schedule.register()

View File

@ -1,10 +1,275 @@
import time
import random
import datetime
import xlrd
import xmltodict
from netforce.model import Model, fields, get_model
from netforce.utils import get_file_path
from netforce.database import get_connection
class ClinicSetting(Model):
_name="clinic.setting"
_string="Setting"
_fields={
"var_k": fields.Float("K"),
'file': fields.File("File"),
}
def read_excel(self,fpath=None):
data={}
if fpath:
suffix=fpath.split(".")[-1]
if suffix not in ('xls', 'xlsx'):
raise Exception("ERROR : please should file xls or xlsx")
wb=xlrd.open_workbook(fpath)
sheet=wb.sheet_by_name("Sheet1")
# read header values into the list
keys = [sheet.cell(0, col_index).value for col_index in range(sheet.ncols)]
data=[]
for row_index in range(1, sheet.nrows):
#d = {(keys[col_index] or "").lower(): sheet.cell(row_index, col_index).value for col_index in range(sheet.ncols)}
d={}
for col_index in range(sheet.ncols):
ctype=sheet.cell(row_index,col_index).ctype
if ctype==3:
value=sheet.cell(row_index, col_index).value
year, month, day, hour, minute, second = xlrd.xldate_as_tuple(value,wb.datemode)
value=datetime.datetime(year, month, day, hour, minute,second)
value=value.strftime("%Y-%m-%d")
else:
value=sheet.cell(row_index, col_index).value
d.update({(keys[col_index] or "").lower():value})
data.append(d)
return data
def make_visit(self,ids,context={}):
obj=self.browse(ids)[0]
fname=obj.file
fpath=get_file_path(fname)
lines=self.read_excel(fpath)
if not lines:
raise Exception("Wrong File")
medicals=[]
patients=[]
for line in lines:
medical=line.get('medical') or line.get('eponame') or ""
if not medical in medicals:
medicals.append(medical)
patient=line.get('hn','')
name14=line.get('name14') or ""
value=(patient,name14)
if not value in patients:
patients.append(value)
products=[p['name'] for p in get_model("product").search_read([],['name'])]
print('generate product')
print("="*50)
seq=6
for md in medicals:
md=md.replace(" ","")
if not md:
continue
if not md in products:
vals={
'code': "m"+("%s"%seq).zfill(4),
'name':md,
'uom_id': 2,
'type': 'stock',
}
seq+=1
prod_id=get_model("product").create(vals)
print(prod_id)
print("="*50)
print('generate patient')
hns=[pt['hn'] for pt in get_model("clinic.patient").search_read([],['hn'])]
for hn, name in patients:
hn=hn.replace(' ',"")
if not hn:
continue
if not hn in hns:
vals={
'hn': hn,
'name': name,
'type': 'sc',
}
pt_id=get_model("clinic.patient").create(vals)
print('hn ', pt_id)
print("="*50)
patients=get_model("clinic.patient").search_read([],['name','hn'])
visits=get_model("clinic.visit").search_read([],['number','time_start','cycle_id','state'])
doctor_ids=[dt['id'] for dt in get_model("clinic.doctor").search_read([],['name'])]
nurse_ids=[ns['id'] for ns in get_model("clinic.nurse").search_read([],['name'])]
cycle_ids=[cc['id'] for cc in get_model("clinic.cycle").search_read([],['name'])]
department_ids=[dp['id'] for dp in get_model("clinic.department").search_read([],['name'])]
#db=get_connection()
def get_patient(hn):
for pt in patients:
if hn==pt['hn']:
return pt
return None
def get_visit(date,state=None):
for visit in visits:
if date==visit['time_start'][0:10]:
if state:
if visit['state']==state:
return visit
else:
return None
return visit
print("="*50)
print("create simple visit")
timenow=time.strftime("%H:%M:%S")
timenow2="%s:%s:%s" % (int(time.strftime("%H"))+1, time.strftime("%M"), time.strftime("%S"))
time_start=timenow
for line in lines:
hn=line['hn']
date=line['dttran']
visit=get_visit(date)
if not visit:
patient=get_patient(hn)
if patient:
time_start="%s %s"%(date,timenow)
time_stop="%s %s"%(date,timenow2)
vals={
'time_start': time_start,
'time_stop': time_stop,
'patient_id': patient['id'],
'cycle_id': random.choice(cycle_ids),
'nurse_id': random.choice(nurse_ids),
'doctor_id': random.choice(doctor_ids),
'department_id': random.choice(department_ids),
}
visit_id=get_model("clinic.visit").create(vals)
print("create visit %s ", visit_id)
print("="*50)
print("visit with state is draft")
return #XXXX
count=0
for line in lines:
date=line['dttran']
# prevent timeout
if count > 10:
break
#print(date)
visit=get_visit(date=date,state='draft')
print(date, ' ', visit)
if visit:
visit_id=visit['id']
context['called']=True
hd_case_id=get_model("clinic.visit").browse(visit_id).confirm(context=context)
#allow37=line['allow37']
hct=line.get('hct')
medical=line.get('medical') or line.get("eponame") or ""
medical_cost=line.get('medical_cost') or line.get('allow37') or 0.0
inject_service=line.get('inject_service') or line.get("epoadm29") or ""
vals={
'hct': hct and hct or 0,
'lines': [],
}
if medical:
prods=get_model("product").search_browse([['name','=',medical]])
if prods:
prod=prods[0]
vals['lines'].append(('create',{
'type': 'other',
'product_id': prod.id,
'description': prod.name,
'uom_id': prod.uom_id.id,
'qty': 1,
'price': medical_cost,
'amount': medical_cost,
}))
if inject_service:
vals['lines'].append(('create',{
'type': 'other',
'product_id': 55, #XXX
'description': prod.name,
'uom_id': prod.uom_id.id,
'qty': 1,
'price': medical_cost,
'amount': medical_cost,
}))
hd_case=get_model("clinic.hd.case").browse(hd_case_id)
hd_case.write(vals)
count+=1
print("#%s write hd_case %s ok and visit %s" % (count,hd_case_id,hd_case.visit_id.number))
print("="*50)
print("Done")
return
def make_done(self,ids,context={}):
obj=self.browse(ids)[0]
fname=obj.file
fpath=get_file_path(fname)
lines=self.read_excel(fpath)
if not lines:
raise Exception("Wrong File")
def get_line(hn,date):
for line in lines:
if hn==line['hn'] and date==line['dttran']:
return line
count=0
for visit in get_model("clinic.visit").search_browse([['state','=','draft']]):
if count > 200:
break
count+=1
context['called']=True
hd_case_id=visit.confirm(context=context)
hn=visit.patient_id.hn
date_visit=visit.time_start[0:10]
line=get_line(hn,date_visit)
if line:
hct=line.get('hct')
medical=line.get('medical') or line.get('eponame') or ""
medical_cost=line.get('medical_cost') or line.get("allow37") or ""
inject_service=line.get('inject_service') or line.get("EPOadm29") or ""
vals={
'hct': hct and hct or 0,
'lines': [],
}
if medical:
prods=get_model("product").search_browse([['name','=',medical]])
if prods:
prod=prods[0]
vals['lines'].append(('create',{
'type': 'fee',
'product_id': prod.id,
'description': prod.name,
'uom_id': prod.uom_id.id,
'qty': 1,
'price': medical_cost,
'amount': medical_cost,
}))
if inject_service:
prod=get_model("product").browse(55)
vals['lines'].append(('create',{
'type': 'other',
'product_id': 55, #XXX
'description': prod.name,
'uom_id': prod.uom_id.id,
'qty': 1,
'price': medical_cost,
'amount': medical_cost,
}))
hd_case=get_model("clinic.hd.case").browse(hd_case_id)
hd_case.write(vals)
print("#%s make hd_case %s ok "%(count,hd_case.number))
def make_complete(self,ids,context={}):
context['called']=True
count=0
for hd_case in get_model('clinic.hd.case').search_browse(['state','=','draft']):
if count > 100:
break
if not hd_case.dialyzers:
patient=hd_case.patient_id
if not patient.addresses:
patient.simple_address()
hd_case.new_dialyzer(context=context)
hd_case.complete()
print("%s is completed"%hd_case.number)
count+=1
ClinicSetting.register()

View File

@ -93,7 +93,7 @@ class Visit(Model):
def confirm(self,ids,context={}):
obj=self.browse(ids[0])
number=obj.number
if number=="/":
if number=="/" or not number:
number=self._get_number(context)
vals={
'number': number,
@ -130,6 +130,19 @@ class Visit(Model):
'amount': product.sale_price or 0.0,
'uom_id': product.uom_id.id,
}))
if obj.patient_id.type=='sc':
products=get_model("product").search_browse([['code','=','S0001']]) #XXX
for product in products:
vals['lines'].append(('create',{
'type': 'fee',
'product_id': product.id,
'description': product.name or "",
'qty': 1,
'price': product.sale_price or 0.0,
'amount': product.sale_price or 0.0,
'uom_id': product.uom_id.id,
}))
patient_type={
"mg":"Medical Government",
@ -152,6 +165,8 @@ class Visit(Model):
break
hd_case_id=hd_case_obj.create(vals)
if context.get("called"): #XXX call outside
return hd_case_id
return {
'next': {
'name': 'clinic_hd_case',

View File

@ -1,167 +1,3 @@
====
question:
- can filter field in related
find dialyzer automatic after confirm visit
====
- import data
- payment
- NHSO
- SSO
=====
select diaylizer at treatment page -> ok
=====
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
######
- import payment
- visit planing
######
========
Account Receivable -> invoice
find account id
1. partner
2. product line
3. settings
Account Payable -> payment
!!! import data
- remove payment
set account payable
issue:
date of visit is not copy after click from calendar
======
!!! this night
- import payment
setting account
- debit
- credit
patient
- type
-nhso สปสช
- center office of healthcare information
- sc ประักนสังคม
- mg
task
1. find invoice
2. match invoice
- date, number for patient (HN)
3. if have invoice create payment if not review input data again
4. post payment to journal
===========================
- main
- create journal entry from file import
- detail (if have some time need to approve)
- defind state for each step
- visit
- treatment
- dializer
- defind flow of each step
- patient
- new
- load default data
- one2many
- visit
-> split date and time ->ok
-> state
- draft
- confirmed
- should select dialyzer before treament
- buttons -> ok
- confirm
- state : draft -> waiting treatment
- do treatment
- state : waiting treatment ->
- cancel visit -> ok
- print visit -> ok
- treament
- visit planing
- find visit of patient which state is close
- print invoice
- pay for normal person
-> how ???
- make payment
- time start/stop -> ok
- only time
- date treament ->ok
- color (check state)
- if fail -> red
- cancelled
- make next appointment -> ok
- state
- ready to treatment
- paid -> no because not realte to accounting
- many2one for dializer
- list show percent of progress bar
- plaining visit !!!
- select next day to visit
- copy data to visit
- after click complete
- day [monday, tueday, wedsday, thursday, friday]
- time
- dialyzer
- import payment
- import
- create payment with invoice that found
- post
- undo
=======
sequence (support multi company) -> ok
- visit
- hd case
- create invoice after validate ->ok
- create stock picking -> no
- doctor
- nurse
- patient
create new hd case after confirm visit ->ok
question?
- how cycle running?
- treatment
- 1 cycle take how long ?
issue:
hd case should link only 1 dialyzer -> should not copy 2 time
create journal entry
-> ok
sunday
todo:
- need to close all issue:
https://docs.google.com/spreadsheets/d/1GDl9vCswHlD1MMfVwRS504keIz9NYL8VhUZlSPDEJvk/edit?usp=drive_web
payment
- personal
- government
set visible for each staus
======= import data
- flow
1. select sheet
2. select columns
3. load data -> load payment
4. review data -> review payment
5. import data -> post payment
6. done
- issue
load excel is very slow
formalar
tick:
find all -> replace -> multiple x