Merge branch 'master' into conv_bal

conv_bal
watcha.h 2015-08-08 22:34:32 +07:00
commit 27105dba01
9 changed files with 267 additions and 41 deletions

View File

@ -33,16 +33,6 @@
</group>
<group span="6" columns="1">
</group>
<!--<field name="account_products" nolabel="1">-->
<!--<list>-->
<!--<field name="patient_type_id"/>-->
<!--<field name="categ_id"/>-->
<!--<field name="product_id" domain='[["categ_id","=",categ_id]]'/>-->
<!--<field name="type"/>-->
<!--<field name="ar_debit_id"/>-->
<!--<field name="ar_credit_id"/>-->
<!--</list>-->
<!--</field>-->
</tab>
<tab string="Matching Payment">
<field name="patient_type_id"/>
@ -57,15 +47,6 @@
</group>
<group span="6" columns="1">
</group>
<!--<field name="account_patients" nolabel="1">-->
<!--<list>-->
<!--<field name="type_id"/>-->
<!--<field name="patient_id" domain='[["type_id","=",type_id]]'/>-->
<!--<field name="partner_id" domain='[["is_patient","=","true"]]'/>-->
<!--<field name="hn"/>-->
<!--<field name="card_no"/>-->
<!--</list>-->
<!--</field>-->
</tab>
<tab string="Matching HD Case">
<field name="skip_type_id"/>

View File

@ -0,0 +1,5 @@
<inherit inherit="fin_settings">
<field name="rounding_account_id" position="after">
<field name="acc_prod_match"/>
</field>
</inherit>

View File

