2014-10-28 13:39:29 +00:00
|
|
|
import re
|
2014-10-26 08:48:51 +00:00
|
|
|
import time
|
|
|
|
|
|
|
|
from netforce.model import Model, fields, get_model
|
|
|
|
from netforce.access import get_active_company
|
2014-10-26 10:11:19 +00:00
|
|
|
from netforce.utils import get_data_path
|
2014-10-26 08:48:51 +00:00
|
|
|
|
|
|
|
class CycleItem(Model):
|
|
|
|
_name="clinic.cycle.item"
|
|
|
|
_string="Cycle Item"
|
2014-10-26 10:11:19 +00:00
|
|
|
_name_field="name"
|
2014-10-26 08:48:51 +00:00
|
|
|
|
|
|
|
def _get_all(self,ids,context):
|
|
|
|
res={}
|
|
|
|
for obj in self.browse(ids):
|
2014-10-26 10:11:19 +00:00
|
|
|
name="%s-%s"%(obj.cycle_id.name,obj.date)
|
2014-10-26 08:48:51 +00:00
|
|
|
hd_total=len([hd_case for hd_case in obj.hd_cases if hd_case.state=='completed']) # XXX
|
|
|
|
pt=(hd_total or 0.0)
|
|
|
|
k=(obj.var_k or 0.0)
|
|
|
|
pt_k=pt*k
|
|
|
|
x=(pt_k + 1275)/13.5
|
|
|
|
total=0.0
|
2014-10-26 15:17:56 +00:00
|
|
|
for line in obj.nurse_lines:
|
2014-10-27 14:17:22 +00:00
|
|
|
total+=(line.amount or 0.0)
|
2014-10-26 15:17:56 +00:00
|
|
|
total2=0.0
|
|
|
|
for line in obj.doctor_lines:
|
2014-10-27 14:17:22 +00:00
|
|
|
total2+=(line.amount or 0.0)
|
2014-10-26 08:48:51 +00:00
|
|
|
res[obj.id]={
|
2014-10-26 10:11:19 +00:00
|
|
|
'name': name,
|
2014-10-26 08:48:51 +00:00
|
|
|
'var_x': x,
|
|
|
|
'total_pt': hd_total,
|
|
|
|
'total_amount': hd_total*k,
|
|
|
|
'total': total,
|
2014-10-26 15:17:56 +00:00
|
|
|
'total2': total2,
|
2014-10-26 10:11:19 +00:00
|
|
|
'total_balance': (hd_total*k)-total,
|
2014-10-26 08:48:51 +00:00
|
|
|
}
|
|
|
|
return res
|
|
|
|
|
|
|
|
_fields={
|
2014-10-26 10:11:19 +00:00
|
|
|
'name': fields.Char("Name", function="_get_all",function_multi=True), # need to field related in journal
|
2014-10-26 08:48:51 +00:00
|
|
|
'company_id': fields.Many2One("company", "Company"),
|
|
|
|
'cycle_id': fields.Many2One("clinic.cycle", "Cycle",search=True),
|
|
|
|
'date': fields.Date("Date",search=True),
|
|
|
|
'var_k': fields.Float("K"),
|
|
|
|
'var_x': fields.Float("X", function="_get_all",function_multi=True),
|
|
|
|
'total_pt': fields.Float("PT", function="_get_all",function_multi=True),
|
|
|
|
'total_amount': fields.Float("PT*K", function="_get_all",function_multi=True),
|
2014-10-26 10:11:19 +00:00
|
|
|
'total_balance': fields.Float("Total Balance", function="_get_all",function_multi=True),
|
2014-10-26 08:48:51 +00:00
|
|
|
'total': fields.Float("Total", function="_get_all",function_multi=True),
|
2014-10-26 15:17:56 +00:00
|
|
|
'total2': fields.Float("Total", function="_get_all",function_multi=True),
|
2014-10-26 08:48:51 +00:00
|
|
|
"state": fields.Selection([("draft","Draft"),("done","Done")],"Status",required=True),
|
|
|
|
'hd_cases': fields.One2Many("clinic.hd.case","cycle_item_id", "HD Cases"),
|
2014-10-26 15:17:56 +00:00
|
|
|
'nurse_lines': fields.One2Many('clinic.cycle.item.line', 'cycle_item_id', 'Nurse Lines',domain=[['type','=','nurse']]),
|
|
|
|
'doctor_lines': fields.One2Many('clinic.cycle.item.line', 'cycle_item_id', 'Doctor Lines',domain=[['type','=','doctor']]),
|
|
|
|
'var_doctor': fields.Float("K Doctor"),
|
2014-10-26 08:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_defaults={
|
|
|
|
'state': 'draft',
|
|
|
|
'company_id': lambda *a: get_active_company(),
|
|
|
|
'date': lambda *a: time.strftime("%Y-%m-%d"),
|
|
|
|
'var_k': 450,
|
2014-10-26 15:17:56 +00:00
|
|
|
'var_doctor': 450,
|
2014-10-26 08:48:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def compute(self,ids,context={}):
|
2014-10-28 13:39:29 +00:00
|
|
|
# XXX should compute after hd case done
|
2014-10-26 08:48:51 +00:00
|
|
|
for obj in self.browse(ids):
|
2014-10-26 15:17:56 +00:00
|
|
|
vals={
|
|
|
|
'nurse_lines': [],
|
|
|
|
'doctor_lines': [],
|
|
|
|
}
|
|
|
|
nurse_dict={}
|
|
|
|
doctor_dict={}
|
2014-10-26 08:48:51 +00:00
|
|
|
for hd_case in obj.hd_cases:
|
|
|
|
if hd_case.state=='completed':
|
|
|
|
nurse_code=hd_case.nurse_id.categ_id.code or ""
|
2014-10-26 15:17:56 +00:00
|
|
|
if not nurse_dict.get(nurse_code):
|
|
|
|
nurse_dict[nurse_code]=0
|
|
|
|
nurse_dict[nurse_code]+=1
|
|
|
|
|
|
|
|
doctor_categ=hd_case.doctor_id.categ_id or ""
|
|
|
|
if not doctor_categ:
|
|
|
|
continue
|
|
|
|
doctor_name=hd_case.doctor_id.name or ""
|
|
|
|
key=(doctor_categ,doctor_name)
|
|
|
|
if not doctor_dict.get(key):
|
|
|
|
doctor_dict[key]=0
|
|
|
|
doctor_dict[key]+=1
|
2014-10-26 08:48:51 +00:00
|
|
|
|
2014-10-26 15:17:56 +00:00
|
|
|
for line in obj.nurse_lines:
|
|
|
|
line.delete()
|
|
|
|
for line in obj.doctor_lines:
|
2014-10-26 08:48:51 +00:00
|
|
|
line.delete()
|
|
|
|
|
2014-10-26 15:17:56 +00:00
|
|
|
for k, v in doctor_dict.items():
|
|
|
|
categ=k[0]
|
|
|
|
name=k[1]
|
|
|
|
qty=v
|
|
|
|
vals['doctor_lines'].append(('create',{
|
|
|
|
'personal_categ': categ.id,
|
|
|
|
'description': name,
|
|
|
|
'type': 'doctor',
|
|
|
|
'formular': categ.formular,
|
|
|
|
'qty': qty,
|
|
|
|
'rate': obj.var_doctor or 0.0,
|
2014-10-27 14:17:22 +00:00
|
|
|
'amount': qty*obj.var_doctor,
|
2014-10-26 08:48:51 +00:00
|
|
|
}))
|
2014-10-26 15:17:56 +00:00
|
|
|
|
|
|
|
print(nurse_dict)
|
|
|
|
for personal_categ in get_model("clinic.personal.categ").search_browse([]):
|
|
|
|
if personal_categ.type=='nurse':
|
|
|
|
formular=personal_categ.formular or ""
|
|
|
|
rate=0
|
|
|
|
try:
|
|
|
|
var_x="%s"%(round(obj.var_x,2))
|
|
|
|
formulared=formular.replace("x",var_x)
|
|
|
|
rate=eval(formulared)
|
|
|
|
except:
|
|
|
|
rate=0
|
2014-10-27 14:17:22 +00:00
|
|
|
qty=nurse_dict.get(personal_categ.code,0)
|
2014-10-26 15:17:56 +00:00
|
|
|
vals['nurse_lines'].append(('create',{
|
|
|
|
'personal_categ': personal_categ.id,
|
|
|
|
'type': 'nurse',
|
|
|
|
'formular': formular,
|
2014-10-27 14:17:22 +00:00
|
|
|
'qty': qty,
|
2014-10-26 15:17:56 +00:00
|
|
|
'rate': rate,
|
2014-10-27 14:17:22 +00:00
|
|
|
'amount': qty*rate,
|
2014-10-26 15:17:56 +00:00
|
|
|
}))
|
2014-10-27 14:17:22 +00:00
|
|
|
print("qty * rate ", qty, ' ', rate)
|
2014-10-27 19:01:18 +00:00
|
|
|
# x=(pt*k+n2*100+n3*250-n4*25-n5*25+n6*75)/(n1+n2+n3+0.5*(n4+n5+n6))
|
2014-10-26 15:17:56 +00:00
|
|
|
|
2014-10-26 08:48:51 +00:00
|
|
|
obj.write(vals)
|
|
|
|
|
|
|
|
return {
|
|
|
|
'next': {
|
|
|
|
'name': 'clinic_cycle_item',
|
|
|
|
'mode': 'form',
|
|
|
|
'active_id': obj.id,
|
|
|
|
},
|
|
|
|
'flash': 'Compute OK',
|
|
|
|
}
|
2014-10-28 13:39:29 +00:00
|
|
|
|
|
|
|
def reduce_formular(self,line_strs=None):
|
|
|
|
def get_lines(line_str):
|
|
|
|
return line_strs.replace("\n","").replace(" ","").split(",")
|
|
|
|
line2=[]
|
|
|
|
m='/(\d+)'
|
|
|
|
for line in get_lines(line_strs):
|
|
|
|
res=re.findall(m,line)
|
|
|
|
if res:
|
|
|
|
x1=res[0]
|
|
|
|
line=line.replace("/%s"%x1,"")
|
|
|
|
line=line.replace("(","")
|
|
|
|
line=line.replace(")","")
|
|
|
|
p1='x'
|
|
|
|
res=re.findall(p1,line)
|
|
|
|
if res:
|
|
|
|
line=line.replace("x",'x/%s'%x1)
|
|
|
|
p2='[-,+,*]\d+'
|
|
|
|
res=re.findall(p2,line)
|
|
|
|
if res:
|
|
|
|
for r in res:
|
|
|
|
x2=float(r)/float(x1)
|
|
|
|
x2=x2> 0 and '+%s'%x2 or x2
|
|
|
|
line=line.replace(r,str(x2))
|
|
|
|
if line:
|
|
|
|
line2.append(line)
|
|
|
|
return line2
|
2014-10-26 10:11:19 +00:00
|
|
|
|
2014-10-28 13:39:29 +00:00
|
|
|
def match_value(self,items):
|
|
|
|
for qty, f in items:
|
|
|
|
p1='x'
|
|
|
|
res=re.findall(p1,f)
|
|
|
|
if res:
|
|
|
|
f=f.replace("x",'%sx'%qty)
|
|
|
|
|
|
|
|
p2='([-,+,*])(\d+)'
|
|
|
|
res=re.findall(p2,f)
|
|
|
|
#XXX
|
|
|
|
if res:
|
|
|
|
#print('res ', res)
|
|
|
|
sym=res[0][0]
|
|
|
|
v=res[0][1]
|
|
|
|
sym_v=''.join([sym,str(int(v)*int(qty))])
|
|
|
|
old_v=''.join([sym,str(int(v))])
|
|
|
|
#print('-'*50)
|
|
|
|
#print(f)
|
|
|
|
#print(old_v, " ", sym_v)
|
|
|
|
f=f.replace('%s'%str(old_v),'%s'%str(sym_v))
|
|
|
|
#print(f)
|
|
|
|
#print('-'*50)
|
|
|
|
print(f)
|
|
|
|
|
2014-10-26 10:11:19 +00:00
|
|
|
def onchange_line(self,context={}):
|
|
|
|
data=context['data']
|
|
|
|
path=context["path"]
|
|
|
|
line=get_data_path(data,path,parent=True)
|
2014-10-28 13:39:29 +00:00
|
|
|
#pt=data['pt'] or 0.0
|
|
|
|
#k=data['var_k'] or 0.0
|
|
|
|
#x=(pt*k+n2*100+n3*250-n4*25-n5*25+n6*75)/(n1+n2+n3+0.5*(n4+n5+n6))
|
2014-10-26 10:11:19 +00:00
|
|
|
#qty=line.get("qty")
|
|
|
|
#rate=line.get("rate")
|
|
|
|
total=0.0
|
2014-10-28 13:39:29 +00:00
|
|
|
items=[]
|
|
|
|
values=[]
|
2014-10-26 15:17:56 +00:00
|
|
|
for line in data['nurse_lines']:
|
2014-10-27 14:17:22 +00:00
|
|
|
formular=line['formular']
|
2014-10-28 13:39:29 +00:00
|
|
|
values.append(line['qty'])
|
|
|
|
items.append(formular)
|
2014-10-27 14:17:22 +00:00
|
|
|
qty=line['qty']
|
|
|
|
rate=line['rate']
|
|
|
|
line['amount']=qty*rate
|
2014-10-26 10:11:19 +00:00
|
|
|
total+=line['amount']
|
2014-10-28 13:39:29 +00:00
|
|
|
formulars=self.reduce_formular(','.join(items))
|
|
|
|
res=self.match_value(list(zip(values,formulars)))
|
2014-10-26 10:11:19 +00:00
|
|
|
data['total']=total
|
|
|
|
data['total_amount']=data['total_pt']*(data['var_k'] or 0)
|
|
|
|
data['total_balance']=data['total_amount']-data['total']
|
|
|
|
return data
|
|
|
|
|
2014-10-27 14:17:22 +00:00
|
|
|
def create_payment(self,ids,context={}):
|
2014-10-26 10:11:19 +00:00
|
|
|
obj=self.browse(ids)[0]
|
|
|
|
settings=get_model("settings").browse(1)
|
|
|
|
account_id=settings.ap_nurse_id.id
|
|
|
|
if not account_id:
|
2014-10-27 14:17:22 +00:00
|
|
|
raise Exception("No Account payment for Nurse")
|
2014-10-26 10:11:19 +00:00
|
|
|
vals={
|
|
|
|
"company_id": obj.company_id.id,
|
2014-10-27 14:17:22 +00:00
|
|
|
"type": "out",
|
2014-10-26 10:11:19 +00:00
|
|
|
"pay_type": "direct",
|
|
|
|
"date": obj.date or time.strftime("%Y-%m-%d"),
|
|
|
|
"account_id": account_id,
|
|
|
|
'related_id': "clinic.cycle.item,%s"%obj.id,
|
|
|
|
'direct_lines': [],
|
|
|
|
}
|
2014-10-26 15:17:56 +00:00
|
|
|
for line in obj.nurse_lines:
|
2014-10-26 10:11:19 +00:00
|
|
|
if not line.amount:
|
|
|
|
continue
|
|
|
|
vals['direct_lines'].append(('create',{
|
2014-10-26 15:17:56 +00:00
|
|
|
'description': 'Payment; %s'%line.personal_categ.name,
|
2014-10-26 10:11:19 +00:00
|
|
|
'account_id': account_id,
|
|
|
|
'qty': 1,
|
|
|
|
'unit_price': line.amount,
|
|
|
|
'amount': line.amount,
|
|
|
|
}))
|
2014-10-27 14:17:22 +00:00
|
|
|
account_id=settings.ap_doctor_id.id
|
|
|
|
if not account_id:
|
|
|
|
raise Exception("No Account payment for Doctor")
|
2014-10-26 15:17:56 +00:00
|
|
|
for line in obj.doctor_lines:
|
|
|
|
if not line.amount:
|
|
|
|
continue
|
|
|
|
vals['direct_lines'].append(('create',{
|
|
|
|
'description': 'Payment; %s'%line.description,
|
|
|
|
'account_id': account_id,
|
|
|
|
'qty': line.qty,
|
|
|
|
'unit_price': line.amount,
|
|
|
|
'amount': line.amount,
|
|
|
|
}))
|
|
|
|
|
2014-10-27 19:01:18 +00:00
|
|
|
payment_id=get_model("account.payment").create(vals,context={"type":"out"})
|
2014-10-27 14:17:22 +00:00
|
|
|
#get_model("account.payment").browse(payment_id).post()
|
2014-10-26 10:11:19 +00:00
|
|
|
obj.write({
|
|
|
|
'state': 'done',
|
|
|
|
})
|
2014-10-27 14:17:22 +00:00
|
|
|
if context.get('called'):
|
|
|
|
return obj.id
|
2014-10-26 10:11:19 +00:00
|
|
|
return {
|
|
|
|
'next': {
|
|
|
|
'name': 'payment',
|
|
|
|
'mode': 'form',
|
|
|
|
'active_id': payment_id,
|
|
|
|
},
|
|
|
|
'flash': 'Create journal successfully',
|
|
|
|
}
|
|
|
|
|
|
|
|
def to_draft(self,ids,context={}):
|
|
|
|
obj=self.browse(ids)[0]
|
|
|
|
related_id="clinic.cycle.item,%s"%obj.id
|
|
|
|
for payment in get_model("account.payment").search_browse([['related_id','=',related_id]]):
|
|
|
|
payment.to_draft()
|
|
|
|
payment.delete()
|
|
|
|
obj.write({
|
|
|
|
'state': 'draft',
|
|
|
|
})
|
2014-10-27 14:17:22 +00:00
|
|
|
if context.get('called'):
|
|
|
|
return obj.id
|
2014-10-26 10:11:19 +00:00
|
|
|
return {
|
|
|
|
'next': {
|
|
|
|
'name': 'clinic_cycle_item',
|
|
|
|
'mode': 'form',
|
|
|
|
'active_id': obj.id,
|
|
|
|
},
|
|
|
|
'flash': 'Cycle item is set to draft',
|
|
|
|
}
|
2014-10-27 14:17:22 +00:00
|
|
|
|
|
|
|
def to_drafts(self,ids,context={}):
|
|
|
|
for obj in self.browse(ids):
|
|
|
|
context['called']=True
|
|
|
|
obj.to_draft(context=context)
|
|
|
|
return {
|
|
|
|
'next': {
|
|
|
|
'name': 'clinic_cycle_item',
|
|
|
|
'mode': 'list',
|
|
|
|
},
|
|
|
|
'flash': 'Cycle item is set to draft',
|
|
|
|
}
|
2014-10-26 10:11:19 +00:00
|
|
|
|
2014-10-27 14:17:22 +00:00
|
|
|
def view_payment(self,ids,context={}):
|
2014-10-26 10:11:19 +00:00
|
|
|
obj=self.browse(ids)[0]
|
|
|
|
related_id="clinic.cycle.item,%s"%obj.id
|
|
|
|
payment_ids=get_model("account.payment").search([['related_id','=',related_id]])
|
|
|
|
if payment_ids:
|
|
|
|
payment_id=payment_ids[0]
|
|
|
|
return {
|
|
|
|
'next': {
|
|
|
|
'name': 'payment',
|
|
|
|
'mode': 'form',
|
|
|
|
'active_id': payment_id,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2014-10-27 14:17:22 +00:00
|
|
|
|
|
|
|
def pay(self,ids,context={}):
|
|
|
|
context['called']=True
|
|
|
|
for obj in self.browse(ids):
|
|
|
|
obj.create_payment(context)
|
|
|
|
return {
|
|
|
|
'next': {
|
|
|
|
'name': 'clinic_cycle_item',
|
|
|
|
'mode': 'list',
|
|
|
|
},
|
|
|
|
'flash': 'Paid',
|
|
|
|
}
|
2014-10-26 08:48:51 +00:00
|
|
|
|
|
|
|
CycleItem.register()
|