diff --git a/netforce_clinic/actions/clinic_hd_case.xml b/netforce_clinic/actions/clinic_hd_case.xml index 8e4d8a3..117d905 100644 --- a/netforce_clinic/actions/clinic_hd_case.xml +++ b/netforce_clinic/actions/clinic_hd_case.xml @@ -1,8 +1,8 @@ - HD Cases + HD Case Treatments multi_view clinic.hd.case - [["All",[]],["Draft",[["state","=","draft"]]],["Confirmed",[["state","=","confirmed"]]],["Approved",[["state","=","approved"]]],["Validated",[["state","=","validated"]]],["Paid",[["state","=","paid"]]],["Cancelled",[["state","=","cancelled"]]]] + [["All",[]],["Draft",[["state","=","draft"]]],["Confirmed",[["state","=","confirmed"]]],["Approved",[["state","=","approved"]]],["Paid",[["state","=","paid"]]],["Cancelled",[["state","=","cancelled"]]]] list,form clinic_menu diff --git a/netforce_clinic/layouts/clinic_dialyzer_form.xml b/netforce_clinic/layouts/clinic_dialyzer_form.xml index 8b94c21..feee612 100644 --- a/netforce_clinic/layouts/clinic_dialyzer_form.xml +++ b/netforce_clinic/layouts/clinic_dialyzer_form.xml @@ -23,8 +23,8 @@ - + + diff --git a/netforce_clinic/layouts/clinic_visit_form.xml b/netforce_clinic/layouts/clinic_visit_form.xml index 9f3d267..dd03a20 100644 --- a/netforce_clinic/layouts/clinic_visit_form.xml +++ b/netforce_clinic/layouts/clinic_visit_form.xml @@ -3,7 +3,7 @@ @@ -12,6 +12,7 @@ + diff --git a/netforce_clinic/models/__init__.py b/netforce_clinic/models/__init__.py index d10c368..07648b8 100644 --- a/netforce_clinic/models/__init__.py +++ b/netforce_clinic/models/__init__.py @@ -8,8 +8,8 @@ from . import doctor from . import nurse from . import visit from . import hd_case +from . import hd_case_dialyzer from . import hd_case_line -from . import hd_case_line_detail from . import dialyzer from . import department from . import education diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py index 64ec5f4..630e861 100644 --- a/netforce_clinic/models/hd_case.py +++ b/netforce_clinic/models/hd_case.py @@ -1,6 +1,8 @@ +import time +from datetime import datetime + from netforce.model import Model, fields, get_model from netforce.utils import get_data_path -import time from netforce.access import get_active_user,set_active_user from netforce.access import get_active_company @@ -10,6 +12,16 @@ class HDcase(Model): _audit_log=True _name_field="number" _multi_company=True + + def get_hrs(self,ids,context={}): + res={} + fmt="%Y-%m-%d %H:%M:%S" + for obj in self.browse(ids): + diff=datetime.strptime(obj.date_stop,fmt)-datetime.strptime(obj.date_start,fmt) + total_time=round(diff.seconds/3600,2) + res[obj.id]=total_time + return res + _fields={ "number": fields.Char("Number",required=True,search=True), "patient_id": fields.Many2One("clinic.patient","Patient",required=True,search=True), @@ -25,12 +37,12 @@ class HDcase(Model): "bp_stop": fields.Integer("BP mmHG stop"), "per_bp_stop": fields.Integer("/Per stop"), "hct": fields.Integer("HCT %"), - "state": fields.Selection([("draft","Draft"),("approved","Approved"),("confirmed","Confirmed"),("validated","Validated"),("cancelled","Cancelled"),("paid","Paid")],"Status",required=True), - "lines": fields.One2Many("clinic.hd.case.line","hd_case_id","Details"), - "lines_detail": fields.One2Many("clinic.hd.case.line.detail","hd_case_id","Detail"), + "state": fields.Selection([("draft","Draft"),("confirmed","Confirmed"),("approved","Approved"),("cancelled","Cancelled"),("paid","Paid")],"Status",required=True), + "dialyzers": fields.One2Many("clinic.hd.case.dialyzer","hd_case_id","Dializers"), + "lines": fields.One2Many("clinic.hd.case.line","hd_case_id","Lines"), "comments": fields.One2Many("message","related_id","Comments"), "company_id": fields.Many2One("company","Company"), - "fee": fields.Float("HD Fee",required=True), + "fee": fields.Float("HD Fee"), "amount": fields.Float("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), @@ -38,7 +50,9 @@ 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"), - 'include_fee': fields.Boolean("Include HD Fee"), + 'total_time': fields.Integer("Total Time(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","Fee Contact"), } def _get_number(self,context={}): @@ -110,13 +124,23 @@ class HDcase(Model): obj=self.browse(ids)[0] obj.write({"state":"cancelled"}) - def confirmed(self,ids,context={}): + def make_invoice(self,ids,context={}): + for obj in self.browse(ids): + if obj.fee: + pass + + def confirm(self,ids,context={}): obj=self.browse(ids)[0] obj.write({"state":"confirmed"}) def paid(self,ids,context={}): obj=self.browse(ids)[0] obj.write({"state":"paid"}) + + def approve(self,ids,context={}): + obj=self.browse(ids)[0] + obj.make_invoice() + obj.write({"state":"approved"}) def approved(self,ids,context={}): for obj in self.browse(ids): @@ -223,7 +247,7 @@ class HDcase(Model): total=0 amt=0 fee=obj.fee or 0 - for line in obj.lines_detail: + for line in obj.lines: total+=line.total or 0 fee=0 # XXX amt=total+fee @@ -244,7 +268,7 @@ class HDcase(Model): def onchange_product(self,context={}): data=context['data'] all_total=0.0 - for line in data['lines_detail']: + for line in data['lines']: qty=line['qty'] or 0 price=line['price'] or 0.0 total=qty*price @@ -255,5 +279,20 @@ class HDcase(Model): data['total']=all_total data['amount']=all_total+fee_amt return data + + def delete(self,ids,context={}): + for obj in self.browse(ids): + if obj.state != 'draft': + raise Exception("Can not delete HD Case %s because state is not draft"%obj.number) + super().delete(ids) + + def onchange_fee_type(self,context={}): + data=context['data'] + fee_type=data.get("fee_type","") + if fee_type in ("mg","sc","nhso"): + data['fee']=1500 + else: + data['fee']=0.0 + return data HDcase.register() diff --git a/netforce_clinic/models/hd_case_dialyzer.py b/netforce_clinic/models/hd_case_dialyzer.py new file mode 100644 index 0000000..acf1372 --- /dev/null +++ b/netforce_clinic/models/hd_case_dialyzer.py @@ -0,0 +1,19 @@ +from netforce.model import Model, fields + +class HdcaseDialyzer(Model): + _name="clinic.hd.case.dialyzer" + _fields={ + "hd_case_id": fields.Many2One("clinic.hd.case","HdCase",required=True,on_delete="cascade"), + "dialyzer_id": fields.Many2One("clinic.dialyzer","Dialzer",search=True), + "description": fields.Char("Description",search=True), + "use_time":fields.Integer("Use time"), + "max_use_time":fields.Integer("Max use time"), + "member_type": fields.Selection([("unsub","Unsub cellul"),("sub","Sub cellul"),("synthetic","Synthetic")],"Member Type",required=True), + "dialyzer_type": fields.Selection([("low","low flux"),("high","high flux"),("dbl","dbl hifulx")],"Member Type",required=True), + "bid_flow_rate": fields.Integer("Bid Flow Rate (ml/min)",required=True,search=True), + "ultrafittration": fields.Float("Ultrafittration Kg.",required=True,search=True), + "state":fields.Selection([("draft","New"),("active","Active"),("drop","Drop")],"Status"), + } + +HdcaseDialyzer.register() + diff --git a/netforce_clinic/models/hd_case_line.py b/netforce_clinic/models/hd_case_line.py index d731752..7441492 100644 --- a/netforce_clinic/models/hd_case_line.py +++ b/netforce_clinic/models/hd_case_line.py @@ -1,22 +1,16 @@ -from netforce.model import Model, fields, get_model -from netforce.utils import get_data_path -import time -from netforce.access import get_active_user -from netforce.access import get_active_company +from netforce.model import Model, fields class Hdcaseline(Model): _name="clinic.hd.case.line" _fields={ "hd_case_id": fields.Many2One("clinic.hd.case","HdCase",required=True,on_delete="cascade"), - "dialzer_id": fields.Many2One("clinic.dialyzer","Dialzer",search=True), - "detail": fields.Char("description",search=True), - "use_time":fields.Integer("Use time"), - "max_use_time":fields.Integer("Max use time"), - "member_type": fields.Selection([("unsub","Unsub cellul"),("sub","Sub cellul"),("synthetic","Synthetic")],"Member Type",required=True), - "dialyzer_type": fields.Selection([("low","low flux"),("high","high flux"),("dbl","dbl hifulx")],"Member Type",required=True), - "bid_flow_rate": fields.Integer("Bid Flow Rate (ml/min)",required=True,search=True), - "ultrafittration": fields.Float("Ultrafittration Kg.",required=True,search=True), - "state":fields.Selection([("draft","New"),("active","Active"),("drop","Drop")],"Status DZ"), + "product_id": fields.Many2One("product","Product",search=True), + "detail": fields.Char("Description",search=True), + "qty":fields.Integer("QTY"), + "uom_id": fields.Many2One("uom","UOM",required=True,search=True), + "price":fields.Float("Price"), + "total":fields.Float("Total"), } + Hdcaseline.register() diff --git a/netforce_clinic/models/hd_case_line_detail.py b/netforce_clinic/models/hd_case_line_detail.py deleted file mode 100644 index ecb77e3..0000000 --- a/netforce_clinic/models/hd_case_line_detail.py +++ /dev/null @@ -1,19 +0,0 @@ -from netforce.model import Model, fields, get_model -from netforce.utils import get_data_path -import time -from netforce.access import get_active_user -from netforce.access import get_active_company - -class HdcaselineDetail(Model): - _name="clinic.hd.case.line.detail" - _fields={ - "hd_case_id": fields.Many2One("clinic.hd.case","HdCase",required=True,on_delete="cascade"), - "product_id": fields.Many2One("product","Product",search=True), - "detail": fields.Char("Description",search=True), - "qty":fields.Integer("QTY"), - "uom_id": fields.Many2One("uom","UOM",required=True,search=True), - "price":fields.Float("Price"), - "total":fields.Float("Total"), - } -HdcaselineDetail.register() - diff --git a/netforce_clinic/models/patient.py b/netforce_clinic/models/patient.py index 579055f..7ff8b59 100644 --- a/netforce_clinic/models/patient.py +++ b/netforce_clinic/models/patient.py @@ -139,7 +139,7 @@ class Patient(Model): data['partner_id']=partner_id 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=self.get_partner_id(patient_type=obj.type,data={'name': obj.name}) @@ -147,8 +147,35 @@ class Patient(Model): 'partner_id': partner_id, }) return obj_id - + + def create(self,vals,**kw): + obj_id=super(Patient,self).create(vals,**kw) + obj=self.browse(obj_id) + partner_id=obj.partner_id + if not partner_id: + for partner in get_model("partner").search_browse([['name', '=', obj.name]]): + if partner.name==obj.name: + partner_id=partner.id + break + if not partner_id: + partner_id=get_model("partner").create({ + 'name': obj.name, + 'last_name': obj.name, + 'type': 'person', + }) + obj.write({ + 'partner_id': partner_id, + }) + return obj_id + def delete(self,ids,context={}): + partner_ids=[] + for obj in self.browse(ids): + partner_ids.append(obj.partner_id.id) + 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"): @@ -156,11 +183,19 @@ class Patient(Model): get_model("partner").delete(partner_ids) super().delete(ids) - def _write(self,ids,vals,**kw): - partner_id=vals.get('partner_id') - if not partner_id: - obj=self.browse(ids[0]) - vals['partner_id']=self.get_partner_id(patient_type=obj.type,data={'name': obj.name}) + def write(self,ids,vals,**kw): + for obj in self.browse(ids): + if not obj.partner_id: + for partner in get_model("partner").search_browse([['name', '=', obj.name]]): + if partner.name==obj.name: + partner_id=partner.id + break + if not partner_id: + partner_id=get_model("partner").create({ + 'name': obj.name, + 'type': 'person', + }) + vals['partner_id']=partner_id super().write(ids,vals,**kw) Patient.register() diff --git a/netforce_clinic/models/visit.py b/netforce_clinic/models/visit.py index 687bda7..f3a54c6 100644 --- a/netforce_clinic/models/visit.py +++ b/netforce_clinic/models/visit.py @@ -2,7 +2,7 @@ import time import datetime from netforce.model import Model, fields, get_model -from netforce.access import get_active_company, get_active_user +from netforce.access import get_active_company, get_active_user, set_active_user class Visit(Model): _name="clinic.visit" @@ -21,17 +21,22 @@ class Visit(Model): "state": fields.Selection([("pending","Pending"),("confirmed","Confirmed"),("cancelled","Cancelled")],"Status",required=True), "comments": fields.One2Many("message","related_id","Comments"), "company_id": fields.Many2One("company","Company"), + 'time_use': fields.Integer("Time Use(hrs)"), } def _get_number(self,context={}): while 1: - num=get_model("sequence").get_number("sale_order") + seq_id=get_model("sequence").find_sequence(name="Clinic Visit") + num=get_model("sequence").get_next_number(seq_id,context=context) if not num: return None + user_id=get_active_user() + set_active_user(1) res=self.search([["number","=",num]]) + set_active_user(user_id) if not res: return num - get_model("sequence").increment("sale_order") + get_model("sequence").increment_number(seq_id,context=context) def _get_nurse(self,context={}): user_id=get_active_user() @@ -48,9 +53,12 @@ class Visit(Model): "number": _get_number, "company_id": lambda *a: get_active_company(), 'nurse_id': _get_nurse, + 'time_use': 1, } _order="date,cycle" + def get_dialyzer(self): + return def confirm(self,ids,context={}): obj=self.browse(ids)[0] @@ -59,11 +67,12 @@ class Visit(Model): fmt_date="%Y-%m-%d %H:%M:%S" timenow=dt.now().strftime("%H:%M:%S") date_from=dt.strptime("%s %s"%(obj.visit_date,timenow),fmt_date) - to=3600 - date_to=date_from+datetime.timedelta(seconds=to) + seconds=(obj.time_use or 1)*3600 + date_to=date_from+datetime.timedelta(seconds=seconds) date_to=date_to.strftime(fmt_date) date_from=date_from.strftime(fmt_date) - hd_case_id=hd_case_obj.create({ + 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, 'nurse_id': obj.nurse_id.id, @@ -71,7 +80,46 @@ class Visit(Model): 'date_start': date_from, 'date_stop': date_to, 'visit_id': obj.id, - }) + 'fee': include_fee and 1500.00 or 0.0, + 'fee_type': obj.patient_id.type, + 'lines':[], + 'dialyzers': [], + } + + patient_type={ + "mg":"Medical Government", + "sc":"Social Security", + "nhso":"NHSO (30฿)", + "personal": "Personal", + "others": "Others", + } + categ_name=patient_type.get(obj.patient_id.type) + categ_ids=get_model("partner.categ").search([['name','=',categ_name]]) + if not categ_ids: + raise Exception("Category: %s not found"%categ_name) + partner_id=None + if obj.patient_id.type in ("mg","sc","nhso"): + partner_obj=get_model("partner") + for partner in partner_obj.search_browse([]): + if partner.categ_id.id in categ_ids: + partner_id=partner.id + vals['fee_partner_id']=partner_id + break + + # find dialyser + for dlz in get_model("clinic.dialyzer").search_browse([['patient_id','=',obj.patient_id.id],['state','=','active']]): + vals['dialyzers'].append({ + "dialzer_id": dlz.id, + "description": dlz.description, + "use_time": dlz.use_time, + "max_use_time": dlz.max_use_time, + "member_type": dlz.member_type, + "dialyzer_type": dlz.dialyzer_type, + "bid_flow_rate": dlz.bid_flow_rate, + "ultrafittration": dlz.ultrafittration, + }) + + hd_case_id=hd_case_id=hd_case_obj.create(vals) obj.write({"state":"confirmed"}) return { 'next': { @@ -79,7 +127,7 @@ class Visit(Model): 'mode': 'form', 'active_id': hd_case_id, }, - 'flash': 'Visit %s confirmed'%obj.number, + 'flash': 'Visit %s has been confirmed'%obj.number, } def cancel(self,ids,context={}): @@ -102,5 +150,25 @@ class Visit(Model): data['patient_id']=None data['department_id']=None return data + + def copy(self,ids,context={}): + obj=self.browse(ids[0]) + vals={ + 'patient_id': obj.patient_id.id, + 'doctor_id': obj.doctor_id.id, + 'nurse_id': obj.nurse_id.id, + 'department_id': obj.department_id.id, + } + new_id=self.create(vals,context=context) + new_obj=self.browse(new_id) + return { + 'next':{ + 'name': 'clinic_visit', + 'mode': 'form', + 'active_id': new_id, + }, + 'flash': 'Visit %s is copy to %s'%(obj.number,new_obj.number), + } + Visit.register()