@ -1,3 +1,5 @@
import time
from netforce.model import Model, fields, get_model
class AccountInvoice(Model):
@ -75,4 +77,237 @@ class AccountInvoice(Model):
}
get_model("account.fixed.asset").create(vals)
def post(self,ids,context={}):
t0=time.time()
settings=get_model("settings").browse(1)
for obj in self.browse(ids):
obj.check_related()
if abs(obj.amount_total)<0.001:
raise Exception("Invoice total is zero")
partner=obj.partner_id
if obj.type=="out":
account_id=partner.account_receivable_id.id or settings.account_receivable_id.id
if not account_id:
raise Exception("Account receivable not found")
elif obj.type=="in":
account_id=partner.account_payable_id.id or settings.account_payable_id.id
if not account_id:
raise Exception("Account payable not found")
sign=obj.type=="out" and 1 or -1
if obj.inv_type=="credit":
sign*=-1
obj.write({"account_id": account_id})
if obj.type=="out":
desc="Sale; "+partner.name
elif obj.type=="in":
desc="Purchase; "+partner.name
if obj.type=="out":
journal_id=settings.sale_journal_id.id
if not journal_id:
raise Exception("Sales journal not found")
elif obj.type=="in":
journal_id=settings.purchase_journal_id.id
if not journal_id:
raise Exception("Purchases journal not found")
if obj.currency_rate:
currency_rate=obj.currency_rate
else:
if obj.currency_id.id==settings.currency_id.id:
currency_rate=1.0
else:
rate_from=obj.currency_id.get_rate(date=obj.date)
if not rate_from:
raise Exception("Missing currency rate for %s"%obj.currency_id.code)
rate_to=settings.currency_id.get_rate(date=obj.date)
if not rate_to:
raise Exception("Missing currency rate for %s"%settings.currency_id.code)
currency_rate=rate_from/rate_to
obj.write({"currency_rate":currency_rate})
move_vals={
"journal_id": journal_id,
"number": obj.number,
"date": obj.date,
"ref": obj.ref,
"narration": desc,
"related_id": "account.invoice,%s"%obj.id,
"company_id": obj.company_id.id,
}
lines=[]
taxes={}
tax_nos=[]
t01=time.time()
total_amt=0.0
total_base=0.0
total_tax=0.0
for line in obj.lines:
cur_amt=get_model("currency").convert(line.amount,obj.currency_id.id,settings.currency_id.id,rate=currency_rate)
total_amt+=cur_amt
tax_id=line.tax_id
if tax_id and obj.tax_type!="no_tax":
base_amt=get_model("account.tax.rate").compute_base(tax_id,cur_amt,tax_type=obj.tax_type)
tax_comps=get_model("account.tax.rate").compute_taxes(tax_id,base_amt,when="invoice")
for comp_id,tax_amt in tax_comps.items():
tax_vals=taxes.setdefault(comp_id,{"tax_amt":0,"base_amt":0})
tax_vals["tax_amt"]+=tax_amt
tax_vals["base_amt"]+=base_amt
total_tax+=tax_amt
else:
base_amt=cur_amt
total_base+=base_amt
acc_id=line.account_id.id
if not acc_id:
raise Exception("Missing line account for invoice line '%s'"%line.description)
amt=base_amt*sign
line_vals={
"description": line.description,
"account_id": acc_id,
"credit": amt>0 and amt or 0,
"debit": amt<0 and -amt or 0,
"track_id": line.track_id.id,
"track2_id": line.track2_id.id,
"partner_id": partner.id,
}
lines.append(line_vals)
for comp_id,tax_vals in taxes.items():
comp=get_model("account.tax.component").browse(comp_id)
acc_id=comp.account_id.id
if not acc_id:
raise Exception("Missing account for tax component %s"%comp.name)
amt=tax_vals["tax_amt"]*sign
line_vals={
"description": desc,
"account_id": acc_id,
"credit": amt>0 and amt or 0,
"debit": amt<0 and -amt or 0,
"tax_comp_id": comp_id,
"tax_base": tax_vals["base_amt"],
"partner_id": partner.id,
"invoice_id": obj.id,
}
if comp.type in ("vat","vat_exempt"):
if obj.type=="out":
if obj.tax_no:
tax_no=obj.tax_no
else:
tax_no=self.gen_tax_no(exclude=tax_nos,context={"date":obj.date})
tax_nos.append(tax_no)
obj.write({"tax_no":tax_no})
line_vals["tax_no"]=tax_no
elif obj.type=="in":
line_vals["tax_no"]=obj.tax_no
lines.append(line_vals)
if obj.tax_type=="tax_in":
rounding=total_amt-(total_base+total_tax)
if abs(rounding)>0.00499: # XXX
amt=rounding*sign
if not settings.rounding_account_id.id:
raise Exception("Missing rounding account in financial settings")
line_vals={
"description": desc,
"account_id": settings.rounding_account_id.id,
"credit": amt>0 and amt or 0,
"debit": amt<0 and -amt or 0,
"partner_id": partner.id,
"invoice_id": obj.id,
}
lines.append(line_vals)
t02=time.time()
dt01=(t02-t01)*1000
print("post dt01",dt01)
groups={}
keys=["description","account_id","track_id","tax_comp_id","partner_id","invoice_id","reconcile_id"]
for line in lines:
key_val=tuple(line.get(k) for k in keys)
if key_val in groups:
group=groups[key_val]
group["debit"]+=line["debit"]
group["credit"]+=line["credit"]
if line.get("tax_base"):
if "tax_base" not in group:
group["tax_base"]=0
group["tax_base"]+=line["tax_base"]
else:
groups[key_val]=line.copy()
group_lines=sorted(groups.values(),key=lambda l: (l["debit"],l["credit"]))
for line in group_lines:
amt=line["debit"]-line["credit"]
amt=get_model("currency").round(settings.currency_id.id,amt)
if amt>=0:
line["debit"]=amt
line["credit"]=0
else:
line["debit"]=0
line["credit"]=-amt
is_match=False
if settings.acc_prod_match and obj.type=='out':
print("#POST: clinic customize")
cst=get_model('clinic.setting').browse(1)
prod_acc=cst.get_product_account
move_vals["lines"]=[]
for line in group_lines:
desc=line['description']
ar_debit_id=None
#ar_credit_id=None
for prod_id in get_model('product').search([['name','=',desc]]):
for ptype_id in get_model("clinic.patient.type").search([['contact_id','=',partner.id]]):
acc=prod_acc(prod_id,ptype_id,'credit')
#ar_credit_id=acc.get("ar_credit_id")
ar_debit_id=acc.get("ar_debit_id")
if ar_debit_id:
break
if not ar_debit_id:
raise Exception("Missing AR Debit Account for product %s"%(desc))
line_vals={
"description": desc,
"account_id": ar_debit_id,
"debit": line['credit'],
"credit": 0,
"due_date": obj.due_date,
"partner_id": partner.id,
'track_id': line['track_id'],
}
move_vals["lines"]+=[("create",line_vals)]
move_vals["lines"]+=[("create",vals) for vals in group_lines]
is_match=True
if not is_match:
print("#POST: standard account")
amt=0
for line in group_lines:
amt-=line["debit"]-line["credit"]
line_vals={
"description": desc,
"account_id": account_id,
"debit": amt>0 and amt or 0,
"credit": amt<0 and -amt or 0,
"due_date": obj.due_date,
"partner_id": partner.id,
}
acc=get_model("account.account").browse(account_id)
if acc.currency_id.id!=settings.currency_id.id:
if acc.currency_id.id!=obj.currency_id.id:
raise Exception("Invalid account currency for this invoice: %s"%acc.code)
line_vals["amount_cur"]=obj.amount_total*sign
move_vals["lines"]=[("create",line_vals)]
move_vals["lines"]+=[("create",vals) for vals in group_lines]
t03=time.time()
dt02=(t03-t02)*1000
print("post dt02",dt02)
move_id=get_model("account.move").create(move_vals)
t04=time.time()
dt03=(t04-t03)*1000
print("post dt03",dt03)
get_model("account.move").post([move_id])
t05=time.time()
dt04=(t05-t04)*1000
print("post dt04",dt04)
obj.write({"move_id":move_id,"state":"waiting_payment"})
t06=time.time()
dt05=(t06-t05)*1000
print("post dt05",dt05)
t1=time.time()
dt=(t1-t0)*1000
print("invoice.post <<< %d ms"%dt)
AccountInvoice.register()

