diff --git a/netforce_clinic/actions/clinic_report_account_hd_case_detail.xml b/netforce_clinic/actions/clinic_report_account_hd_case_detail.xml new file mode 100644 index 0000000..1ed5550 --- /dev/null +++ b/netforce_clinic/actions/clinic_report_account_hd_case_detail.xml @@ -0,0 +1,8 @@ + + Report Account HD Case Detail + report + clinic.report.account.hd.case.detail + report_account_hd_case_detail + report_account_hd_case_detail + account_menu + diff --git a/netforce_clinic/actions/clinic_report_account_hd_case_summary.xml b/netforce_clinic/actions/clinic_report_account_hd_case_summary.xml index 875e713..9ed5b18 100644 --- a/netforce_clinic/actions/clinic_report_account_hd_case_summary.xml +++ b/netforce_clinic/actions/clinic_report_account_hd_case_summary.xml @@ -1,5 +1,5 @@ - HD Case Expense + Report Account HD Case Summary report clinic.report.account.hd.case.summary report_account_hd_case_summary diff --git a/netforce_clinic/layouts/clinic_account_menu.xml b/netforce_clinic/layouts/clinic_account_menu.xml index 98b1ca2..2b9c2a4 100644 --- a/netforce_clinic/layouts/clinic_account_menu.xml +++ b/netforce_clinic/layouts/clinic_account_menu.xml @@ -4,6 +4,7 @@ + diff --git a/netforce_clinic/layouts/clinic_report_account_hd_case_detail.xml b/netforce_clinic/layouts/clinic_report_account_hd_case_detail.xml new file mode 100644 index 0000000..7c850d2 --- /dev/null +++ b/netforce_clinic/layouts/clinic_report_account_hd_case_detail.xml @@ -0,0 +1,13 @@ +
+ + + + + + + + + + + + diff --git a/netforce_clinic/models/__init__.py b/netforce_clinic/models/__init__.py index 49b3d66..37b40fe 100644 --- a/netforce_clinic/models/__init__.py +++ b/netforce_clinic/models/__init__.py @@ -68,6 +68,7 @@ from . import report_visit from . import report_cycle_item from . import report_hd_case_summary from . import report_account_hd_case_summary +from . import report_account_hd_case_detail from . import report_hd_case_detail from . import report_medical_summary from . import report_medical_detail diff --git a/netforce_clinic/models/report_account_hd_case_detail.py b/netforce_clinic/models/report_account_hd_case_detail.py new file mode 100644 index 0000000..3807143 --- /dev/null +++ b/netforce_clinic/models/report_account_hd_case_detail.py @@ -0,0 +1,345 @@ +import time +from calendar import monthrange + +from netforce.model import Model, fields, get_model +from netforce.access import get_active_company + +class ReportAccountHDCaseDetail(Model): + _name="clinic.report.account.hd.case.detail" + _string="Report Account HD Case Detail" + _transient=True + + _fields={ + "date": fields.Date("Month", required=True), + "date_from": fields.Date("From", required=True), + "date_to": fields.Date("To", required=True), + 'branch_id': fields.Many2One("clinic.branch","Branch"), + 'department_id': fields.Many2One("clinic.department","Departments"), + 'ptype_id': fields.Many2One("clinic.patient.type","Patient Type"), + 'reimbursable': fields.Selection([['yes','Yes'],['no','No']],'Claim'), + 'walkin': fields.Selection([['yes','Yes'],['no','No']],'Walkin'), + 'cycle_id': fields.Many2One("clinic.cycle","Cycle"), + 'pay_type': fields.Selection([['cash','Cash'],['credit','Credit']],'Pay Type'), + 'product_id': fields.Many2One("product","Product"), + } + + def default_get(self,field_names=None,context={},**kw): + defaults=context.get("defaults",{}) + date=defaults.get('date',time.strftime("%Y-%m-%d")) + year,month=time.strftime("%Y-%m").split("-") + weekday, total_day=monthrange(int(year), int(month)) + date_from=defaults.get('date_from','%s-%s-01'%(year,month)) + date_to=defaults.get('date_to',"%s-%s-%s"%(year,month,total_day)) + date_from=defaults.get('date',date) + date_to=defaults.get('date',date) + product_id=defaults.get('product_id') + reimbursable=defaults.get('reimbursable',"yes") + + branch_id=defaults.get('branch_id',None) + if branch_id: + branch_id=int(branch_id) + department_id=defaults.get('department_id',None) + if department_id: + department_id=int(department_id) + select_dpt=get_model('select.company').get_select() + if select_dpt: + if not branch_id: + branch_id=select_dpt['branch_id'] + if not department_id: + if select_dpt.get('department_ids'): + department_id=select_dpt['department_ids'][0] + else: + department_id=select_dpt['department_id'] + res={ + 'date': date, + 'date_from': date_from, + 'date_to': date_to, + 'branch_id': branch_id, + 'department_id': department_id, + 'reimbursable': reimbursable, + 'product_id': product_id, + } + return res + + def get_report_data(self,ids,context={}): + company_id=get_active_company() + company=get_model("company").browse(company_id) + defaults=self.default_get(context=context) + date_from=defaults.get("date_from") + date_to=defaults.get("date_to") + date=defaults.get("date") + branch_id=defaults.get("branch_id") + department_id=defaults.get("department_id") + reimbursable=defaults.get('reimbursable','yes') + product_id=defaults.get('product_id') + walkin=defaults.get('walkin') + ptype_id=None + cycle_id=None + pay_type='' + if ids: + obj=self.browse(ids)[0] + branch_id=obj.branch_id.id + department_id=obj.department_id.id + date=obj.date + date_from=obj.date_from + date_to=obj.date_to + ptype_id=obj.ptype_id.id + cycle_id=obj.cycle_id.id + reimbursable=obj.reimbursable or "" + product_id=obj.product_id.id + pay_type=obj.pay_type + walkin=obj.walkin + dom=[ + ['hd_case_id.date','>=', date_from], + ['hd_case_id.date','<=', date_to], + ['hd_case_id.state','in',['completed','waiting_payment','paid']], + ] + if walkin: + dom.append(['hd_case_id.patient_id.walkin','=',walkin]) + if ptype_id: + dom.append(['hd_case_id.patient_type_id','=',ptype_id]) + if branch_id: + dom.append(['hd_case_id.branch_id','=',branch_id]) + if department_id: + dom.append(['hd_case_id.department_id','=',department_id]) + if cycle_id: + dom.append(['hd_case_id.cycle_id','=',cycle_id]) + if reimbursable: + dom.append(['reimbursable','=',reimbursable]) + if product_id: + dom.append(['product_id','=',product_id]) + records={} + cycles={} + context['reimbursable']=reimbursable + categ_prods=[] + for cat_prod in get_model("product.categ").search_read([],['code']): + code=(cat_prod['code'] or "").lower() + categ_prods.append(code) + for line in get_model("clinic.hd.case.line").search_browse(dom,context=context): + hdcase=line.hd_case_id + pm_numbers=[] + pm_id=None + for pm in hdcase.payments: + if pm.number: + pm_numbers.append(pm.number) + pm_id=pm.id #XXX + pm_number=','.join([pnum for pnum in pm_numbers]) + prods={ + 'yes': [], + 'no': [], + '': [], + } + #get the right invoice + for hline in hdcase.lines: + prod=hline.product_id + reim=hline.reimbursable + if prod: + prods[reim].append(prod.id) + inv_number="" + inv_ref="" + inv_id=None + for inv in hdcase.invoices: + inv_prods=[] + for inv_line in inv.lines: + prod=inv_line.product_id + if prod: + if prod.id in prods[reimbursable]: + inv_prods.append(prod.id) + if prods[reimbursable]==inv_prods: + inv_number+=inv.number or "" + inv_ref+=inv.ref or "" + inv_id=inv.id + pick_ref="" + pick_id=None + for pick in hdcase.pickings: + pick_ref=pick.number or "" + pick_id=pick.id + patient=hdcase.patient_id + ptype=hdcase.patient_type_id + cycle=hdcase.cycle_id + cycle_item=hdcase.cycle_item_id + if cycle.id not in cycles.keys(): + cycles[cycle.id]=[] + for cline in cycle_item.lines: + nurse=cline.nurse_id + cycles[cycle.id].append(nurse.name) + vals={ + 'hdcase_id': hdcase.id, + 'number': hdcase.number or "", + 'date': hdcase.date, + 'hct': hdcase.hct or 0, + 'epo_name': hdcase.epo or "", + 'ptype': ptype.name or "", + 'ptype_color': ptype.color or "default", + 'dname': hdcase.doctor_id.name or "", + 'cycle': cycle.name or "", + 'cid': cycle.id, + 'pname': patient.name, + 'hn': patient.hn_no, + 'idcard': patient.card_no or "", + 'cseq': cycle.sequence or 0, + 'cycle_item_id': cycle_item.id, + 'pm_number': pm_number and pm_number or "", + 'pm_id': pm_id, + 'inv_number': inv_number and inv_number or "", + 'inv_id': inv_id, + 'mdc_name': hdcase.mdc_name, + 'dlz_name': hdcase.dlz_name, + 'dlz_id': hdcase.dlz_id and hdcase.dlz_id or 0, + 'inv_ref': inv_ref and inv_ref or "", + 'pick_ref': pick_ref and pick_ref or "", + 'pick_id': pick_id, + } + # merge 1 line of number + hdcase_id=vals['hdcase_id'] + if not records.get(hdcase_id): + for categ_prod in categ_prods: + vals[categ_prod]=0 + vals['misc']=0 + records[hdcase_id]=vals + amt=line.amount or 0 + categ=line.product_categ_id + if categ: + code=(categ.code or "").lower() + if code: + code=code.replace("epo","mdc") #XXX + records[hdcase_id][code]+=amt + else: + if categ.parent_id: + code=categ.parent_id.code or '' + if code: + code=code.lower() + records[hdcase_id][code]+=amt + else: + records[hdcase_id]['misc']+=amt + else: + records[hdcase_id]['misc']+=amt + + #print('merge product categ of ivr, fine and dlz to misc') + records[hdcase_id]['misc']+=records[hdcase_id]['ivr'] + records[hdcase_id]['misc']+=records[hdcase_id]['fine'] + records[hdcase_id]['misc']+=records[hdcase_id]['dlz'] + + lines=[] + # nurse would like to see only receipt + del_invoice=False + del_receipt=False + if pay_type and reimbursable=='no' and pay_type=='cash': + del_invoice=True + elif pay_type and reimbursable=='no' and pay_type=='credit': + del_receipt=True + + for hdcase_id, vals in records.items(): + if del_invoice and vals['inv_number']: + continue + elif del_receipt and vals['pm_number']: + continue + lines.append(vals) + company_name=company.name or "" + if department_id: + company_name+=' (%s)'%get_model('clinic.department').browse(department_id).name or "" + elif branch_id: + company_name+=' (%s)'%get_model('clinic.branch').browse(branch_id).name or "" + total_fee=0 + total_srv=0 + total_epo=0 + total_lab=0 + total_dlz=0 + total_misc=0 + total_mdc=0 + slines=[] + no=1 + ptypes={} + index=0 + old=[] + for line in sorted(lines, key=lambda x: (x['date'],x['cseq'])): + ptype=line['ptype'] or "" + if ptype not in ptypes.keys(): + ptypes[ptype]={ + 'qty': 0, + 'color': line['ptype_color'] or "default", + } + ptypes[ptype]['qty']+=1 + total_fee+=line.get('fee',0) + total_srv+=line.get('srv',0) + total_epo+=line.get('epo',0) + total_mdc+=line.get('mdc',0) + total_lab+=line.get('lab',0) + total_misc+=line.get('misc',0) + total_dlz+=line.get('dlz_price',0) + line['no']=no + + cid=line['cid'] + if not cid in old: + old.append(cid) + index=0 + else: + index+=1 + if not line.get('is_shop'): + cres=cycles[cid] + line['nurse']='' + if index < len(cres): + line['nurse']=cres[index] + slines.append(line) + no+=1 + types=[] + total_qty=0 + for name, vals in ptypes.items(): + qty=vals['qty'] or 0 + total_qty+=qty + color=vals['color'] or "default" + types.append({ + 'name': name, + 'qty': qty, + 'color': color, + }) + data={ + 'company_name': company_name, + 'branch_id': branch_id, + 'department_id': department_id, + 'date': date, + 'date_from': date_from, + 'date_to': date_to, + 'lines': slines, + 'total_fee': total_fee, + 'total_srv': total_srv, + 'total_epo': total_epo, + 'total_mdc': total_mdc, + 'total_lab': total_lab, + 'total_misc': total_misc, + 'total_dlz': total_dlz, + 'total_qty': total_qty, + 'types': types, + 'reimbursable': reimbursable, + 'is_reim': reimbursable=='yes' and True or False, + 'ptype_id': ptype_id, + } + if not reimbursable: + data['title']='' + elif reimbursable=='yes': + data['title']='Report - Claim' + else: + data['title']='Report - No Claim' + data['title']='' #XXX + return data + + def onchange_date(self,context={}): + data=context['data'] + date=data['date'] + year,month,day=date.split("-") + weekday, total_day=monthrange(int(year), int(month)) + data['date_from']="%s-%s-01"%(year,month) + data['date_to']="%s-%s-%s"%(year,month,total_day) + return data + + def onchange_branch(self,context={}): + data=context['data'] + data['department_id']=None + return data + + def onchange_datefrom(self,context={}): + data=context['data'] + data['date_to']=data['date_from'] + return data + +ReportAccountHDCaseDetail.register() diff --git a/netforce_clinic/reports/report_account_hd_case_detail.xlsx b/netforce_clinic/reports/report_account_hd_case_detail.xlsx new file mode 100644 index 0000000..d28ac1d Binary files /dev/null and b/netforce_clinic/reports/report_account_hd_case_detail.xlsx differ diff --git a/netforce_clinic/templates/report_account_hd_case_detail.hbs b/netforce_clinic/templates/report_account_hd_case_detail.hbs new file mode 100644 index 0000000..52f16e1 --- /dev/null +++ b/netforce_clinic/templates/report_account_hd_case_detail.hbs @@ -0,0 +1,155 @@ +
+

