clinic/netforce_clinic/models/report_payment_matching.py

357 lines
12 KiB
Python

import time
from calendar import monthrange
from netforce.model import Model,fields,get_model
from netforce.access import get_active_company
from netforce.utils import get_file_path
from . import utils
STATES={
'draft': 'Draft',
'waiting_matching':'Waiting Matching',
'match':'Match',
'unmatch':'Unmatch',
'approved':'Approved',
}
class ReportPaymentMatching(Model):
_name="clinic.report.payment.matching"
_string="Report Payment Mathching"
_transient=True
_fields={
"date": fields.Date("Month", required=True),
"date_from": fields.Date("From", required=True),
"date_to": fields.Date("To", required=True),
'state': fields.Selection([['draft','Draft'],['waiting_matching','Waiting Matching'],['match','Match'],['unmatch','Unmatch'],['approved','Approved']],'State'),
'patient_id': fields.Many2One("clinic.patient","Patient",domain=[['state','=','admit']]),
'file': fields.File("File"),
'type_id': fields.Many2One("clinic.patient.type","Patient Type",required=True),
'hcode_id': fields.Many2One("clinic.hospital","HCode",required=True),
'match_qty': fields.Integer("Match Qty"),
'unmatch_qty': fields.Integer("Unmatch Qty"),
'show_hcode': fields.Integer("Unmatch Qty"),
}
def _get_date_from(self,context={}):
year,month=time.strftime("%Y-%m").split("-")
return '%s-%s-01'%(year,month)
def _get_date_to(self,context={}):
year,month,day=time.strftime("%Y-%m-%d").split("-")
weekday, total_day=monthrange(int(year), int(month))
return "%s-%s-%s"%(year,month,total_day)
def _get_type_id(self,context={}):
st=get_model("clinic.setting").browse(1)
return st.patient_type_id.id
_defaults={
'date': lambda *a: time.strftime("%Y-%m-%d"),
'date_from': _get_date_from,
'date_to': _get_date_to,
'state': 'match',
'type_id': _get_type_id,
'show_hcode': 1,
}
def match_invoice(self,ids,context={}):
if not ids:
print("no ids")
return
obj=self.browse(ids)[0]
if not obj.file:
raise Exception("File not found!")
hcode_impt=obj.hcode_id.code or ""
fname=obj.file
#pks
if obj.type_id.code=='SSO':
n,sf=fname.split(".")
if sf not in ('xls','xlsx'):
raise Exception("File should be xls or xlsx")
fpath=get_file_path(fname)
lines=utils.read_excel(fpath,show_datetime=True)
elif obj.type_id.code=='UC':
fpath=get_file_path(fname)
node='HDBills'
lines=utils.read_xml(fpath,node=node)
hcode_impt=fname.split("_")[0]
print('>> ', hcode_impt)
else:
raise Exception("Script is not support")
if not lines:
raise Exception("No data to match")
dom=[]
dom.append(['state','in',['match','waiting_matching']])
dom.append(['ok','=',False])
matches={}
for exp in get_model("clinic.hd.case.expense").search_browse(dom):
ptype=exp.patient_id.type_id
if ptype.id==obj.type_id.id:
exp.write({
'match_id': obj.id,
'ok': False,
})
if not matches.get(exp.date):
patient=exp.patient_id
if obj.type_id.code=='SSO':
key='%s:%s:%s:%s:%s'%(
patient.hn_no,
exp.date,
exp.fee_amt and exp.fee_amt or 0,
exp.srv_amt and exp.srv_amt or 0,
exp.mdc_amt and exp.mdc_amt or 0,
)
else:
key='%s:%s:%s'%(
patient.hn_no,
exp.date,
exp.fee_amt and exp.fee_amt or 0,
)
matches[key]={
'exp_id': exp.id,
}
else:
exp.write({
'match_id': None,
'ok': False,
})
match_qty=0
unmatch_qty=0
if obj.type_id.code=='S':
for line in lines:
hcode=line.get('hcode18')
if not hcode:
hcode='0'
hcode=int(hcode)
hcode=str(hcode)
if hcode_impt==hcode:
lsrv_amt=line.get('epoadm29') or 0
lfee_amt=line.get('amount23') or 0
lmdc_amt=line.get('allow37') or 0
dttran=line.get("dttran")
date=dttran[0:10]
time=dttran[11:]
hn=line.get('hn')
hn=''.join([x for x in hn if x.isdigit()])
key='%s:%s:%s:%s:%s'%(
hn,
date,
lfee_amt,
lsrv_amt,
lmdc_amt,
)
if not time:
print("wrong format")
continue
found=matches.get(key)
if found:
exp_id=found['exp_id']
print("match !! ", key)
exp=get_model("clinic.hd.case.expense").browse(exp_id)
invno=''
if line.get('invno'):
invno='%s'%(int(line['invno']))
exp.write({
'ok': True,
'invno': invno,
'state': 'match',
})
for inv in exp.invoices:
inv.write({
'ref': invno,
})
match_qty+=1
else:
unmatch_qty+=1
print("no ", key)
elif obj.type_id.code=='U':
for line in lines:
hn=line.get('hn')
amt=line.get('amount') or 0
dttran=line.get("dttran")
date,time=dttran.split("T")
amt=round(float(amt),1)
key='%s:%s:%s'%(
hn,
date,
amt,
)
found=matches.get(key)
if found:
exp_id=found['exp_id']
exp=get_model("clinic.hd.case.expense").browse(exp_id)
invno=''
if line.get('invno'):
invno='%s'%(int(line['invno']))
exp.write({
'ok': True,
'invno': invno,
'state': 'match',
})
for inv in exp.invoices:
inv.write({
'ref': invno,
})
match_qty+=1
else:
unmatch_qty+=1
print("no ", key)
obj.write({
'match_qty': match_qty,
'unmatch_qty': unmatch_qty,
})
return {
'next': {
'name': 'clinic_report_payment_matching',
'mode': 'form',
'active_id': obj.id,
},
'flash': 'Match successfully',
}
def get_report_data(self,ids,context={}):
year, month=time.strftime("%Y-%m").split("-")
lines=[]
if not ids:
return
obj=self.browse(ids)[0]
dom=[]
dom.append(['state','!=','completed'])
dom.append(['match_id','=',obj.id])
match_qty=0
unmatch_qty=0
for exp in get_model("clinic.hd.case.expense").search_browse(dom):
patient=exp.patient_id
match='No'
exp_color=""
match_color=""
if exp.ok:
match='Yes'
exp_color='#489f48'
match_color='white'
match_qty+=1
else:
exp_color='#C0C0C0'
unmatch_qty+=1
lines.append({
'exp_id': exp.id,
'date': exp.date,
'patient_name': patient.name,
'patient_id': patient.id,
'hn': patient.hn or "",
'fee_amt': exp.fee_amt or 0,
'mdc_amt': exp.mdc_amt or 0,
'srv_amt': exp.srv_amt or 0,
#'state': STATES[exp.state],
'match': match,
'invno': exp.invno,
'exp_color': exp_color,
'match_color': match_color,
})
lines2=[]
no=1
for line in sorted(lines, key=lambda a: a['hn']):
line['no']=no
lines2.append(line)
no+=1
data={
'match_qty': match_qty or 0,
'nomatch_qty': unmatch_qty or 0,
'lines': lines2,
}
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 make_payment(self,ids,context={}):
if not ids:
return
obj=self.browse(ids)[0]
partner=obj.type_id.contact_id
company_id=get_active_company()
vals={
"partner_id": partner.id,
"company_id": company_id,
"type": "in",
"pay_type": "invoice",
'date': time.strftime("%Y-%m-%d"),
"account_id": partner.account_payment_id.id,
'invoice_lines': [],
}
dom=[]
dom.append(['ok','=',True])
dom.append(['state','=','match'])
dom.append(['match_id','=',obj.id])
count=0
for exp in get_model("clinic.hd.case.expense").search_browse(dom):
for inv in exp.invoices:
vals['invoice_lines'].append(('create',{
'invoice_id': inv.id,
'amount': inv.amount_due,
}))
exp.write({
'state': 'completed',
'ok': False,
})
count+=1
obj.write({
'match_qty': 0,
'unmatch_qty': obj.unmatch_qty-obj.match_qty,
})
if not count:
return
payment_id=get_model("account.payment").create(vals,context={"type":"in"})
return {
'next': {
'name': 'payment',
'mode': 'form',
'active_id': payment_id,
},
'flash': 'Create payment for match items',
}
def onchange_type(self,context={}):
data=context['data']
type_id=data['type_id']
ptype=get_model("clinic.patient.type").browse(type_id)
if ptype.code=='U':
data['show_hcode']=0
else:
data['show_hcode']=1
for exp in get_model("clinic.hd.case.expense").search_browse([]):
if ptype.id==exp.patient_id.type_id.id and exp.ok:
exp.write({
'ok': False,
})
print("Done!")
return data
ReportPaymentMatching.register()