View File

@ -8,6 +8,7 @@ class Settings(Model):
"income_account_id": fields.Many2One("account.account","Income Account"),
"ap_nurse_id": fields.Many2One("account.account","Account Payment Nurse"),
"ap_doctor_id": fields.Many2One("account.account","Account Payment Doctor"),
'acc_prod_match': fields.Boolean("Account Product Matching"),
}
def get_default_address(self,ids,context={}):

View File

@ -104,6 +104,7 @@ class HDCase(Model):
dlz_name=','.join([dlz for dlz in dlz_name])
epo_names=[]
mdc_names=[]
iron_names=[]
fee=0
lab=0
misc=0
@ -113,6 +114,7 @@ class HDCase(Model):
for line in obj.lines:
amt=line.amount or 0
prod=line.product_id
prod_name=prod.description or prod.name or ""
categ=line.product_categ_id
if categ and prod:
sign=1
@ -120,24 +122,17 @@ class HDCase(Model):
sign=-1
if categ.parent_id:
if categ.parent_id.code=='MDC':
name=prod.description or prod.name or ""
##name=name.split("-")
#name=name.replace("-SSO","")
#name=name.title()
#name=name[0].title()
if reimbursable_ctx:
if reimbursable_ctx==line.reimbursable:
mdc+=amt
mdc_names.append(name or "")
mdc_names.append(prod_name or "")
else:
mdc+=amt
mdc_names.append(name or "")
if categ.code=='EPO':
name=prod.description or prod.name or ""
#name=name.split("-")
#if name:
#name=name[0].title()
epo_names.append(name.title())
epo_names.append(prod_name.title())
elif categ.code=='IVR':
iron_names.append(prod_name.title())
elif categ.code=='FEE':
fee+=amt*sign
elif categ.code=='DLZ':
@ -158,12 +153,13 @@ class HDCase(Model):
misc+=amt
res[obj.id]={
'epo': ','.join([n for n in epo_names]),
'mdc_name': ','.join([n for n in mdc_names]),
'iron_name': ','.join([n for n in iron_names]),
'fee': fee,
'lab': lab,
'misc': misc,
'mdc': mdc,
'srv': srv,
'mdc_name': ','.join([n for n in mdc_names]),
'dlz_id': dlz_id,
'dlz_price': dlz_price,
'dlz_name': dlz_name,
@ -558,7 +554,6 @@ class HDCase(Model):
}
payment_id=get_model("account.payment").create(vals,context=context)
obj.write({
#'state': 'paid',
'payment_lines': [('create',{
'payment_id': payment_id,
'amount': pay_amount,

View File

@ -45,7 +45,7 @@ class HDCasePayment(Model):
hd_case.post_invoices()
if obj.pay_amount:
hd_case.make_payment(context=context)
hd_case.do_expense()
#hd_case.do_expense()
inv_remain_amount=0
for inv in hd_case.invoices:
@ -82,7 +82,7 @@ class HDCasePayment(Model):
hd_case.make_invoices(context=context)
hd_case.post_invoices()
hd_case.create_cycle_item()
hd_case.do_expense()
#hd_case.do_expense()
hd_case.write({
'state': 'waiting_payment',
'req_fee': 0, # force to hide button pay!

View File

@ -247,12 +247,14 @@ class ReportCycleItem(Model):
epo_items=[{'name': k, 'qty': v} for k,v in epos.items() if k ]
nlines.append({
'sub': 'show',
'is_sub': True,
'sub_txt': 'รวม',
'row_color': '#dfdfdf',
'no': count,
'fee': sub_fee,
'mdc': sub_mdc,
'epo_items': epo_items,
'epo_txt': ', '.join(['%s = %s'%(k,v) for k,v in epos.items() if k])
})
for epo_item in epo_items:
if not total_epos.get(epo_item['name']):
@ -285,6 +287,9 @@ class ReportCycleItem(Model):
})
index+=1
vscl_txt=' '.join(['%s = %s'%(x['description'],x['qty']) for x in vscl_lines])
total_epo_txt=''
for t_epo in total_epo_items:
total_epo_txt+='%s = %s '%(t_epo['name'], t_epo['qty'])
data={
'company_name': company_name or "",
'lines': nlines,
@ -301,6 +306,7 @@ class ReportCycleItem(Model):
'total_pt': total_pt,
'total_epo': sum([x['qty'] for x in total_epo_items]),
'total_epo_items': total_epo_items,
'total_epo_txt': total_epo_txt,
}
return data

View File

@ -13,7 +13,8 @@
<th>ชื่อ-สกุล</th>
<th>แพทย์</th>
<th>สิทธ์</th>
<th style="text-align:left">ยาฉีด</th>
<th style="text-align:left">EPO</th>
<th style="text-align:left">Iron</th>
<th>HCT</th>
<th>DZ</th>
<th>N/U</th>
@ -38,18 +39,19 @@
<td><a href="/ui#name=clinic_staff&active_id={{did}}&mode=form">{{dname}}</a></td>
<td><a href="/ui#name=clinic_patient_type&active_id={{tid}}&mode=form">{{tname}}</a></td>
<td style="text-align:left">{{mdc_name}}</td>
<td style="text-align:left">{{iron_name}}</td>
<td style="text-align:right">{{hct}}</td>
<td><a href="/ui#name=clinic_dialyzer&active_id={{dlz_id}}&mode=form">{{dlz_name}}</a></td>
<td>{{dlz_use}}</td>
<td><a href="/ui#name=clinic_cycle_item&active_id={{ctid}}&mode=form">{{nfirst_name}}</a></td>
{{else}}
{{#ifeq sub "show"}}
<td>ผู้ป่วย | ยาฉีด</td>
<td>รวม</td>
<td></td>
<td style="text-align:center">{{no}}</td>
<td colspan="9">
<td colspan="10">
{{#each epo_items}}
{{name}} : {{qty}} &nbsp;&nbsp;&nbsp;
{{name}} = {{qty}} &nbsp;&nbsp;&nbsp;
{{/each}}
</td>
{{else}}
@ -61,6 +63,7 @@
<td><a href="/ui#name=clinic_staff&active_id={{did}}&mode=form">{{dname}}</a></td>
<td><a href="/ui#name=clinic_patient_type&active_id={{tid}}&mode=form">{{tname}}</a></td>
<td style="text-align:left">{{mdc_name}}</td>
<td style="text-align:left">{{iron_name}}</td>
<td style="text-align:right">{{hct}}</td>
<td><a href="/ui#name=clinic_dialyzer&active_id={{dlz_id}}&mode=form">{{dlz_name}}</a></td>
<td>{{dlz_use}}</td>
@ -73,7 +76,7 @@
<th class="active">ผู้ป่วยทั้งหมด</th>
<th class="active"></th>
<th class="active">{{total_pt}}</th>
<th colspan="9" class="active">
<th colspan="10" class="active">
<p>
{{#each ptype_lines}}
{{name}} : {{qty}} &nbsp;&nbsp;&nbsp;
@ -87,10 +90,10 @@
</th>
</tr>
<tr>
<th class="active">ยาฉีดทั้งหมด</th>
<th class="active">ยาทั้งหมด</th>
<th class="active"></th>
<th class="active">{{total_epo}}</th>
<th colspan="9" class="active">
<th colspan="10" class="active">
<p>
{{#each total_epo_items}}
{{name}} = {{qty}} &nbsp;&nbsp;&nbsp;