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()