357 lines
12 KiB
Python
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"),
|
|
'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=='S':
|
|
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=='U':
|
|
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=='S':
|
|
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()
|