diff --git a/netforce_clinic/actions/clinic_period.xml b/netforce_clinic/actions/clinic_period.xml
index 67bf988..d4dd157 100644
--- a/netforce_clinic/actions/clinic_period.xml
+++ b/netforce_clinic/actions/clinic_period.xml
@@ -2,5 +2,5 @@
Period
multi_view
clinic.period
- clinic_menu
+ account_menu
diff --git a/netforce_clinic/layouts/clinic_hd_case_expense_form.xml b/netforce_clinic/layouts/clinic_hd_case_expense_form.xml
index e5c45e2..56da269 100644
--- a/netforce_clinic/layouts/clinic_hd_case_expense_form.xml
+++ b/netforce_clinic/layouts/clinic_hd_case_expense_form.xml
@@ -5,21 +5,34 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/netforce_clinic/layouts/clinic_hd_case_expense_list.xml b/netforce_clinic/layouts/clinic_hd_case_expense_list.xml
index 2bce0fb..5f513d3 100644
--- a/netforce_clinic/layouts/clinic_hd_case_expense_list.xml
+++ b/netforce_clinic/layouts/clinic_hd_case_expense_list.xml
@@ -1,8 +1,10 @@
-
-
+
-
+
+
+
+
diff --git a/netforce_clinic/layouts/clinic_hd_case_form.xml b/netforce_clinic/layouts/clinic_hd_case_form.xml
index af833ce..570eb81 100644
--- a/netforce_clinic/layouts/clinic_hd_case_form.xml
+++ b/netforce_clinic/layouts/clinic_hd_case_form.xml
@@ -70,6 +70,7 @@
+
{{#each context.data}}
diff --git a/netforce_clinic/layouts/clinic_hd_case_list.xml b/netforce_clinic/layouts/clinic_hd_case_list.xml
index db8a828..004aba5 100644
--- a/netforce_clinic/layouts/clinic_hd_case_list.xml
+++ b/netforce_clinic/layouts/clinic_hd_case_list.xml
@@ -4,6 +4,7 @@
+
diff --git a/netforce_clinic/layouts/clinic_menu_inherit.xml b/netforce_clinic/layouts/clinic_menu_inherit.xml
index 3c405e1..b63c0b2 100644
--- a/netforce_clinic/layouts/clinic_menu_inherit.xml
+++ b/netforce_clinic/layouts/clinic_menu_inherit.xml
@@ -13,5 +13,8 @@
+ -
+
+
diff --git a/netforce_clinic/layouts/clinic_setting.xml b/netforce_clinic/layouts/clinic_setting.xml
index 89088b1..12cb2b2 100644
--- a/netforce_clinic/layouts/clinic_setting.xml
+++ b/netforce_clinic/layouts/clinic_setting.xml
@@ -70,6 +70,9 @@
+
+
+
diff --git a/netforce_clinic/layouts/import_clinic_payment_form.xml b/netforce_clinic/layouts/import_clinic_payment_form.xml
index 533bc1a..be9f56a 100644
--- a/netforce_clinic/layouts/import_clinic_payment_form.xml
+++ b/netforce_clinic/layouts/import_clinic_payment_form.xml
@@ -10,12 +10,6 @@
-
-
-
-
-
-
diff --git a/netforce_clinic/migrations/__init__.py b/netforce_clinic/migrations/__init__.py
index d2ad46a..e69df29 100644
--- a/netforce_clinic/migrations/__init__.py
+++ b/netforce_clinic/migrations/__init__.py
@@ -1 +1,2 @@
from . import clinic_setting
+from . import import_clinic_hd_case
diff --git a/netforce_clinic/migrations/import_clinic_hd_case.py b/netforce_clinic/migrations/import_clinic_hd_case.py
new file mode 100644
index 0000000..f742aec
--- /dev/null
+++ b/netforce_clinic/migrations/import_clinic_hd_case.py
@@ -0,0 +1,107 @@
+from netforce.model import get_model
+from netforce import migration
+from netforce.utils import get_file_path
+from netforce.access import get_active_user, set_active_user, set_active_company, get_active_company
+from . import utils
+
+class Migration(migration.Migration):
+ _name="import.clinic.hd.case"
+ _version="2.80"
+
+ def import_visit(self,lines):
+ visits={}
+ cycles=[(c['id'],'%s:00'%c['time_start'],'%s:00'%c['time_stop']) for c in get_model("clinic.cycle").search_read([[]],['time_start','time_stop'])]
+ for line in lines:
+ hcode=line.get('hcode18')
+ if not hcode:
+ hcode='0'
+ hcode=int(hcode)
+ hcode=str(hcode)
+ hcode_impt='23869'
+ if hcode_impt==hcode:
+ name=line.get("name14")
+ patient_ids=get_model("clinic.patient").search([['name','=',name]])
+ if patient_ids:
+ patient_id=patient_ids[0]
+ patient=get_model("clinic.patient").browse(patient_id)
+ doctor=patient.doctor_id
+ department=patient.department_id
+ vals={
+ 'patient_id': patient.id,
+ 'doctor_id': doctor.id,
+ 'department_id': department.id,
+ }
+ # find cycle
+ dttran=line.get("dttran")
+ date=dttran[0:10]
+ time=dttran[11:]
+ if not time:
+ continue
+ cycle_id=None
+ for cycle in cycles:
+ time_start=cycle[1]
+ time_stop=cycle[2]
+ if time >= time_start:
+ cycle_id=cycle[0]
+ vals['cycle_id']=cycle_id
+ vals['time_start']='%s %s'%(date,time_start)
+ vals['time_stop']='%s %s'%(date,time_stop)
+ if not cycle_id:
+ raise Exception("not found cycle on this time %s %s %s"%(dttran, time_start,time_stop))
+ visit_ids=get_model("clinic.visit").search([['visit_date','=',date],['patient_id','=',patient_id]])
+ visit_id=None
+ if not visit_ids:
+ vals['visit_date']=date
+ visit_id=get_model('clinic.visit').create(vals)
+ #print('create visit ', visit_id, date)
+ else:
+ visit_id=visit_ids[0]
+ #print('already ', date, ' ', name)
+ if visit_id:
+ visits.update({
+ visit_id: {
+ 'hct': line.get('hct'),
+ }
+ })
+ else:
+ print("found ", name)
+ return visits
+
+ def confirm_visit(self,visits):
+ hd_case_ids=[]
+ visit_ids=visits.keys()
+ for visit in get_model('clinic.visit').browse(visit_ids):
+ if visit!='confirmed':
+ visit.confirm()
+ hd_case=visit.hd_cases[0]
+ hd_case.write({
+ 'hct': visits[visit.id]['hct'] or 0,
+ })
+ hd_case_ids.append(hd_case.id)
+ return hd_case_ids
+
+
+ def hdc_done(self,hd_case_ids):
+ done_ids=[]
+ for hd_case in get_model("clinic.hd.case").browse(hd_case_ids):
+ if hd_case.state=='waiting_treatment':
+ hd_case.complete()
+ done_ids.append(hd_case.id)
+ return done_ids
+
+ def migrate(self):
+ fname='pks.xls'
+ fpath=get_file_path(fname)
+ lines=utils.read_excel(fpath,show_datetime=True)
+ company_id=get_active_company()
+ set_active_company(1)
+ visits=self.import_visit(lines)
+ print("visit ", len(visits))
+ hd_case_ids=self.confirm_visit(visits)
+ print('hd case ', len(hd_case_ids))
+ hd_case_ids=self.hdc_done(hd_case_ids)
+ set_active_company(company_id)
+ print('Done ', len(hd_case_ids))
+ return True
+
+Migration.register()
diff --git a/netforce_clinic/migrations/utils.py b/netforce_clinic/migrations/utils.py
new file mode 100644
index 0000000..6280c1a
--- /dev/null
+++ b/netforce_clinic/migrations/utils.py
@@ -0,0 +1,130 @@
+from datetime import datetime
+import xlrd
+import xmltodict
+
+
+DAYS={
+ 'th_TH': ['จันทร์', 'อังคาร', 'พุธ', 'พฤหัสบดี', 'ศุกร์', 'เสาร์', 'อาทิตย์'],
+ 'th_TH2': ['จันทร์', 'อังคาร', 'พุธ', 'พฤหัสบดี', 'ศุกร์', 'เสาร์', 'อาทิตย์'],
+ 'en_US': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
+}
+
+MONTHS={
+ 'th_TH': [None, 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'],
+ 'th_TH2': [None, 'ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.'],
+ 'en_US': [None, 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
+}
+
+PATIENT_TYPE={
+ "sc":"ปกส.",
+ "uc":"UC.",
+ "others": "จ่ายเอง",
+}
+
+STAFF_TYPE={
+ 'doctor': 'แพทย์',
+ 'nurse': 'พยาบาล',
+ 'staff': 'ทั่วไป',
+}
+
+TOPICS={
+ 'topic1': {'name': 'จำนวนครั้งการทำ Hemodialysis', 'unit': 'ครั้ง'},
+ 'topic2': {'name': 'จำนวนผู้ป่วยยกมาจากเดือน', 'unit': 'คน'},
+ 'topic3': {'name': 'จำนวนผู้ป่วยรับใหม่เดือน', 'unit': 'คน'},
+ 'topic4': {'name': 'จำนวนผู้ป่วยจำหน่ายเดือน', 'unit': 'คน'},
+ 'topic5': {'name': 'จำนวนผู้ป่วยยกไปเดือน', 'unit': 'คน'},
+ 'topic6': {'name': 'จำนวนผู้ป่วยเบิก ปกส.', 'unit': 'คน'},
+ 'topic7': {'name': 'จำนวนผู้ป่วยเบิก สปกส.', 'unit': 'คน'},
+ 'topic8': {'name': 'จำนวนผู้ป่วยจ่ายเอง', 'unit': 'คน'},
+}
+
+def read_excel(fpath=None,show_datetime=False):
+ 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")
+ keys = [sheet.cell(0, col_index).value for col_index in range(sheet.ncols)]
+ data=[]
+ for row_index in range(1, sheet.nrows):
+ 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(year, month, day, hour, minute,second)
+ if show_datetime:
+ value=value.strftime("%Y-%m-%d %H:%M:%S")
+ else:
+ 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 read_xml(fpath=None,node="HDBills"):
+ root_name="STMSTM"
+ child_name=node
+ data={}
+ if not child_name:
+ return data
+ if fpath:
+ suffix=fpath.split(".")[-1]
+ if suffix not in ('xml'):
+ raise Exception("ERROR : please should file xml")
+ data=xmltodict.parse(open(fpath,"r").read())
+ root=data.get(root_name)
+ lines=[]
+ if root:
+ child=root.get(child_name)
+ if not child:
+ return {}
+ for k, v in child.items():
+ collections=v
+ for collection in collections:
+ if isinstance(collection,dict):
+ line={}
+ for i, j in collection.items():
+ key=(i or "").lower()
+ line[key]=j
+ lines.append(line)
+ return lines
+
+def date2thai(date, format='%(BY)s-%(m)s-%(d)s', lang='th_TH'):
+ '''
+ >>> date2thai('2011-12-31', lang='th_TH')
+ '2554-12-31'
+ >>> date2thai('2011-12-31', format='%(Td)s %(d)s %(Tm)s, %(By)s', lang='en_US')
+ 'Saturday 31 December, 54'
+ >>> print date2thai('2011-12-31', format='%(Td)s %(d)s %(Tm)s, %(By)s', lang='th_TH')
+ เสาร์ 31 ธันวาคม, 54
+ >>> date2thai('2000-06-08', lang='th_TH')
+ '2543-06-08'
+ >>> date2thai('2000-06-08', format='%(Td)s %(d)s %(Tm)s, %(By)s', lang='en_US')
+ 'Thursday 08 June, 43'
+ >>> print date2thai('2000-06-08', format='%(Td)s %(d)s %(Tm)s, %(By)s', lang='th_TH')
+ พฤหัสบดี 08 มิถุนายน, 43
+ '''
+
+ if not date or not date.count('-') == 2:
+ return ''
+
+ year, month, day = date.split('-')
+
+ #dow = DateTime.Date(int(year), int(month), int(day)).day_of_week
+ dow = datetime(int(year),int(month),int(day)).weekday()
+ return format % { 'BY': int(year) + 543
+ , 'By': int(year[2:]) + 43
+ , 'Tm': MONTHS[lang][int(month)]
+ , 'Td': DAYS[lang][dow]
+ , 'm': month
+ , 'd': int(day) # XXX remove zero
+ }
+
+
+
+
diff --git a/netforce_clinic/models/account_invoice.py b/netforce_clinic/models/account_invoice.py
index ad53ea9..e1917ee 100644
--- a/netforce_clinic/models/account_invoice.py
+++ b/netforce_clinic/models/account_invoice.py
@@ -1,24 +1,9 @@
-from netforce.model import Model, fields, get_model
+from netforce.model import Model, fields
-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,
- },
- }
+class AccountInvoice(Model):
+ _inherit="account.invoice"
+ _fields={
+ 'clinic_expense_id': fields.Many2One("clinic.hd.case.expense","Expense"),
+ }
-AccountPayment.register()
+AccountInvoice.register()
diff --git a/netforce_clinic/models/dialyzer.py b/netforce_clinic/models/dialyzer.py
index 07580a5..4a5e198 100644
--- a/netforce_clinic/models/dialyzer.py
+++ b/netforce_clinic/models/dialyzer.py
@@ -98,8 +98,14 @@ class Dialyzer(Model):
break
if not ship_address_id:
raise Exception("contact %s dont'have address with type shipping"%partner.name)
+ st=get_model("clinic.setting").browse(1)
+ journal=st.stock_journal_id
+ if not journal:
+ raise Exception("Not found stock journal")
+
pick_vals={
"type": "out",
+ 'journal_id': journal.id,
"ref": obj.number,
"related_id": "clinic.dialyzer,%s"%obj.id,
"partner_id": obj.patient_id.partner_id.id,
diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py
index 03c0987..96f4543 100644
--- a/netforce_clinic/models/hd_case.py
+++ b/netforce_clinic/models/hd_case.py
@@ -36,24 +36,21 @@ class HDCase(Model):
due_amt=0
fee_amt=0
mdc_amt=0
+ srv_amt=0
for line in obj.lines:
if line.type=='fee':
fee_amt+=line.amount or 0.0
elif line.type=='medicine':
mdc_amt+=line.amount or 0.0
+ elif line.type=='service':
+ srv_amt+=line.amount or 0.0
total+=line.amount or 0.0
-
- # TODO need to check with invoice policy
- # government pay for :
- # - fee -> create invoice with fee type on state waiting to payment
- # - fee & medicine -> create 2 invoice for fee and medicine type
if obj.invoice_policy=='fee':
due_amt=total-fee_amt
elif obj.invoice_policy=='fee_mdc':
due_amt=total-(fee_amt+mdc_amt)
else:
due_amt=total
-
for line in obj.payment_lines:
due_amt-=line.amount or 0.0
vals[obj.id]={
@@ -61,6 +58,7 @@ class HDCase(Model):
"amount": due_amt,
'fee_amount': fee_amt,
'mdc_amount': mdc_amt,
+ 'srv_amount': srv_amt,
}
return vals
@@ -85,7 +83,7 @@ class HDCase(Model):
"wt_kg": fields.Float("Wt.kg."),
"bp": fields.Integer("BP"),
"mm_hg": fields.Integer("mmHG"),
- "hct": fields.Integer("Hct%(<40)",required=True),
+ "hct": fields.Integer("Hct",required=True),
"hct_msg" : fields.Char(""),
"state": fields.Selection([("draft","Draft"),('waiting_treatment','Waiting Treatment'),("in_progress","In Progress"),("completed","Finish Treatment"),('paid','Paid'),("waiting_payment","Waiting Payment"),("discountinued","Discountinued"),("cancelled","Cancelled")],"Status",required=True),
"staffs": fields.One2Many("clinic.hd.case.staff","hd_case_id","Staffs"),
@@ -102,6 +100,7 @@ class HDCase(Model):
"total": fields.Float("Total",function="_get_total",readonly=True,function_multi=True),
"fee_amount": fields.Float("Fee",function="_get_total",readonly=True,function_multi=True),
"mdc_amount": fields.Float("Medicine",function="_get_total",readonly=True,function_multi=True),
+ "srv_amount": fields.Float("Service",function="_get_total",readonly=True,function_multi=True),
"amount": fields.Float("Due Amount",function="_get_total",readonly=True,function_multi=True),
'fee_partner_id': fields.Many2One("partner","Contact Fee"),
'fee_paid': fields.Boolean("Fee Paid"),
@@ -229,7 +228,7 @@ class HDCase(Model):
qty=line['qty'] or 0
price=line['price'] or 0.0
line['amount']=qty*price
- self.update_amount(data)
+ data=self.update_amount(context)
return data
def onchange_product(self,context={}):
@@ -246,7 +245,7 @@ class HDCase(Model):
line['qty']=qty
line['price']=price
line['amount']=amt
- self.update_amount(data)
+ data=self.update_amount(context)
return data
def onchange_pay(self,context={}):
@@ -262,11 +261,17 @@ class HDCase(Model):
return data
def onchange_policy(self,context={}):
+ data=context['data']
+ data=self.update_amount(context)
+ return data
+
+ def update_amount(self,context={}):
data=context['data']
inv_pol=data['invoice_policy']
total=0.0
fee=0.0
mdc=0.0
+ srv=0.0
due_amt=0.0
for line in data['lines']:
amt=line['amount'] or 0.0
@@ -276,6 +281,8 @@ class HDCase(Model):
fee+=amt
elif ltype=='medicine':
mdc+=amt
+ elif ltype=='service':
+ srv+=amt
elif ltype=='others':
pass
if inv_pol=='fee':
@@ -289,25 +296,8 @@ class HDCase(Model):
data['total']=total
data['fee_amount']=fee
data['mdc_amount']=mdc
+ data['srv_amount']=srv
data['amount']=due_amt
- return data
-
- def update_amount(self,data):
- total_amt=0.0
- fee_amt=0.0
- for line in data['lines']:
- price=line.get('price') or 0
- qty=line.get('qty') or 0
- amt=qty*price
- if line['type']=='fee':
- fee_amt+=amt
- else:
- total_amt+=amt
- data['total']=total_amt+fee_amt
- data['fee_amount']=fee_amt
- for line in data['payment_lines']:
- total_amt-=line['amount'] or 0.0
- data['amount']=total_amt
return data
def make_payment(self,ids,context={}):
@@ -377,8 +367,10 @@ class HDCase(Model):
obj.write({" state":"cancelled"})
def make_invoices(self,ids,context={}):
- setting=get_model("settings").browse(1)
+ setting=get_model("settings").browse(1,context)
currency_id=setting.currency_id.id
+ if not currency_id:
+ raise Exception("Currency not found in account settings")
account_receivable_id=setting.account_receivable_id.id
company_id=get_active_company()
uom=get_model("uom").search_browse([['name','ilike','%Unit%']])
@@ -388,7 +380,6 @@ class HDCase(Model):
if obj.invoices:
for inv in obj.invoices:
inv.void()
-
due_date=obj.date[0:10] # XXX
# cash, credit
make_invoice=context.get('make_invoice',True)
@@ -466,15 +457,14 @@ class HDCase(Model):
fee_lines+=mdc_lines
mdc_lines=[]
+ contact=obj.patient_id.type_id.contact_id
+ account_id=contact.account_receivable_id.id or account_receivable_id
+ if not account_id:
+ raise Exception("Not found account receive")
+
if mdc_lines:
inv_vals=vals.copy()
inv_vals["partner_id"]=obj.fee_partner_id.id
- account_id=account_receivable_id
- patient_type=obj.patient_id.type
- if patient_type=='sc':
- account_id=setting.ar_sc_id.id
- elif patient_type=='uc':
- account_id=setting.ar_uc_id.id
for mdc_line in mdc_lines:
mdc_line['account_id']=account_id
inv_vals['lines'].append(('create',mdc_line))
@@ -483,13 +473,6 @@ class HDCase(Model):
if fee_lines and not obj.fee_paid:
inv_vals=vals.copy()
inv_vals["partner_id"]=obj.fee_partner_id.id
- account_id=account_receivable_id
- patient_type=obj.patient_id.type
- if patient_type=='sc':
- account_id=setting.ar_sc_id.id
- elif patient_type=='uc':
- account_id=setting.ar_uc_id.id
-
for fee_line in fee_lines:
fee_line['account_id']=account_id
inv_vals['lines'].append(('create',fee_line))
@@ -630,37 +613,42 @@ class HDCase(Model):
# clear old expense
for exp in obj.expenes:
exp.delete()
-
exp_lines=[]
- for inv in obj.invoices:
- exp_lines.append(('create',{
- 'date': obj.date,
- 'patient_id': obj.patient_id.id,
- 'invoice_id': inv.id,
- 'hd_case_id': obj.id,
- 'amount': inv.amount_due,
- 'state': 'waiting_matching',
- }))
- for pm in obj.payments:
- exp_lines.append(('create',{
- 'date': obj.date,
- 'patient_id': obj.patient_id.id,
- 'payment_id': pm.id,
- 'hd_case_id': obj.id,
- 'amount': pm.amount_total,
- 'state': 'waiting_matching',
- }))
+ fee=0.0
+ mdc=0.0
+ srv=0.0
+ for line in obj.lines:
+ amt=line.amount or 0.0
+ ltype=line.type
+ if ltype=='fee':
+ fee+=amt
+ elif ltype=='medicine':
+ mdc+=amt
+ elif ltype=='service':
+ srv+=amt
+ elif ltype=='others':
+ pass
+ exp_lines.append(('create',{
+ 'date': obj.date,
+ 'patient_id': obj.patient_id.id,
+ 'hd_case_id': obj.id,
+ 'fee_amt': fee,
+ 'mdc_amt': mdc,
+ 'srv_amt': srv,
+ 'state': 'waiting_matching',
+ }))
+
obj.write({
'expenes': exp_lines,
})
def complete(self,ids,context={}):
obj=self.browse(ids)[0]
- obj.make_invoices()
- obj.post_invoices()
+ obj.make_invoices(context=context)
+ obj.post_invoices(context=context)
obj.update_usetime()
obj.create_cycle_item()
- obj.do_expense()
+ obj.do_expense(context=context)
vals={
"state":"waiting_payment", # for government
}
diff --git a/netforce_clinic/models/hd_case_expense.py b/netforce_clinic/models/hd_case_expense.py
index e457a1d..2e68529 100644
--- a/netforce_clinic/models/hd_case_expense.py
+++ b/netforce_clinic/models/hd_case_expense.py
@@ -1,6 +1,6 @@
import time
-from netforce.model import Model, fields
+from netforce.model import Model, fields, get_model
from netforce.access import get_active_company
class HDCaseExpense(Model):
@@ -24,9 +24,14 @@ class HDCaseExpense(Model):
'date': fields.Date("Date",required=True,search=True),
'patient_id': fields.Many2One("clinic.patient","Patient",required=True,search=True),
'hd_case_id': fields.Many2One("clinic.hd.case","HD Case",required=True,search=True),
- 'invoice_id': fields.Many2One("account.invoice","Invoice",search=True),
'payment_id': fields.Many2One("account.payment","Payment",search=True),
- 'amount': fields.Float("Amount"),
+ "invoices": fields.One2Many("account.invoice","clinic_expense_id","Invoices"),
+ 'fee_amt': fields.Float("Fee"),
+ 'mdc_amt': fields.Float("Medicine"), # EPOadm
+ 'srv_amt': fields.Float("Service"), # Allow
+ 'fee': fields.Boolean("Fee"),
+ 'medicine': fields.Boolean("Medicine"),
+ 'service': fields.Boolean("Service"),
'state': fields.Selection([['draft','Draft'],['waiting_matching','Waiting Matching'],['match','Match'],['unmatch','Unmatch'],['approved','Approved']],'State'),
'note': fields.Text("Note"),
'pt_conflict': fields.Boolean("Patient Conclict",function="_get_patient_conflict"),
@@ -41,6 +46,16 @@ class HDCaseExpense(Model):
_order="date desc"
+ def create(self,vals,**kw):
+ new_id=super().create(vals,**kw)
+ hd_case_id=vals['hd_case_id']
+ hd_case=get_model("clinic.hd.case").browse(hd_case_id)
+ for inv in hd_case.invoices:
+ inv.write({
+ 'clinic_expense_id': new_id,
+ })
+ return new_id
+
def approve(self,ids,context={}):
obj=self.browse(ids)[0]
obj.write({
@@ -56,6 +71,7 @@ class HDCaseExpense(Model):
def delete(self,ids,context={}):
for obj in self.browse(ids):
if obj.state!='draft':
+ continue #XXX migration
raise Exception("Status is not draft!")
super().delete(ids,context)
diff --git a/netforce_clinic/models/hd_case_line.py b/netforce_clinic/models/hd_case_line.py
index 79c6f96..7e9fbd4 100644
--- a/netforce_clinic/models/hd_case_line.py
+++ b/netforce_clinic/models/hd_case_line.py
@@ -10,7 +10,7 @@ class Hdcaseline(Model):
"uom_id": fields.Many2One("uom","UOM",required=True,search=True),
"price":fields.Float("Price"),
"amount":fields.Float("Amount"),
- "type": fields.Selection([("fee","Fee"),('medicine','Medicine'),("others","Others")],"Type",required=True),
+ "type": fields.Selection([("fee","Fee"),('medicine','Medicine'),('service','Service'),("others","Others")],"Type",required=True),
}
_defaults={
diff --git a/netforce_clinic/models/import_payment.py b/netforce_clinic/models/import_payment.py
index 1fa68e7..a2c9274 100644
--- a/netforce_clinic/models/import_payment.py
+++ b/netforce_clinic/models/import_payment.py
@@ -51,8 +51,6 @@ class ImportPayment(Model):
'payment_id': fields.Many2One("account.payment","Payment"),
'company_id': fields.Many2One("company","Company"),
'partner_id': fields.Many2One("partner","Fee Contact",function="_get_partner"),
- 'is_uc': fields.Integer("Is UC"),
- 'node': fields.Char("Node"),
}
def get_hcode_id(self,context={}):
@@ -161,6 +159,16 @@ class ImportPayment(Model):
return ''.join(h for h in hn if h.isdigit())
def import_payment_pks(self,ids,context={}):
+ '''
+ step to import
+ 1. select period : date from/to
+ 2. select hospital code
+ 2. select patient type
+ 3. select file
+ - pks=> excel
+ - uc => xml
+
+ '''
obj=self.browse(ids)[0]
fname=obj.file
fpath=get_file_path(fname)
@@ -168,10 +176,12 @@ class ImportPayment(Model):
if not lines:
raise Exception("No data to import")
msg=""
-
+ dom=[]
+ dom.append(['date','>=',obj.date_from])
+ dom.append(['date','<=',obj.date_to])
+ expenses=get_model("clinic.hd.expense").search_browse(dom)
for line in lines:
pass
-
obj.write({
'total_row': len(lines),
'msg': msg,
@@ -186,25 +196,47 @@ class ImportPayment(Model):
'flash': 'Import successfully'
}
- def import_payment_uc(self,ids,context={}):
- obj=self.browse(ids)[0]
- fname=obj.file
- fpath=get_file_path(fname)
- lines=utils.read_xml(fpath,node=obj.node)
- if not lines:
- raise Exception("No Data to import")
+ def get_invoice_epobills(self,lines):
+ for line in lines:
+ hn=line.get('hn',"")
+ hn_num=self.get_hn_num(hn)
+ print(hn_num)
+ return lines
+ def get_invoice_hdbills(self,lines):
for line in lines:
date,time=line.get("dttran").split("T")
invno=line.get("invno")
hdrate=float(line.get("hdrate","0"))
hn=line.get('hn',"")
hn_num=self.get_hn_num(hn)
+ print(hn_num)
+ return lines
- obj.write({
- 'match_qty': 0,
- 'unmatch_qty': 0,
- })
+ def import_payment_uc(self,ids,context={}):
+ obj=self.browse(ids)[0]
+ fname=obj.file
+ if "_" not in fname and len(fname.split("_")) <3:
+ raise Exception("File name should be HCODE_[EURSTM or UOCDSTM]_YYYYMMDD")
+ fpath=get_file_path(fname)
+ hcode,itype,date=fname.split("_")
+ node=''
+ if itype=='EURSTM':
+ node='EPOBills'
+ elif itype=='UOCDSTM':
+ node='HDBills'
+ else:
+ node='HDBills'
+
+ lines=utils.read_xml(fpath,node=node)
+ if itype=='EURSTM':
+ lines=self.get_invoice_epobills(lines)
+ elif itype=='UOCDSTM':
+ lines=self.get_invoice_hdbills(lines)
+ else:
+ lines=[]
+ if not lines:
+ raise Exception("No Data to import")
return {
'next': {
'name': 'import_clinic_payment',
diff --git a/netforce_clinic/models/setting.py b/netforce_clinic/models/setting.py
index 5f45df4..9bfc087 100644
--- a/netforce_clinic/models/setting.py
+++ b/netforce_clinic/models/setting.py
@@ -20,6 +20,7 @@ class ClinicSetting(Model):
'real_time': fields.Boolean("Real Time"), # HD Case
'patient_type_id': fields.Many2One("clinic.patient.type","Default Type"), # Import payment
'find_dlz': fields.Boolean("Find Dialyzer After Confirm Visit"), # Visit
+ 'stock_journal_id': fields.Many2One("stock.journal","Default Journal"),
}
_defaults={
diff --git a/netforce_clinic/models/visit.py b/netforce_clinic/models/visit.py
index b25e6c2..99b07d8 100644
--- a/netforce_clinic/models/visit.py
+++ b/netforce_clinic/models/visit.py
@@ -186,7 +186,6 @@ class Visit(Model):
if context.get("called"): #XXX call outside
return hd_case_id
- print("checking cycle item")
date=vals['time_start'][0:10]
cycle=obj.cycle_id
dom=[]
diff --git a/netforce_clinic/todo.txt b/netforce_clinic/todo.txt
index c1293cf..70a2932 100644
--- a/netforce_clinic/todo.txt
+++ b/netforce_clinic/todo.txt
@@ -1,129 +1,9 @@
-============
- urgent still missing
- - report Matching Payment
- - special case -> how
- - labor cost in period
- - computation of labor cost in period
-
-============
--- tonight -
-- matching
-- report expense
--- cost nurse / doctor
--XXXX
-- reqeust fee again after request
-
-- missing
- - import schedule -> wait K. Ekk
- - missing hd case in staff (nurse, doctor)
- - special nurse
- - report for show max cycle and got cycle
- - create journal entry -> ok
- - optimize
-===============
-
-hd case
- start / stop -> option udpate time
======
-improval
- - type of patient
-=====
- import payment from government
- - read file
- xml
- - uc
- excel
- - social security
- - step
- 1. create visit -> OK
- 2. confirm visit -> hd case -> still run script
- - after finish need to update invoice date related to hd case
- 3. match payment
- - show wrong match
- - show how to solve
-
+ import payment
+ step:
+ 1. check matching
+ 2. prepare file to import
+ 3. import
+ - find import
+ -
======
-bug:
- - มีปัญหาการสร้าง address ของ contact จากผู้ป่วยโดยอัตโนมัติ เพราะมันไม่ได้ถูกเก็บไว้ที่ form
- - export excel in matrix mode
- -
-=====
-first:
- match payment
-second:
- record with period
- - setting
- - set current period
- - master data
- - period
- - lines
- date_from , date_to
- - fee nurse sum report
- - can select by period
- - cycle daily
- - confirm
- - submit according period
-
-======
-DROP TABLE clinic_cycle_dialy_line;
-drop table clinic_cycle_item_line;
-drop table clinic_cycle_item_nurse;
-drop table clinic_gen_visit cascade;
-drop table clinic_gen_visit_line;
-drop table clinic_hd_case cascade;
-drop table clinic_hd_case_dialyzer;
-drop table clinic_hd_case_line;
-drop table clinic_patient cascade;
-drop table address cascade;
-TRUNCATE clinic_dialyzer cascade;
-TRUNCATE clinic_patient_cause cascade;
-TRUNCATE clinic_patient_comorbidity cascade;
-TRUNCATE clinic_patient_morbidity cascade;
-TRUNCATE clinic_schedule_line cascade;
-TRUNCATE clinic_schedule_load_nurse_line cascade;
-TRUNCATE clinic_setting_level cascade;
-
-=======
- - change personal -> stuff -> link to employee
- - add level to the list of the stuff
-
- - design
- - auto complete hd after time out
- - create payment for each type of patient
- - invoice
- - reports
- - visitl dialy
- - summary total for each cycle
- - define rule to get
- - fee product
- - invoice
- - add picture of patient to visit/hd case dialy
- - cycle dialy
- - lines
- - order by cycle
- - order doctor, nurse, personal
- - report salary
- -
-========
-customize ui
- calendar -
- - show search
- - change color from cycle
- - filter state from attr
- - can print sechedule all month
- - set attribute color for field
-
-========
-
-cycle dialy
- -list of cycle items
- - report all compute all cost
-
-- sale medical
-visit dialy
- list of visits
-schedule planing for nurses / personal
-
-import payment
- - error report
- - manual matching