+ {{title}} +

+

+ {{company_name}}
+

+

+ From {{date_from}} To {{date_to}} +

+
+ + + + {{#ifeq reimbursable "no"}} + + + + {{#ifeq reimbursable "no"}} + + + + + + + + + + + + + + + {{else}} + + + + + + + + + + + {{/ifeq}} + + + + {{#each lines}} + + {{#ifeq ../reimbursable "no"}} + + + + + + + + + + + + + + + {{else}} + + + + + + + + + {{#if inv_id}} + + {{else}} + + {{/if}} + + {{/ifeq}} + + {{/each}} + + + {{#ifeq reimbursable "no"}} + + + + + + + + + + + + + + {{else}} + + + + + + + + + + + {{/ifeq}} + +
+ {{else}} + + {{/ifeq}} + {{#if ptype_id}} + Total: {{total_qty}} + {{else}} + {{#each types}} + {{name}}: {{qty}} + {{/each}} + Total: {{total_qty}} + {{/if}} +
Cycle#HD Case#Nameสิทธิ์Receipt#Invoice#ชื่อยาค่าฟอกค่ายาLabMisc.DlzRef.Inv#Picking#Cycle#HD Case#Nameสิทธิ์ชื่อยาค่าฟอกค่ายาค่าบริการฉีดยาInv#Picking#
{{cycle}} + {{view "link" string=number action="clinic_hd_case" action_options="mode=form" active_id=hdcase_id}} + {{pname}}{{ptype}} + {{#if pm_id}} + {{view "link" string=pm_number action="payment" action_options="mode=form" active_id=pm_id}} + {{/if}} + + {{#if inv_id}} + {{view "link" string=inv_number action="cust_invoice" action_options="form_view_xml&cust_invoice_form&mode=form" active_id=inv_id}} + {{/if}} + {{epo_name}}{{currency fee zero=""}}{{currency mdc zero=""}}{{currency lab zero=""}}{{currency misc zero=""}}{{currency dlz_price zero=""}} + {{#if inv_id}} + {{view "link" string=inv_ref action="cust_invoice" action_options="form_view_xml&cust_invoice_form&mode=form" active_id=inv_id}} + {{/if}} + + {{#if pick_id}} + {{view "link" string=pick_ref action="pick_out" action_options="mode=form" active_id=pick_id}} + {{/if}} + {{cycle}} + {{view "link" string=number action="clinic_hd_case" action_options="mode=form" active_id=hdcase_id}} + {{pname}}{{ptype}}{{epo_name}}{{currency fee zero=""}}{{currency mdc zero=""}}{{currency srv zero=""}} + {{view "link" string=inv_number action="cust_invoice" action_options="form_view_xml&cust_invoice_form&mode=form" active_id=inv_id}} + + + {{#if pick_id}} + {{view "link" string=pick_ref action="pick_out" action_options="mode=form" active_id=pick_id}} + {{else}} + - + {{/if}} +
{{currency total_fee zero=""}}{{currency total_mdc zero=""}}{{currency total_lab zero=""}}{{currency total_misc zero=""}}{{currency total_dlz zero=""}}{{currency total_fee zero=""}}{{currency total_mdc zero=""}}{{currency total_srv zero=""}}
+