merge branch fix account
commit
41626fe43a
|
@ -0,0 +1,6 @@
|
|||
<action>
|
||||
<field name="type">report_odt2</field>
|
||||
<field name="model">account.invoice</field>
|
||||
<field name="method">get_invoice_data</field>
|
||||
<field name="template">cust_invoice</field>
|
||||
</action>
|
|
@ -0,0 +1,8 @@
|
|||
<action>
|
||||
<field name="string">Payment Matching</field>
|
||||
<field name="view_cls">report</field>
|
||||
<field name="model">clinic.payment.matching</field>
|
||||
<field name="report_template">payment_matching</field>
|
||||
<field name="report_template_xls">payment_matching</field>
|
||||
<field name="menu">account_menu</field>
|
||||
</action>
|
|
@ -5,7 +5,6 @@
|
|||
<item string="Account Patient" action="clinic_setting_account_patient"/>
|
||||
<item string="HD Case Expense" action="clinic_report_account_hd_case_summary"/>
|
||||
<item string="RD Shop Expense" action="clinic_report_account_shop"/>
|
||||
<item string="HD Cases Matching" action="clinic_matching_hdcase_acc"/>
|
||||
<item string="Payment Matching" action="clinic_matching_payment"/>
|
||||
<item string="Payment Invoices" action="clinic_invoice_payment"/>
|
||||
<divider/>
|
||||
|
@ -18,6 +17,10 @@
|
|||
<item string="Labor Cost Daily" action="clinic_report_labor_cost_daily"/>
|
||||
<item string="Labor Cost Overtime" action="clinic_report_labor_cost_overtime"/>
|
||||
</item>
|
||||
<item string="Matching">
|
||||
<item string="Payment Matching" action="clinic_payment_matching"/>
|
||||
<item string="HD Cases Matching" action="clinic_matching_hdcase_acc"/>
|
||||
</item>
|
||||
</item>
|
||||
<item string="Financial Settings" position="after">
|
||||
<item string="Ratchawat Settings" action="clinic_account_setting"/>
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<inherit model="account.payment" inherit="payment_form">
|
||||
<field name="default_line_desc" position="before">
|
||||
<field name="rd_cust" span="2"/>
|
||||
</field>
|
||||
</inherit>
|
|
@ -4,7 +4,6 @@
|
|||
<field name="patient_partner_id" span="2"/>
|
||||
</field>
|
||||
<field name="memo" position="after">
|
||||
<field name="account_id" span="2"/>
|
||||
<field name="hdcase_reconcile" span="2"/>
|
||||
<field name="account_id" string="Account Receivable" span="2"/>
|
||||
</field>
|
||||
</inherit>
|
||||
|
|
|
@ -35,7 +35,22 @@
|
|||
<button string="Drop" type="danger" icon="remove" states="active" method="drop"/>
|
||||
</foot>
|
||||
<related>
|
||||
<!--<field name="hd_cases" readonly="1"/>-->
|
||||
<field name="hd_cases_dlz" readonly="1">
|
||||
<list>
|
||||
<field name="hdcase_date"/>
|
||||
<field name="use_time"/>
|
||||
<field name="nurse_id"/>
|
||||
</list>
|
||||
<form>
|
||||
<field name="hd_case_id"/>
|
||||
<field name="membrane_type" span="2"/>
|
||||
<field name="dialyzer_type" span="2"/>
|
||||
<field name="use_time"/>
|
||||
<field name="max_use_time"/>
|
||||
<field name="description"/>
|
||||
</form>
|
||||
</field>
|
||||
<field name="pickings" click_action="view_picking"/>
|
||||
<field name="hd_cases" readonly="1"/>
|
||||
</related>
|
||||
</form>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<inherit inherit="doc_form">
|
||||
<field name="partner_id" position="before">
|
||||
<field name="name"/>
|
||||
</field>
|
||||
</inherit>
|
|
@ -1,10 +1,11 @@
|
|||
<form model="clinic.hd.case" attrs='{"readonly":[["state","in",["cancelled","paid","waiting_payment"]]]}' show_company="1">
|
||||
<head>
|
||||
<field name="state"/>
|
||||
<!--
|
||||
<button string="Print" dropdown="1" icon="print">
|
||||
<!--<item string="Reciept" method="print_receipt"/>-->
|
||||
<item string="Reciept" action="report_clinic_payment_form" action_options="convert=pdf"/>
|
||||
</button>
|
||||
-->
|
||||
<button string="Options" dropdown="1">
|
||||
<item string="New Dialyzer" action="clinic_hd_case_dlz" states="draft,in_progress,waiting_treatment"/>
|
||||
<item string="Drop Dialyzer" method="drop_dlz" confirm="Are you sure?" states="completed"/>
|
||||
|
@ -57,6 +58,7 @@
|
|||
<field name="description"/>
|
||||
</list>
|
||||
</field>
|
||||
<field name="note"/>
|
||||
</group>
|
||||
</tab>
|
||||
<tab string="Expense">
|
||||
|
@ -110,12 +112,9 @@
|
|||
<group span="3" columns="1">
|
||||
</group>
|
||||
</tab>
|
||||
<tab string="Note">
|
||||
<field name="note" nolabel="1"/>
|
||||
</tab>
|
||||
<tab string="Other">
|
||||
<tab string="Approval">
|
||||
<field name="nurse_id" span="4"/>
|
||||
<field name="fee_partner_id" span="4" domain="[['type','=','org']]"/>
|
||||
<!--<field name="fee_partner_id" span="4" domain="[['type','=','org']]"/>-->
|
||||
</tab>
|
||||
</tabs>
|
||||
<foot>
|
||||
|
@ -123,11 +122,14 @@
|
|||
<button string="Done" type="success" perm="clinic_hdcase_done" icon="ok" method="done" states="in_progress"/>
|
||||
<button string="Discard" type="danger" perm="clinic_hdcase_discard" icon="remove" action="clinic_hd_case_distcont" states="in_progress"/>
|
||||
<button string="Claim Expense" type="default" perm="clinic_hdcase_claim" icon="arrow-right" states="completed" method="request_fee" attrs='{"invisible":[["req_fee","=",1]]}'/>
|
||||
<button string="Pay" type="success" perm="clinic_hdcase_pay" icon="ok" method="pay" states="completed,waiting_payment" attrs='{"invisible":[["req_fee","=",0]]}'/>
|
||||
<button string="Pay" type="success" perm="clinic_hdcase_pay" icon="ok" method="pay" states="completed" attrs='{"invisible":[["req_fee","=",0]]}'/>
|
||||
</foot>
|
||||
<related>
|
||||
<field name="invoices" click_action="view_invoice">
|
||||
<list colors='{"#9f9":[["state","=","paid"]]}'>
|
||||
<head>
|
||||
<button string="Print" action="clinic_hdcase_invoice_print" action_options="convert=pdf" icon="print"/>
|
||||
</head>
|
||||
<field name="number"/>
|
||||
<field name="ref"/>
|
||||
<field name="inv_type"/>
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
<field name="pcode" span="3"/>
|
||||
<field name="hcode_id" span="3" attrs='{"required":[["pcode","=","SSO"]],"invisible":[["pcode","!=","SSO"]]}'/>
|
||||
<field name="file" span="3"/>
|
||||
<field name="branch_id" span="2"/>
|
||||
<field name="department_id" span="2"/>
|
||||
<field name="type" invisible="1" span="3"/>
|
||||
<tabs>
|
||||
<tab string="General">
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<form model="clinic.payment.matching">
|
||||
<!--<field name="date" span="2" mode="month"/>-->
|
||||
<group form_layout="stacked">
|
||||
<separator string="Invoice Filter"/>
|
||||
<field name="period_id" onchange="onchange_period" domain='[["state","=","open"]]' span="2"/>
|
||||
<field name="date_from" span="2"/>
|
||||
<field name="date_to" span="2"/>
|
||||
<field name="inv_state" span="2"/>
|
||||
<field name="branch_id" span="2"/>
|
||||
<field name="department_id" domain='[["branch_id","=",branch_id]]' span="2"/>
|
||||
</group>
|
||||
<separator string="Document Mathing"/>
|
||||
<field name="view_type" span="2"/>
|
||||
<button string="Copy Invoice To Payment" icon="arrow-right"/>
|
||||
<group form_layout="stacked" attrs='{"invisible":[["view_type","=","invoice"]]}'>
|
||||
<field name="file_id" span="2"/>
|
||||
<field name="patient_type_id" onchange="onchange_ptype" span="2" attrs='{"required":[["view_type","=","matching"]]}'/>
|
||||
<field name="pcode" span="2" attrs='{"required":[["view_type","=","matching"]]}'/>
|
||||
<field name="hcode_id" span="2" attrs='{"required":[["pcode","=","SSO"]],"invisible":[["pcode","!=","SSO"]]}'/>
|
||||
</group>
|
||||
</form>
|
|
@ -1,8 +1,27 @@
|
|||
<inherit model="product" inherit="product_form">
|
||||
<field name="categ_id" position="after">
|
||||
<field name="patient_types"/>
|
||||
</field>
|
||||
<field name="create_time" position="after">
|
||||
<field name="report_visible"/>
|
||||
</field>
|
||||
<tab string="Other" position="after">
|
||||
<tab string="Ratchawat">
|
||||
<group form_layout="stacked">
|
||||
<separator string="Product View"/>
|
||||
<field name="patient_types" nolabel="1" span="12">
|
||||
<list>
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="default"/>
|
||||
</list>
|
||||
</field>
|
||||
<separator string="Product Account Setting"/>
|
||||
<field name="account_products" nolabel="1">
|
||||
<list>
|
||||
<field name="patient_type_id"/>
|
||||
<field name="ar_debit_id"/>
|
||||
<field name="ar_credit_id"/>
|
||||
<field name="type"/>
|
||||
</list>
|
||||
</field>
|
||||
<separator string="Report HD Case Summary Setting"/>
|
||||
<field name="report_visible"/>
|
||||
</group>
|
||||
</tab>
|
||||
</tab>
|
||||
</inherit>
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
<field name="department_id" domain='[["branch_id","=",branch_id]]' span="3"/>
|
||||
<field name="ptype_id" span="2"/>
|
||||
<field name="walkin" span="2"/>
|
||||
<field name="reimbursable" span="2"/>
|
||||
<field name="cycle_id" span="2"/>
|
||||
<field name="product_id" span="2"/>
|
||||
<field name="reimbursable" span="2"/>
|
||||
<field name="pay_type" attrs='{"invisible":[["reimbursable","=","yes"]]}' span="2"/>
|
||||
</form>
|
||||
|
|
|
@ -10,11 +10,6 @@
|
|||
<separator string="Visit"/>
|
||||
<group form_layout="stacked">
|
||||
<field name="find_dlz"/>
|
||||
<!--
|
||||
<newline/>
|
||||
<field name="auto_gen_visit" string="Next Gen"/>
|
||||
<field name="next_date" span="3"/>
|
||||
-->
|
||||
</group>
|
||||
<separator string="HD Case"/>
|
||||
<group form_layout="stacked">
|
||||
|
@ -38,4 +33,6 @@
|
|||
<separator string="RD Shop"/>
|
||||
<field name="shop_type_id"/>
|
||||
<field name="signature"/>
|
||||
<separator string="Reporting"/>
|
||||
<field name="product_categ_view"/>
|
||||
</form>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<form model="clinic.setting.account.product" show_company="1">
|
||||
<field name="patient_type_id"/>
|
||||
<field name="categ_id"/>
|
||||
<field name="patient_type_id" required="1"/>
|
||||
<field name="categ_id" required="1"/>
|
||||
<field name="product_id" domain='[["categ_id","=",categ_id]]'/>
|
||||
<field name="ar_credit_id" domain='[["type","!=","view"]]'/>
|
||||
<field name="ar_debit_id" domain='[["type","!=","view"]]'/>
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
<field name="bank_name" attrs='{"invisible":[["pay_type","=","credit"]]}' span="2"/>
|
||||
<field name="bank_branch" attrs='{"invisible":[["pay_type","=","credit"]]}' span="2"/>
|
||||
<field name="hd_case_call" invisible="1"/>
|
||||
<field name="shop_categs" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<tabs>
|
||||
<tab string="General">
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<field name="number"/>
|
||||
<field name="date"/>
|
||||
<field name="contact_id"/>
|
||||
<field name="ref"/>
|
||||
<field name="branch_id"/>
|
||||
<!--<field name="ref"/>-->
|
||||
<!--<field name="branch_id"/>-->
|
||||
<field name="department_id"/>
|
||||
<field name="pay_type"/>
|
||||
<field name="user_id"/>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
from . import clinic_setting
|
||||
from . import conv_bal
|
||||
#from . import conv_bal
|
||||
#from . import repost_invoice
|
||||
|
|
|
@ -22,12 +22,18 @@ class Migration(migration.Migration):
|
|||
get_model("conv.bal").import_acc_file([cbv.id],context={})
|
||||
get_model("conv.bal").import_acc([cbv.id],context={})
|
||||
|
||||
cbv.write({
|
||||
'date_fmt': '%d/%m/%Y',
|
||||
'file': 'ar.csv',
|
||||
})
|
||||
print("import sale file (step 2)running ...")
|
||||
get_model("conv.bal").import_sale_file([cbv.id],context={})
|
||||
del_ids=get_model("conv.sale.invoice").search([["conv_id","=",cbv.id]])
|
||||
get_model('conv.sale.invoice').delete(del_ids)
|
||||
for ar_file in ['ar_fee','ar_epo','ar_srv','ar_other']:
|
||||
cbv.write({
|
||||
'date_fmt': '%d/%m/%Y',
|
||||
'file': '%s.csv'%(ar_file),
|
||||
})
|
||||
ctx={
|
||||
'is_append': True,
|
||||
}
|
||||
get_model("conv.bal").import_sale_file([cbv.id],context=ctx)
|
||||
get_model("conv.bal").import_sale([cbv.id],context={})
|
||||
|
||||
print("import purch file (step 3) running ...")
|
||||
|
|
|
@ -9,30 +9,52 @@ class Migration(migration.Migration):
|
|||
def migrate(self):
|
||||
set_active_user(1)
|
||||
set_active_company(1)
|
||||
for hdcase_line in get_model('clinic.hd.case.line').search_browse([['description','=',None]]):
|
||||
prod=hdcase_line.product_id
|
||||
if prod:
|
||||
hdcase_line.write({
|
||||
'description': prod.name,
|
||||
})
|
||||
|
||||
for hdcase in get_model('clinic.hd.case').search_browse([]):
|
||||
dom=[
|
||||
#['department_id','=',2],
|
||||
#['date','>=','2015-08-18'],
|
||||
#['date','<=','2015-08-18'],
|
||||
]
|
||||
hdcase_ids=set()
|
||||
for hdcase in get_model('clinic.hd.case').search_browse(dom):
|
||||
reset=False
|
||||
for inv in hdcase.invoices:
|
||||
if inv.state=='waiting_payment':
|
||||
print('hdcase:repost ---> ', inv.number)
|
||||
inv.to_draft()
|
||||
if inv.state=='paid':
|
||||
inv.write({
|
||||
'hdcase_reconcile': True,
|
||||
'state': 'waiting_payment',
|
||||
})
|
||||
inv.post()
|
||||
for shop in get_model('clinic.shop').search_browse([]):
|
||||
for inv in shop.invoices:
|
||||
print('shop:repost ---> ', inv.number)
|
||||
inv.to_draft()
|
||||
inv.write({
|
||||
'hdcase_reconcile': True,
|
||||
})
|
||||
inv.post()
|
||||
for pm_line in get_model("account.payment.line").search_browse([['invoice_id','=',inv.id]]):
|
||||
pm=pm_line.payment_id
|
||||
pm.to_draft()
|
||||
pm.delete()
|
||||
inv.to_draft()
|
||||
inv.delete()
|
||||
elif inv.state=='waiting_payment':
|
||||
inv.to_draft()
|
||||
inv.delete()
|
||||
reset=True
|
||||
hdcase_ids.update({hdcase.id})
|
||||
if reset:
|
||||
for line in hdcase.lines:
|
||||
line.write({
|
||||
'state': 'draft',
|
||||
})
|
||||
ids=list(hdcase_ids)
|
||||
|
||||
for seq in get_model("sequence").search_browse([['type','in',['cust_invoice','clinic_invoice_noclaim']]]):
|
||||
for run in seq.running:
|
||||
run.delete()
|
||||
dom2=[
|
||||
['date','>=','2015-07-01'],
|
||||
['state','=','waiting_payment'],
|
||||
]
|
||||
#for hdcase in get_model('clinic.hd.case').browse(ids):
|
||||
for hdcase in get_model('clinic.hd.case').search_browse(dom2):
|
||||
print('remake_invoice ---> ', hdcase.number)
|
||||
ctx={
|
||||
'is_migrate': True,
|
||||
}
|
||||
hdcase.make_invoices(context=ctx)
|
||||
hdcase.post_invoices()
|
||||
print("Done!")
|
||||
return True
|
||||
|
||||
|
|
|
@ -51,9 +51,7 @@ from . import gen_visit_line
|
|||
from . import gen_visit_time
|
||||
from . import payment
|
||||
from . import account_payment
|
||||
from . import account_payment_line
|
||||
from . import account_invoice
|
||||
from . import account_invoice_line
|
||||
from . import staff
|
||||
from . import staff_categ
|
||||
from . import staff_level
|
||||
|
@ -144,3 +142,5 @@ from . import conv_bal
|
|||
from . import conv_sale_invoice
|
||||
from . import account_move_line
|
||||
from . import invoice_payment
|
||||
from . import document
|
||||
from . import payment_matching
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
import time
|
||||
|
||||
from netforce.model import Model, fields, get_model
|
||||
from netforce.utils import get_file_path
|
||||
from netforce.access import get_active_company, get_active_user
|
||||
|
||||
from . import utils
|
||||
|
||||
class AccountInvoice(Model):
|
||||
_inherit="account.invoice"
|
||||
|
||||
def _get_patient(self,ids,context={}):
|
||||
res={}
|
||||
for obj in self.browse(ids):
|
||||
pt_id=None
|
||||
if obj.patient_partner_id:
|
||||
for pt in get_model('clinic.patient').search_browse([['partner_id','=',obj.patient_partner_id.id]]):
|
||||
pt_id=pt.id
|
||||
res[obj.id]=pt_id
|
||||
return res
|
||||
|
||||
_fields={
|
||||
'clinic_expense_id': fields.Many2One("clinic.hd.case.expense","Expense"),
|
||||
'department_id': fields.Many2One("clinic.department","Department",search=True),
|
||||
'patient_partner_id': fields.Many2One("partner","Patient",search=True),
|
||||
'hdcase_credit': fields.Boolean("HD Case Credit"),
|
||||
'hdcase_reconcile': fields.Boolean("HD Case Reconcile"),
|
||||
'patient_partner_id': fields.Many2One("partner","Partner Patient",search=True),
|
||||
'patient_id': fields.Many2One("clinic.patient","Patient",function="_get_patient", store=True,search=True),
|
||||
}
|
||||
|
||||
def _get_number(self,context={}):
|
||||
|
@ -97,7 +111,9 @@ class AccountInvoice(Model):
|
|||
sign=obj.type=="out" and 1 or -1
|
||||
if obj.inv_type=="credit":
|
||||
sign*=-1
|
||||
obj.write({"account_id": account_id})
|
||||
#XXX ratchawat
|
||||
if not obj.patient_partner_id:
|
||||
obj.write({"account_id": account_id})
|
||||
if obj.type=="out":
|
||||
desc="Sale; "+partner.name
|
||||
elif obj.type=="in":
|
||||
|
@ -239,71 +255,29 @@ class AccountInvoice(Model):
|
|||
else:
|
||||
line["debit"]=0
|
||||
line["credit"]=-amt
|
||||
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,
|
||||
}
|
||||
|
||||
is_match=False
|
||||
if obj.hdcase_reconcile 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']
|
||||
if not desc:
|
||||
print("skip no description ", obj.number)
|
||||
continue
|
||||
ar_debit_id=None
|
||||
#ar_credit_id=None
|
||||
# search from patient_type
|
||||
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
|
||||
|
||||
# search from patient
|
||||
if not ar_debit_id:
|
||||
for pt in get_model('clinic.patient').search_browse([['partner_id','=',partner.id]]):
|
||||
acc=prod_acc(prod_id,pt.type_id.id,'credit')
|
||||
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), partner.id, partner.name)
|
||||
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]
|
||||
#XXX ratchawat: get receive account from invoice directly
|
||||
if obj.patient_partner_id:
|
||||
line_vals['account_id']=obj.account_id.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)
|
||||
|
@ -323,4 +297,134 @@ class AccountInvoice(Model):
|
|||
dt=(t1-t0)*1000
|
||||
print("invoice.post <<< %d ms"%dt)
|
||||
|
||||
|
||||
|
||||
def get_invoice_data(self,ids,context={}):
|
||||
settings=get_model('settings').browse(1)
|
||||
pages=[]
|
||||
for obj in self.browse(ids):
|
||||
context['refer_id']=obj.id
|
||||
data=self.get_invoice_page(context=context)
|
||||
limit_item=10
|
||||
if data['state']=='draft':
|
||||
limit_item-=3
|
||||
for i in range(len(data['lines']),limit_item):
|
||||
data['lines'].append({
|
||||
'no': '',
|
||||
'product_name': '',
|
||||
'description': '',
|
||||
'uom_name': '',
|
||||
'qty': None,
|
||||
'price': None,
|
||||
'amount': None,
|
||||
})
|
||||
pages.append(data)
|
||||
if pages:
|
||||
pages[-1]["is_last_page"]=True
|
||||
return {
|
||||
"pages": pages,
|
||||
"logo": get_file_path(settings.logo),
|
||||
}
|
||||
|
||||
def get_invoice_page(self,context={}):
|
||||
if not context.get('refer_id'):
|
||||
return {}
|
||||
inv_id=int(context['refer_id'])
|
||||
inv=self.browse(inv_id)
|
||||
comp_id=get_active_company()
|
||||
comp=get_model('company').browse(comp_id)
|
||||
cust=inv.partner_id
|
||||
cust_tax_no=cust.tax_no or ''
|
||||
cust_name=cust.name or ''
|
||||
cust_addr=''
|
||||
if cust.addresses:
|
||||
cust_addr=cust.addresses[0].address_text
|
||||
if 'your' in cust_addr:
|
||||
cust_addr=''
|
||||
dpt=inv.department_id
|
||||
branch_id=None
|
||||
if dpt:
|
||||
branch_id=dpt.branch_id.id
|
||||
elif inv.patient_partner_id:
|
||||
for pt in get_model('clinic.patient').search_read([['partner_id','=',inv.patient_partner_id.id]],['branch_id']):
|
||||
if pt.get("branch_id"):
|
||||
branch_id=pt['branch_id'][0]
|
||||
context['branch_id']=branch_id
|
||||
st=get_model('settings').browse(1,context=context)
|
||||
cst=get_model('clinic.setting').browse(1)
|
||||
no=1
|
||||
sub_total=0
|
||||
amount_total=0
|
||||
lines=[]
|
||||
for line in inv.lines:
|
||||
amt=line.amount or 0
|
||||
prod=line.product_id
|
||||
lines.append({
|
||||
'no': no,
|
||||
'product_name': prod.name or '',
|
||||
'description': line.description or '',
|
||||
'uom_name': prod.uom_id.name or '',
|
||||
'qty': line.qty or 0,
|
||||
'price': line.price or 0,
|
||||
'amount': amt,
|
||||
})
|
||||
sub_total+=amt
|
||||
no+=1
|
||||
amount_total=sub_total
|
||||
is_draft=inv.state=='draft' and True or False
|
||||
is_cheque=False
|
||||
user_id=get_active_user()
|
||||
user=get_model("base.user").browse(user_id)
|
||||
comp_name=comp.name or ""
|
||||
if st.default_address_id.company:
|
||||
comp_name=st.default_address_id.company or ""
|
||||
payment_terms=''
|
||||
currency_code=''
|
||||
due_date=inv.due_date
|
||||
number=inv.number or ""
|
||||
ref=inv.ref or ""
|
||||
payment_terms=inv.payment_terms or ""
|
||||
currency_code=inv.currency_id.code or ""
|
||||
due_date=inv.due_date
|
||||
add=st.default_address_id
|
||||
data={
|
||||
'partner_name': cust_name,
|
||||
'partner_address': cust_addr,
|
||||
'partner_tax_no': cust_tax_no,
|
||||
'due_date': due_date,
|
||||
'currency_code': currency_code,
|
||||
'payment_terms': payment_terms,
|
||||
'comp_name': comp_name,
|
||||
'add_address': add.address or '',
|
||||
'add_address2': add.address2 or '',
|
||||
'add_province_name': add.province_id.name or '',
|
||||
'add_district_name': add.district_id.name or '',
|
||||
'add_subdistrict_name': add.subdistrict_id.name or '',
|
||||
'add_city': add.city or '',
|
||||
'add_postal_code': add.postal_code or '',
|
||||
'add_phone': add.phone or '',
|
||||
'add_fax': add.fax or '',
|
||||
'tax_no': st.tax_no or '',
|
||||
'number': number,
|
||||
'ref': ref,
|
||||
'date': inv.date,
|
||||
'datenow': inv.date or time.strftime("%d/%m/%Y"),
|
||||
'dateprint': inv.date or time.strftime("%d/%m/%Y %H:%M:%S"),
|
||||
'note': inv.note or '',
|
||||
'lines':lines,
|
||||
'amount_subtotal': sub_total,
|
||||
'amount_total': amount_total,
|
||||
'total_text': utils.num2word(amount_total),
|
||||
'is_cheque': is_cheque,
|
||||
'is_draft': is_draft,
|
||||
'user_name': user.name or "",
|
||||
'state': inv.state or "",
|
||||
}
|
||||
data['pay_type']='Credit'
|
||||
if st.logo:
|
||||
data['logo']=get_file_path(st.logo)
|
||||
if cst.signature:
|
||||
data['signature']=get_file_path(cst.signature)
|
||||
return data
|
||||
|
||||
AccountInvoice.register()
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import time
|
||||
|
||||
from netforce.model import Model, fields, get_model
|
||||
|
||||
class AccountInvoiceLine(Model):
|
||||
_inherit="account.invoice.line"
|
||||
_fields={
|
||||
'ar_credit_id': fields.Many2One("account.account","Account Credit"),
|
||||
"ar_debit_id": fields.Many2One("account.account","Account Debit"),
|
||||
}
|
||||
|
||||
|
||||
AccountInvoiceLine.register()
|
|
@ -6,7 +6,6 @@ from netforce.model import Model, fields, get_model
|
|||
class AccountPayment(Model):
|
||||
_inherit="account.payment"
|
||||
_fields={
|
||||
'rd_cust': fields.Boolean("RD Customize"),
|
||||
'number': fields.Char("Number",required=True,search=True),
|
||||
}
|
||||
|
||||
|
@ -48,567 +47,8 @@ class AccountPayment(Model):
|
|||
'name': 'report_clinic_payment_form',
|
||||
'refer_id': hd_case_id,
|
||||
'payment_id': obj.id,
|
||||
'convert': 'pdf',
|
||||
},
|
||||
}
|
||||
|
||||
def import_payment(self,ids,context={}):
|
||||
if not ids:
|
||||
raise Exception("Please save payment before import")
|
||||
return {
|
||||
'next': {
|
||||
'name': 'clinic_import_uc',
|
||||
'refer_id': ids[0], #XXX
|
||||
}
|
||||
}
|
||||
|
||||
def clinic_post(self,ids,context={}):
|
||||
print("account_payment.post")
|
||||
obj=self.browse(ids)[0]
|
||||
settings=get_model("settings").browse(1)
|
||||
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 or 1)
|
||||
obj.write({"currency_rate":currency_rate})
|
||||
if obj.pay_type=="direct":
|
||||
desc=obj.memo or obj.ref or obj.partner_id.name or obj.number # XXX: as in myob?
|
||||
elif obj.pay_type=="invoice":
|
||||
desc=obj.memo or "Payment; %s"%obj.partner_id.name # XXX: as in myob?
|
||||
elif obj.pay_type=="prepay":
|
||||
desc="Prepayment: %s"%obj.partner_id.name
|
||||
elif obj.pay_type=="overpay":
|
||||
desc="Overpayment: %s"%obj.partner_id.name
|
||||
elif obj.pay_type=="refund":
|
||||
desc="Refund: %s"%obj.partner_id.name
|
||||
elif obj.pay_type=="claim":
|
||||
desc="Expense claim payment"
|
||||
elif obj.pay_type=="adjust":
|
||||
desc="Adjustment"
|
||||
else:
|
||||
desc="Payment: %s"%obj.partner_id.name
|
||||
if obj.type=="in":
|
||||
journal_id=settings.pay_in_journal_id.id
|
||||
if not journal_id:
|
||||
raise Exception("Receipts journal not found")
|
||||
elif obj.type=="out":
|
||||
journal_id=settings.pay_out_journal_id.id
|
||||
if not journal_id:
|
||||
raise Exception("Disbursements journal not found")
|
||||
if not obj.number:
|
||||
raise Exception("Missing payment number")
|
||||
move_vals={
|
||||
"journal_id": journal_id,
|
||||
"number": obj.number,
|
||||
"date": obj.date,
|
||||
"narration": desc,
|
||||
"related_id": "account.payment,%s"%obj.id,
|
||||
"company_id": obj.company_id.id,
|
||||
}
|
||||
move_id=get_model("account.move").create(move_vals)
|
||||
lines=[]
|
||||
track_id=None
|
||||
for line in obj.lines: # XXX
|
||||
if line.track_id:
|
||||
if track_id:
|
||||
track_id=None
|
||||
break
|
||||
else:
|
||||
track_id=line.track_id.id
|
||||
amt=get_model("currency").convert(obj.amount_payment,obj.currency_id.id,settings.currency_id.id,rate=currency_rate)
|
||||
if obj.type=="out":
|
||||
amt=-amt
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"account_id": obj.account_id.id,
|
||||
"description": desc,
|
||||
"track_id": track_id,
|
||||
"debit": amt>0 and amt or 0,
|
||||
"credit": amt<0 and -amt or 0,
|
||||
}
|
||||
if obj.account_id.currency_id.id!=settings.currency_id.id:
|
||||
if obj.account_id.currency_id.id!=obj.currency_id.id:
|
||||
raise Exception("Invalid account currency for this payment: %s"%obj.account_id.code)
|
||||
line_vals["amount_cur"]=obj.amount_payment if obj.type=="in" else -obj.amount_payment
|
||||
get_model("account.move.line").create(line_vals)
|
||||
taxes={}
|
||||
reconcile_ids=[]
|
||||
total_over=0
|
||||
for line in obj.lines:
|
||||
if line.type in ("direct","prepay"):
|
||||
cur_amt=get_model("currency").convert(line.amount,obj.currency_id.id,settings.currency_id.id,rate=currency_rate)
|
||||
tax=line.tax_id
|
||||
if tax 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="direct_payment")
|
||||
for comp_id,tax_amt in tax_comps.items():
|
||||
if comp_id in taxes:
|
||||
tax_vals=taxes[comp_id]
|
||||
tax_vals["amount_base"]+=base_amt
|
||||
tax_vals["amount_tax"]+=tax_amt
|
||||
else:
|
||||
tax_vals={
|
||||
"tax_comp_id": comp_id,
|
||||
"amount_base": base_amt,
|
||||
"amount_tax": tax_amt,
|
||||
}
|
||||
taxes[comp_id]=tax_vals
|
||||
else:
|
||||
base_amt=cur_amt
|
||||
if obj.type=="out":
|
||||
amt=base_amt
|
||||
else:
|
||||
amt=-base_amt
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": line.description or desc,
|
||||
"account_id": line.account_id.id,
|
||||
"debit": amt>0 and amt or 0,
|
||||
"credit": amt<0 and -amt or 0,
|
||||
"track_id": line.track_id.id,
|
||||
"track2_id": line.track2_id.id,
|
||||
}
|
||||
print("direct")
|
||||
pprint(line_vals)
|
||||
get_model("account.move.line").create(line_vals)
|
||||
elif line.type in ("invoice","refund"):
|
||||
inv=line.invoice_id
|
||||
inv_taxes={}
|
||||
if inv.inv_type in ("invoice","credit","debit"):
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": inv.account_id.id,
|
||||
"due_date": inv.due_date,
|
||||
"partner_id": inv.partner_id.id,
|
||||
}
|
||||
if line.amount_currency>inv.amount_due:
|
||||
pay_amt=inv.amount_due
|
||||
over_amt=line.amount_currency-inv.amount_due
|
||||
total_over+=get_model("currency").convert(over_amt,inv.currency_id.id,settings.currency_id.id,rate=inv.currency_rate)
|
||||
else:
|
||||
pay_amt=line.amount_currency
|
||||
pay_ratio=pay_amt/inv.amount_total
|
||||
inv_amt=inv.amount_total*pay_ratio
|
||||
cur_inv_amt=get_model("currency").convert(inv_amt,inv.currency_id.id,settings.currency_id.id,rate=inv.currency_rate)
|
||||
if obj.type=="out":
|
||||
amt=cur_inv_amt
|
||||
else:
|
||||
amt=-cur_inv_amt
|
||||
if amt>0:
|
||||
line_vals["debit"]=amt
|
||||
else:
|
||||
line_vals["credit"]=-amt
|
||||
if inv.account_id.currency_id.id!=settings.currency_id.id:
|
||||
if obj.type=="out":
|
||||
line_vals["amount_cur"]=inv_amt
|
||||
else:
|
||||
line_vals["amount_cur"]=-inv_amt
|
||||
print("invoice")
|
||||
pprint(line_vals)
|
||||
pay_line_id=get_model("account.move.line").create(line_vals)
|
||||
if inv.reconcile_move_line_id:
|
||||
inv_line_id=inv.reconcile_move_line_id.id
|
||||
elif inv.move_id: # XXX
|
||||
inv_line_id=inv.move_id.lines[0].id
|
||||
else:
|
||||
inv_line_id=None
|
||||
if inv_line_id:
|
||||
reconcile_ids.append([pay_line_id,inv_line_id])
|
||||
for invline in inv.lines:
|
||||
tax=invline.tax_id
|
||||
if tax and inv.tax_type!="no_tax": # XXX: simplify this
|
||||
cur_line_amt_inv=get_model("currency").convert(invline.amount*pay_ratio,inv.currency_id.id,settings.currency_id.id,rate=inv.currency_rate)
|
||||
base_amt=get_model("account.tax.rate").compute_base(tax.id,cur_line_amt_inv,tax_type=inv.tax_type)
|
||||
tax_comps=get_model("account.tax.rate").compute_taxes(tax.id,base_amt,when="invoice_payment_inv")
|
||||
for comp_id,tax_amt in tax_comps.items():
|
||||
if comp_id in inv_taxes:
|
||||
tax_vals=inv_taxes[comp_id]
|
||||
tax_vals["amount_base"]+=base_amt
|
||||
tax_vals["amount_tax"]+=tax_amt
|
||||
else:
|
||||
tax_vals={
|
||||
"tax_comp_id": comp_id,
|
||||
"amount_base": base_amt,
|
||||
"amount_tax": tax_amt,
|
||||
}
|
||||
inv_taxes[comp_id]=tax_vals
|
||||
cur_line_amt_pmt=get_model("currency").convert(invline.amount*pay_ratio,inv.currency_id.id,settings.currency_id.id,rate=inv.currency_rate) # XXX: check this
|
||||
base_amt=get_model("account.tax.rate").compute_base(tax.id,cur_line_amt_pmt,tax_type=inv.tax_type)
|
||||
tax_comps=get_model("account.tax.rate").compute_taxes(tax.id,base_amt,when="invoice_payment_pmt")
|
||||
for comp_id,tax_amt in tax_comps.items():
|
||||
if comp_id in inv_taxes:
|
||||
tax_vals=inv_taxes[comp_id]
|
||||
tax_vals["amount_base"]+=base_amt
|
||||
tax_vals["amount_tax"]+=tax_amt
|
||||
else:
|
||||
tax_vals={
|
||||
"tax_comp_id": comp_id,
|
||||
"amount_base": base_amt,
|
||||
"amount_tax": tax_amt,
|
||||
}
|
||||
inv_taxes[comp_id]=tax_vals
|
||||
elif inv.inv_type=="overpay":
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": inv.account_id.id,
|
||||
"partner_id": inv.partner_id.id,
|
||||
}
|
||||
amt=line.amount
|
||||
if obj.type=="out":
|
||||
line_vals["debit"]=amt
|
||||
else:
|
||||
line_vals["credit"]=amt
|
||||
print("overpay")
|
||||
pprint(line_vals)
|
||||
get_model("account.move.line").create(line_vals)
|
||||
elif inv.inv_type=="prepay":
|
||||
for oline in inv.lines:
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": oline.account_id.id,
|
||||
}
|
||||
amt=oline.amount*line.amount/inv.amount_total # XXX: currency
|
||||
tax=oline.tax_id
|
||||
if tax:
|
||||
base_amt=get_model("account.tax.rate").compute_base(tax.id,amt,tax_type=inv.tax_type)
|
||||
else:
|
||||
base_amt=amt
|
||||
if obj.type=="out":
|
||||
line_vals["debit"]=base_amt
|
||||
else:
|
||||
line_vals["credit"]=base_amt
|
||||
print("prepay")
|
||||
pprint(line_vals)
|
||||
get_model("account.move.line").create(line_vals)
|
||||
if tax and inv.tax_type!="no_tax":
|
||||
tax_comps=get_model("account.tax.rate").compute_taxes(tax.id,base_amt,when="invoice") # XXX
|
||||
for comp_id,tax_amt in tax_comps.items():
|
||||
if comp_id in inv_taxes:
|
||||
tax_vals=inv_taxes[comp_id]
|
||||
tax_vals["amount_base"]+=base_amt
|
||||
tax_vals["amount_tax"]+=tax_amt
|
||||
else:
|
||||
tax_vals={
|
||||
"tax_comp_id": comp_id,
|
||||
"amount_base": base_amt,
|
||||
"amount_tax": tax_amt,
|
||||
}
|
||||
inv_taxes[comp_id]=tax_vals
|
||||
for comp_id,inv_tax_vals in inv_taxes.items():
|
||||
comp=get_model("account.tax.component").browse(comp_id)
|
||||
if comp.type in ("vat","vat_defer"):
|
||||
acc_id=comp.account_id.id
|
||||
if not acc_id:
|
||||
raise Exception("Missing account for tax component %s"%comp.name)
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": acc_id,
|
||||
"tax_comp_id": comp_id,
|
||||
"tax_base": inv_tax_vals["amount_base"],
|
||||
"partner_id": obj.partner_id.id,
|
||||
"invoice_id": inv.id,
|
||||
}
|
||||
if comp.type=="vat":
|
||||
if inv.type=="out":
|
||||
if line.tax_no:
|
||||
tax_no=line.tax_no
|
||||
else:
|
||||
tax_no=get_model("account.invoice").gen_tax_no(context={"date":obj.date})
|
||||
line.write({"tax_no":tax_no})
|
||||
line_vals["tax_no"]=tax_no
|
||||
elif inv.type=="in":
|
||||
line_vals["tax_no"]=line.tax_no
|
||||
amt=inv_tax_vals["amount_tax"]
|
||||
if obj.type=="in":
|
||||
amt=-amt
|
||||
if amt>0:
|
||||
line_vals["debit"]=amt
|
||||
else:
|
||||
line_vals["credit"]=-amt
|
||||
print("tax")
|
||||
pprint(line_vals)
|
||||
get_model("account.move.line").create(line_vals)
|
||||
elif comp.type=="wht":
|
||||
if comp_id in taxes:
|
||||
tax_vals=taxes[comp_id]
|
||||
tax_vals["amount_base"]+=inv_tax_vals["amount_base"]
|
||||
tax_vals["amount_tax"]+=inv_tax_vals["amount_tax"]
|
||||
else:
|
||||
taxes[comp_id]=inv_tax_vals.copy()
|
||||
elif line.type=="claim":
|
||||
expense=line.expense_id
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": settings.unpaid_claim_id.id,
|
||||
}
|
||||
amt=line.amount
|
||||
if obj.type=="out":
|
||||
line_vals["debit"]=amt
|
||||
else:
|
||||
line_vals["credit"]=amt
|
||||
print("claim")
|
||||
pprint(line_vals)
|
||||
get_model("account.move.line").create(line_vals)
|
||||
elif line.type=="adjust":
|
||||
cur_amt=get_model("currency").convert(line.amount,obj.currency_id.id,settings.currency_id.id,rate=currency_rate)
|
||||
tax_base=get_model("currency").convert(line.tax_base or 0,obj.currency_id.id,settings.currency_id.id,rate=currency_rate)
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": line.account_id.id,
|
||||
"tax_comp_id": line.tax_comp_id.id,
|
||||
"tax_base": tax_base,
|
||||
"track_id": line.track_id.id,
|
||||
"partner_id": obj.partner_id.id,
|
||||
}
|
||||
if obj.type=="in":
|
||||
cur_amt=-cur_amt
|
||||
if cur_amt>0:
|
||||
line_vals["debit"]=cur_amt
|
||||
else:
|
||||
line_vals["credit"]=-cur_amt
|
||||
print("adjust")
|
||||
pprint(line_vals)
|
||||
get_model("account.move.line").create(line_vals)
|
||||
if total_over>0.01:
|
||||
partner=obj.partner_id
|
||||
if obj.type=="in":
|
||||
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=="out":
|
||||
account_id=partner.account_payable_id.id or settings.account_payable_id.id
|
||||
if not account_id:
|
||||
raise Exception("Account payable not found")
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": context.get("overpay_description",""),
|
||||
"account_id": account_id,
|
||||
"track_id": line.track_id.id,
|
||||
"partner_id": obj.partner_id.id,
|
||||
}
|
||||
if obj.type=="out":
|
||||
line_vals["debit"]=total_over
|
||||
else:
|
||||
line_vals["credit"]=total_over
|
||||
print("overpay")
|
||||
pprint(line_vals)
|
||||
get_model("account.move.line").create(line_vals)
|
||||
inv_line_vals={
|
||||
"description": context.get("overpay_description",""),
|
||||
"account_id": account_id,
|
||||
"amount": total_over,
|
||||
}
|
||||
inv_vals={
|
||||
"type": obj.type=="in" and "out" or "in",
|
||||
"inv_type": "overpay",
|
||||
"partner_id": obj.partner_id.id,
|
||||
"date": obj.date,
|
||||
"tax_type": "no_tax",
|
||||
"lines": [("create",inv_line_vals)],
|
||||
"state": "waiting_payment",
|
||||
"payment_id": obj.id,
|
||||
"account_id": account_id,
|
||||
}
|
||||
inv_id=get_model("account.invoice").create(inv_vals)
|
||||
wht_no=get_model("account.payment").gen_wht_no(context={"date":obj.date})
|
||||
for comp_id,tax_vals in sorted(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)
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": acc_id,
|
||||
"tax_comp_id": comp_id,
|
||||
"tax_base": tax_vals["amount_base"],
|
||||
"partner_id": obj.partner_id.id,
|
||||
}
|
||||
if comp.type=="vat":
|
||||
if obj.type=="in":
|
||||
if obj.tax_no:
|
||||
tax_no=obj.tax_no
|
||||
else:
|
||||
tax_no=get_model("account.invoice").gen_tax_no(context={"date":obj.date})
|
||||
obj.write({"tax_no":tax_no})
|
||||
line_vals["tax_no"]=tax_no
|
||||
elif obj.type=="out":
|
||||
line_vals["tax_no"]=obj.tax_no
|
||||
elif comp.type=="wht":
|
||||
if obj.type=="out":
|
||||
# 1 Payment should have same wht_no
|
||||
#wht_no=get_model("account.payment").gen_wht_no(context={"date":obj.date})
|
||||
line_vals["tax_no"]=wht_no
|
||||
amt=tax_vals["amount_tax"]
|
||||
if obj.type=="in":
|
||||
amt=-amt
|
||||
if amt>0:
|
||||
line_vals["debit"]=amt
|
||||
else:
|
||||
line_vals["credit"]=-amt
|
||||
print("tax")
|
||||
pprint(line_vals)
|
||||
get_model("account.move.line").create(line_vals)
|
||||
amt=0
|
||||
move=get_model("account.move").browse(move_id)
|
||||
for line in move.lines:
|
||||
amt+=line.credit-line.debit
|
||||
if amt>0.001:
|
||||
if not settings.currency_loss_id:
|
||||
raise Exception("Missing currency loss account")
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": settings.currency_loss_id.id,
|
||||
"debit": amt,
|
||||
"credit": 0,
|
||||
}
|
||||
get_model("account.move.line").create(line_vals)
|
||||
elif amt<-0.001:
|
||||
if not settings.currency_gain_id:
|
||||
raise Exception("Missing currency gain account")
|
||||
line_vals={
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": settings.currency_loss_id.id,
|
||||
"debit": 0,
|
||||
"credit": -amt,
|
||||
}
|
||||
get_model("account.move.line").create(line_vals)
|
||||
get_model("account.move").post([move_id])
|
||||
obj.write({"move_id":move_id,"state":"posted"})
|
||||
for rec_lines in reconcile_ids:
|
||||
get_model("account.move.line").reconcile(rec_lines,context=context)
|
||||
obj.create_prepay_invoice()
|
||||
|
||||
def post(self,ids,context={}):
|
||||
obj=self.browse(ids)[0]
|
||||
res=None
|
||||
hdcase_reconcile=context.get('hdcase_reconcile')
|
||||
if hdcase_reconcile and obj.pay_type=="invoice":
|
||||
obj.clinic_post(context=context)
|
||||
elif obj.rd_cust:
|
||||
res={}
|
||||
print("RD Customize")
|
||||
desc="Recieved %s"%obj.partner_id.name
|
||||
for ivline in obj.invoice_lines:
|
||||
invoice=ivline.invoice_id
|
||||
partner_id=invoice.partner_id.id
|
||||
for mline in invoice.move_id.lines:
|
||||
if mline.debit>0:
|
||||
amt=mline.debit or 0
|
||||
account_id=mline.account_id.id
|
||||
if not res.get(account_id):
|
||||
res[account_id]={
|
||||
'credit': 0,
|
||||
'debit': 0,
|
||||
'description': desc,
|
||||
'partner_id': partner_id
|
||||
}
|
||||
res[account_id]['credit']+=amt
|
||||
settings=get_model("settings").browse(1)
|
||||
if obj.type=="in":
|
||||
journal_id=obj.journal_id.id or settings.pay_in_journal_id.id
|
||||
if not journal_id:
|
||||
raise Exception("Receipts journal not found")
|
||||
elif obj.type=="out":
|
||||
journal_id=obj.journal_id.id or settings.pay_out_journal_id.id
|
||||
if not journal_id:
|
||||
raise Exception("Disbursements journal not found")
|
||||
if not obj.number:
|
||||
raise Exception("Missing payment number")
|
||||
move_vals={
|
||||
"journal_id": journal_id,
|
||||
"number": obj.number,
|
||||
"date": obj.date,
|
||||
"narration": desc,
|
||||
"related_id": "account.payment,%s"%obj.id,
|
||||
"company_id": obj.company_id.id,
|
||||
}
|
||||
move_id=get_model("account.move").create(move_vals)
|
||||
track_id=None
|
||||
for line in obj.lines: # XXX
|
||||
if line.track_id:
|
||||
if track_id:
|
||||
track_id=None
|
||||
break
|
||||
else:
|
||||
track_id=line.track_id.id
|
||||
lines1=[]
|
||||
lines1.append(('create',{
|
||||
"move_id": move_id,
|
||||
"account_id": obj.account_id.id,
|
||||
"description": desc,
|
||||
"track_id": track_id,
|
||||
'debit': 0,
|
||||
'credit':0,
|
||||
}))
|
||||
lines2=[]
|
||||
for account_id, rvals in res.items():
|
||||
amt=rvals['credit'] or 0
|
||||
lines1[0][1]['debit']+=amt #XXX
|
||||
lines2.append(('create',{
|
||||
"move_id": move_id,
|
||||
"account_id": account_id,
|
||||
"description": rvals['description'],
|
||||
'partner_id': rvals['partner_id'],
|
||||
'debit': rvals['debit'],
|
||||
'credit': rvals['credit'],
|
||||
"track_id": track_id,
|
||||
}))
|
||||
|
||||
if obj.type=="in":
|
||||
rate_type="sell"
|
||||
else:
|
||||
rate_type="buy"
|
||||
adjust_lines=[]
|
||||
adjust_amt=0
|
||||
for jline in obj.adjust_lines:
|
||||
cur_amt=get_model("currency").convert(line.amount,obj.currency_id.id,settings.currency_id.id,date=obj.date,rate_type=rate_type)
|
||||
tax_base=get_model("currency").convert(line.tax_base or 0,obj.currency_id.id,settings.currency_id.id,date=obj.date,rate_type=rate_type)
|
||||
cur_amt=abs(cur_amt)
|
||||
adjust_lines.append(('create',{
|
||||
"move_id": move_id,
|
||||
"description": desc,
|
||||
"account_id": line.account_id.id,
|
||||
"tax_comp_id": line.tax_comp_id.id,
|
||||
"tax_base": tax_base,
|
||||
"track_id": line.track_id.id,
|
||||
"partner_id": obj.partner_id.id,
|
||||
"credit":0,
|
||||
"debit": cur_amt,
|
||||
}))
|
||||
#XXX
|
||||
adjust_amt+=cur_amt
|
||||
lines1[0][1]['debit']-=cur_amt
|
||||
|
||||
lines=lines1+adjust_lines+lines2 #debit, debit, credit
|
||||
move=get_model("account.move").browse(move_id)
|
||||
move.write({
|
||||
'lines': lines,
|
||||
})
|
||||
move.post()
|
||||
obj.write({
|
||||
'move_id': move.id,
|
||||
'state': 'posted',
|
||||
})
|
||||
print("Done!")
|
||||
else:
|
||||
res=super().post(ids,context=context)
|
||||
return res
|
||||
|
||||
AccountPayment.register()
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import time
|
||||
|
||||
from netforce.model import Model, fields, get_model
|
||||
|
||||
class AccountPaymentLine(Model):
|
||||
_inherit="account.payment.line"
|
||||
_fields={
|
||||
'ar_credit_id': fields.Many2One("account.account","Account Credit"), # no long use
|
||||
"ar_debit_id": fields.Many2One("account.account","Account Debit"), # no long use
|
||||
}
|
||||
|
||||
|
||||
AccountPaymentLine.register()
|
|
@ -54,7 +54,7 @@ class ConvBal(Model):
|
|||
else:
|
||||
get_model("account.invoice").create(vals)
|
||||
|
||||
def import_sale_file(self,ids,context):
|
||||
def _import_sale_file(self,ids,context):
|
||||
obj=self.browse(ids)[0]
|
||||
path=get_file_path(obj.file)
|
||||
data=open(path).read()
|
||||
|
|
|
@ -16,7 +16,7 @@ class Dialyzer(Model):
|
|||
'ref': fields.Char("Ref."),
|
||||
"note": fields.Text("Note",search=True),
|
||||
"date": fields.DateTime("Create Date",search=True),
|
||||
"use_time": fields.Integer("Use Time"),
|
||||
"use_time": fields.Integer("Last Use Time"),
|
||||
"max_use_time": fields.Integer("Max Use Time"),
|
||||
"exp_date": fields.Date("Expiry Date",search=True),
|
||||
"dialyzer_type": fields.Selection([("low","low flux"),("high","high flux"),("dbl","dbl hifulx")],"Dialyzer Type"),
|
||||
|
@ -29,6 +29,7 @@ class Dialyzer(Model):
|
|||
"visit_id": fields.Many2One("clinic.visit","Visit",search=True),
|
||||
"hd_case_id": fields.Many2One("clinic.hd.case","HD Case",search=True),
|
||||
"hd_cases": fields.One2Many("clinic.hd.case","dlz_id","HD Case"), #TODO funtion to get hd case
|
||||
"hd_cases_dlz": fields.One2Many("clinic.hd.case.dialyzer","dialyzer_id","Dialyzer History",domain=[['hd_case_id.state','in','waiting_payment','paid']]),
|
||||
'department_id': fields.Many2One("clinic.department","Department",search=True),
|
||||
"membrane_type": fields.Selection([("unsub","Unsub cellul"),("sub","Sub cellul"),("synthetic","Synthetic")],"Membrane Type"),
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
from netforce.model import Model,fields
|
||||
|
||||
class Document(Model):
|
||||
_inherit="document"
|
||||
|
||||
_fields={
|
||||
'name': fields.Char("Name",search=True),
|
||||
}
|
||||
|
||||
Document.register()
|
|
@ -128,7 +128,7 @@ class HDCase(Model):
|
|||
mdc_names.append(prod_name or "")
|
||||
else:
|
||||
mdc+=amt
|
||||
mdc_names.append(name or "")
|
||||
mdc_names.append(prod_name or "")
|
||||
if categ.code=='EPO':
|
||||
epo_names.append(prod_name.title())
|
||||
elif categ.code=='IVR':
|
||||
|
@ -222,6 +222,7 @@ class HDCase(Model):
|
|||
"mdc": fields.Float("MDC",function="_get_expense",function_multi=True),
|
||||
"srv": fields.Float("Service",function="_get_expense",function_multi=True),
|
||||
"mdc_name": fields.Float("MDC Name",function="_get_expense",function_multi=True),
|
||||
"iron_name": fields.Float("Iron Name",function="_get_expense",function_multi=True),
|
||||
'sickbed_id': fields.Many2One("clinic.sickbed",'Sickbed'),
|
||||
"ref": fields.Char("Ref",search=True),
|
||||
"time_start": fields.DateTime("Start Time",required=True),
|
||||
|
@ -558,6 +559,7 @@ class HDCase(Model):
|
|||
context={
|
||||
'type': 'in',
|
||||
'branch_id': obj.branch_id.id,
|
||||
'date': obj.date,
|
||||
}
|
||||
payment_id=get_model("account.payment").create(vals,context=context)
|
||||
obj.write({
|
||||
|
@ -592,6 +594,9 @@ class HDCase(Model):
|
|||
|
||||
def make_invoices(self,ids,context={}):
|
||||
setting=get_model("settings").browse(1,context)
|
||||
fin_account_receivable_id=setting.account_receivable_id.id
|
||||
if not fin_account_receivable_id:
|
||||
raise Exception("Missing Account Receivable")
|
||||
currency_id=setting.currency_id.id
|
||||
if not currency_id:
|
||||
raise Exception("Currency not found in account settings")
|
||||
|
@ -602,7 +607,8 @@ class HDCase(Model):
|
|||
obj=self.browse(ids[0])
|
||||
if obj.invoices:
|
||||
for inv in obj.invoices:
|
||||
inv.void()
|
||||
if inv.state=='waiting_payment':
|
||||
inv.void()
|
||||
due_date=obj.date[0:10]
|
||||
# cash, credit
|
||||
is_credit=context.get('is_credit') or False
|
||||
|
@ -635,7 +641,7 @@ class HDCase(Model):
|
|||
else:
|
||||
acc=prod_acc(prod.id,stype.id,'cash')
|
||||
account_id=acc.get("ar_credit_id",None)
|
||||
ar_debit_id=acc.get("ar_debit_id",None)
|
||||
ar_debit_id=acc.get("ar_debit_id",None) # account receiveable
|
||||
if not account_id:
|
||||
raise Exception("No Income Credit Account for product [%s] %s"%(prod.code, prod.name))
|
||||
if not ar_debit_id:
|
||||
|
@ -669,65 +675,82 @@ class HDCase(Model):
|
|||
patient=obj.patient_id
|
||||
patient_partner=patient.partner_id
|
||||
|
||||
def group_invoice_line(invoice_lines):
|
||||
invoice_vals={}
|
||||
for mode,invoice_line in invoice_lines:
|
||||
ar_debit_id=invoice_line['ar_debit_id']
|
||||
if not invoice_vals.get(ar_debit_id):
|
||||
invoice_vals[ar_debit_id]=[]
|
||||
del invoice_line['ar_debit_id']
|
||||
invoice_vals[ar_debit_id].append((mode,invoice_line))
|
||||
return invoice_vals
|
||||
|
||||
if rmb_lines:
|
||||
ptype=patient.type_id
|
||||
partner=ptype.contact_id
|
||||
if not partner:
|
||||
raise Exception("No contact for patient type %s"%obj.ptype.name)
|
||||
vals={
|
||||
"type": "out",
|
||||
"inv_type": "invoice",
|
||||
"tax_type": "tax_in",
|
||||
'date': obj.date,
|
||||
'due_date': due_date,
|
||||
"ref": '%s (%s)'%(patient.name or '',patient.number or ''),
|
||||
'department_id': obj.department_id.id,
|
||||
"related_id": "clinic.hd.case,%s"%obj.id,
|
||||
"currency_id": currency_id,
|
||||
"company_id": company_id,
|
||||
"lines": [],
|
||||
"company_id": company_id,
|
||||
'hdcase_credit': False,
|
||||
'hdcase_reconcile': True,
|
||||
}
|
||||
vals["partner_id"]=partner.id
|
||||
vals['lines']=rmb_lines
|
||||
if patient_partner:
|
||||
vals['patient_partner_id']=patient_partner.id,
|
||||
#XXX
|
||||
#vals['lines']=rmb_lines
|
||||
# reset account receiveable
|
||||
# group invoice line by account receiveable
|
||||
invoices=group_invoice_line(rmb_lines)
|
||||
if obj.branch_id:
|
||||
context['branch_id']=obj.branch_id.id
|
||||
get_model("account.invoice").create(vals,context=context)
|
||||
for account_receiveable_id, lines in invoices.items():
|
||||
vals={
|
||||
"type": "out",
|
||||
"inv_type": "invoice",
|
||||
"tax_type": "tax_in",
|
||||
'date': obj.date,
|
||||
'due_date': due_date,
|
||||
"ref": '%s (%s)'%(patient.name or '',patient.number or ''),
|
||||
'department_id': obj.department_id.id,
|
||||
"related_id": "clinic.hd.case,%s"%obj.id,
|
||||
"currency_id": currency_id,
|
||||
"company_id": company_id,
|
||||
"lines": [],
|
||||
"company_id": company_id,
|
||||
"partner_id": partner.id,
|
||||
'patient_partner_id':patient_partner.id,
|
||||
'account_id':account_receiveable_id ,
|
||||
'lines':lines,
|
||||
}
|
||||
context['date']=obj.date
|
||||
inv_id=get_model("account.invoice").create(vals,context=context)
|
||||
inv=get_model("account.invoice").browse(inv_id)
|
||||
|
||||
# click button Credit from popup of button Pay
|
||||
if normb_lines and is_credit:
|
||||
partner=patient.partner_id
|
||||
if not partner:
|
||||
raise Exception("No contact for this patient %s"%obj.partner.name)
|
||||
context['branch_id']=obj.branch_id.id
|
||||
number=self._get_number_invoice_noclaim(context=context)
|
||||
vals={
|
||||
'number': number,
|
||||
"type": "out",
|
||||
"inv_type": "invoice",
|
||||
"tax_type": "tax_in",
|
||||
'due_date': due_date,
|
||||
"ref": '%s (%s)'%(patient.name or '',patient.number or ''),
|
||||
"related_id": "clinic.hd.case,%s"%obj.id,
|
||||
"currency_id": currency_id,
|
||||
"company_id": company_id,
|
||||
"lines": [],
|
||||
"company_id": company_id,
|
||||
'partner_id':partner.id,
|
||||
'hdcase_credit': True,
|
||||
'hdcase_reconcile': True,
|
||||
}
|
||||
vals['lines']=normb_lines
|
||||
if patient_partner:
|
||||
vals['patient_partner_id']=patient_partner.id,
|
||||
get_model("account.invoice").create(vals,context) # create alway
|
||||
|
||||
obj.make_pickings()
|
||||
# prevent douplicate create invoice & picking
|
||||
invoices=group_invoice_line(normb_lines)
|
||||
for account_receiveable_id, lines in invoices.items():
|
||||
context['date']=obj.date
|
||||
number=self._get_number_invoice_noclaim(context=context)
|
||||
vals={
|
||||
'number': number,
|
||||
"type": "out",
|
||||
"inv_type": "invoice",
|
||||
"tax_type": "tax_in",
|
||||
'due_date': due_date,
|
||||
"ref": '%s (%s)'%(patient.name or '',patient.number or ''),
|
||||
"related_id": "clinic.hd.case,%s"%obj.id,
|
||||
"currency_id": currency_id,
|
||||
"company_id": company_id,
|
||||
"lines": [],
|
||||
"company_id": company_id,
|
||||
'partner_id':partner.id,
|
||||
'patient_partner_id':patient_partner.id,
|
||||
'account_id': account_receiveable_id,
|
||||
}
|
||||
vals['lines']=lines
|
||||
get_model("account.invoice").create(vals,context)
|
||||
|
||||
if not context.get('is_migrate'):
|
||||
obj.make_pickings()
|
||||
for line in obj.lines:
|
||||
line.write({
|
||||
'state': 'done',
|
||||
|
@ -835,6 +858,7 @@ class HDCase(Model):
|
|||
context={
|
||||
'pick_type': 'out',
|
||||
'journal_id': pick_vals['journal_id'],
|
||||
'date': obj.date
|
||||
}
|
||||
pick_id=picking_obj.create(pick_vals,context=context)
|
||||
pick=picking_obj.browse(pick_id)
|
||||
|
@ -858,6 +882,7 @@ class HDCase(Model):
|
|||
}
|
||||
if obj.number=='/':
|
||||
context['branch_id']=obj.branch_id.id
|
||||
context['date']=obj.date
|
||||
number=self._get_number(context=context)
|
||||
vals['number']=number
|
||||
|
||||
|
@ -875,18 +900,26 @@ class HDCase(Model):
|
|||
# TODO pop to note
|
||||
obj.write({"state":"cancelled"})
|
||||
|
||||
#FIXME should use history to get the last time time and it should drop automatical
|
||||
def update_usetime(self,ids,context={}):
|
||||
datenow=time.strftime("%Y-%m-%d")
|
||||
for obj in self.browse(ids):
|
||||
# in case to draft
|
||||
if obj.date < datenow:
|
||||
continue
|
||||
is_decrease=context.get('is_decrease')
|
||||
for dlz_line in obj.dialyzers:
|
||||
dlz=dlz_line.dialyzer_id
|
||||
membrane_type=dlz_line.membrane_type or 'unsub'
|
||||
dialyzer_type=dlz_line.dialyzer_type or 'low'
|
||||
use_time=dlz_line.use_time or 0
|
||||
max_use_time=dlz_line.max_use_time or 0
|
||||
desc=dlz_line.description or ''
|
||||
#TODO when we to draft after approve hdcase it will update the wrong use time
|
||||
#if use_time > (dlz.use_time or 0):
|
||||
#continue
|
||||
if is_decrease:
|
||||
use_time-=1
|
||||
print("decrease ok")
|
||||
vals={
|
||||
'membrane_type': membrane_type,
|
||||
'dialyzer_type': dialyzer_type,
|
||||
|
@ -901,9 +934,6 @@ class HDCase(Model):
|
|||
})
|
||||
elif use_time > max_use_time:
|
||||
raise Exception("Dialyzer is expired!")
|
||||
else:
|
||||
pass
|
||||
dlz=dlz_line.dialyzer_id
|
||||
dlz.write(vals)
|
||||
return True
|
||||
|
||||
|
@ -1030,6 +1060,7 @@ class HDCase(Model):
|
|||
def undo(self,ids,context={}):
|
||||
obj=self.browse(ids)[0]
|
||||
context['is_decrease']=True
|
||||
# in case to draft
|
||||
obj.update_usetime(context=context)
|
||||
for line in obj.lines:
|
||||
line.write({
|
||||
|
@ -1088,7 +1119,7 @@ class HDCase(Model):
|
|||
|
||||
def request_fee(self,ids,context={}):
|
||||
obj=self.browse(ids)[0]
|
||||
#obj.update_usetime()
|
||||
obj.update_usetime()
|
||||
obj.complete()
|
||||
# send some message to anyboby: patient
|
||||
return {
|
||||
|
@ -1253,7 +1284,7 @@ class HDCase(Model):
|
|||
for payment in obj.payments:
|
||||
context['payment_id']=payment.id
|
||||
data=self.get_report_payment_data(context=context)
|
||||
limit_item=10
|
||||
limit_item=9
|
||||
if data['state']=='draft':
|
||||
limit_item=10
|
||||
for i in range(len(data['lines']),limit_item):
|
||||
|
|
|
@ -6,21 +6,28 @@ class HDCaseDialyzerLine(Model):
|
|||
def _get_all(self,ids,context={}):
|
||||
res={}
|
||||
for obj in self.browse(ids):
|
||||
dlz=obj.dialyzer_id
|
||||
hdcase=obj.hd_case_id
|
||||
res[obj.id]={
|
||||
'membrane_type': dlz.membrane_type,
|
||||
'hdcase_date': hdcase.date,
|
||||
'hdcase_state': hdcase.state,
|
||||
'nurse_id': hdcase.nurse_id.id,
|
||||
}
|
||||
return res
|
||||
|
||||
_fields={
|
||||
"hd_case_id": fields.Many2One("clinic.hd.case","HdCase",on_delete="cascade"),
|
||||
"hd_case_id": fields.Many2One("clinic.hd.case","HDCase",on_delete="cascade"),
|
||||
"dialyzer_type": fields.Selection([("low","low flux"),("high","high flux"),("dbl","dbl hifulx")],"Dialyzer Type"),
|
||||
"dialyzer_id": fields.Many2One("clinic.dialyzer","Dialyzer",search=True),
|
||||
"description": fields.Char("Description",search=True),
|
||||
"use_time":fields.Integer("Use time"),
|
||||
"max_use_time":fields.Integer("Max use time"),
|
||||
"membrane_type": fields.Selection([("unsub","Unsub cellul"),("sub","Sub cellul"),("synthetic","Synthetic")],"Membrane Type"),
|
||||
'hdcase_date': fields.Date('Date', function="_get_all",function_multi=True),
|
||||
"hdcase_state": fields.Selection([("draft","Draft"),('waiting_treatment','Waiting Treatment'),("in_progress","In Progress"),("completed","Finish Treatment"),('paid','Paid'),("waiting_payment","Waiting Payment"),("discountinued","Discountinued"),("cancelled","Cancelled")],"Status",required=True,function="_get_all",function_multi=True),
|
||||
'nurse_id': fields.Many2One('clinic.staff', 'Nurse',function="_get_all",function_multi=True),
|
||||
}
|
||||
|
||||
_order="hd_case_id.date desc"
|
||||
|
||||
HDCaseDialyzerLine.register()
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ class MatchingPayment(Model):
|
|||
'state': fields.Selection([['draft','Draft'],['approved','Approved']],'State'),
|
||||
'type': fields.Selection([['all','All'],['match','Match'],['unmatch','Not Match']],'Type'),
|
||||
'user_id': fields.Many2One("base.user","Approver"),
|
||||
'department_id': fields.Many2One("clinic.department","Department"),
|
||||
'branch_id': fields.Many2One("clinic.branch","Branch"),
|
||||
}
|
||||
|
||||
def _get_ptype(self,context={}):
|
||||
|
@ -146,13 +148,13 @@ class MatchingPayment(Model):
|
|||
def match(self,ids,context={}):
|
||||
obj=self.browse(ids)[0]
|
||||
lines=obj.get_line()
|
||||
print("len.lines ", len(lines))
|
||||
print("total lines: ", len(lines))
|
||||
patient_type=obj.patient_type_id
|
||||
if not patient_type:
|
||||
raise Exception("not found patient type")
|
||||
raise Exception("Not found patient type")
|
||||
contact=patient_type.contact_id
|
||||
if not contact:
|
||||
raise Exception("contact not found")
|
||||
raise Exception("Contact not found")
|
||||
st=get_model("clinic.setting").browse(1)
|
||||
st_pt=st.get_patient_hn()
|
||||
patient_hn=st_pt['hns']
|
||||
|
@ -167,7 +169,7 @@ class MatchingPayment(Model):
|
|||
dom.append(['partner_id',"=",contact.id])
|
||||
dom.append(['state','=', 'waiting_payment'])
|
||||
invoices=get_model('account.invoice').search_browse(dom)
|
||||
print("len(invoices)", len(invoices))
|
||||
print("total invoices: ", len(invoices))
|
||||
for invoice in invoices:
|
||||
pname,hn,card_no='', '', ''
|
||||
pname2=pname
|
||||
|
@ -359,7 +361,6 @@ class MatchingPayment(Model):
|
|||
'state': 'match',
|
||||
})
|
||||
else:
|
||||
#print("not found")
|
||||
hn=hn.replace("-", "")
|
||||
hn=hn.replace("/", "")
|
||||
phn=patient_hn.get(hn)
|
||||
|
|
|
@ -570,8 +570,8 @@ class Patient(Model):
|
|||
res=get_model('clinic.staff').search([['number','=','walkin'],['type','=','doctor']])
|
||||
if res:
|
||||
data['doctor_id']=res[0]
|
||||
else:
|
||||
data['doctor_id']=None
|
||||
#else:
|
||||
#data['doctor_id']=None
|
||||
return data
|
||||
|
||||
Patient.register()
|
||||
|
|
|
@ -0,0 +1,327 @@
|
|||
import time
|
||||
from calendar import monthrange
|
||||
|
||||
from netforce.model import Model, fields, get_model
|
||||
from netforce.utils import get_file_path
|
||||
|
||||
from . import utils
|
||||
|
||||
class PaymentMatching(Model):
|
||||
_name="clinic.payment.matching"
|
||||
_string="Payment Matching"
|
||||
_transient=True
|
||||
|
||||
_fields={
|
||||
'name': fields.Char("Name"),
|
||||
"date": fields.Date("Month"),
|
||||
"date_from": fields.Date("From", required=True),
|
||||
"date_to": fields.Date("To", required=True),
|
||||
'file_id': fields.Many2One('document','File',domain=[['categ_id.code','=','MP']]),
|
||||
"period_id": fields.Many2One("clinic.period.line","Period"),
|
||||
'department_id': fields.Many2One("clinic.department","Department"),
|
||||
'branch_id': fields.Many2One("clinic.branch","Branch"),
|
||||
"inv_state": fields.Selection([("draft","Draft"),("waiting_approval","Waiting Approval"),("waiting_payment","Waiting Payment"),("paid","Paid"),("voided","Voided")],"Status"),
|
||||
"view_type": fields.Selection([("invoice","Invoice"),("matching","Matching")],"View Type"),
|
||||
'patient_type_id': fields.Many2One("clinic.patient.type","Patient Type",required=True),
|
||||
'pcode': fields.Char("Code",required=True),
|
||||
'hcode_id': fields.Many2One("clinic.hospital","HCode"),
|
||||
'inv_ids': fields.Text("Invoice ids"),
|
||||
}
|
||||
|
||||
def _get_date_from(self,context={}):
|
||||
year,month,day=time.strftime("%Y-%m-%d").split("-")
|
||||
return '%s-%s-%s'%(year,month,day)
|
||||
|
||||
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,day)
|
||||
|
||||
def default_get(self,field_names=None,context={},**kw):
|
||||
defaults=context.get("defaults",{})
|
||||
date_from=defaults.get("date_from", self._get_date_from())
|
||||
date_to=defaults.get("date_to", self._get_date_to())
|
||||
yearnow=date_from.split("-")[0]
|
||||
for period in get_model('clinic.period').search_browse([['name','=',yearnow]]):
|
||||
for line in period.lines:
|
||||
if line.state=='open':
|
||||
period_id=line.id
|
||||
date_from=line.date_start
|
||||
date_to=line.date_stop
|
||||
break
|
||||
patient_type_id=None
|
||||
pcode='SSO'
|
||||
for ptype in get_model('clinic.patient.type').search_read([['default','=',True]],['code']):
|
||||
pcode=ptype['code']
|
||||
patient_type_id=ptype['id']
|
||||
hdcode_id=None
|
||||
for hid in get_model("clinic.hospital").search([]):
|
||||
hdcode_id=hid
|
||||
break
|
||||
res={
|
||||
'period_id': period_id,
|
||||
'date': time.strftime("%Y-%m-%d"),
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
#'inv_state': 'waiting_payment',
|
||||
'view_type': 'invoice',
|
||||
'patient_type_id': patient_type_id,
|
||||
'pcode': pcode,
|
||||
'hcode_id': hdcode_id,
|
||||
}
|
||||
return res
|
||||
|
||||
def onchange_period(self,context={}):
|
||||
data=context['data']
|
||||
period_id=data['period_id']
|
||||
period=get_model('clinic.period.line').browse(period_id)
|
||||
data['date_from']=period.date_start
|
||||
data['date_to']=period.date_stop
|
||||
return data
|
||||
|
||||
def onchange_ptype(self,context={}):
|
||||
data=context['data']
|
||||
type_id=data['patient_type_id']
|
||||
if type_id:
|
||||
t=get_model('clinic.patient.type').browse(type_id)
|
||||
data['pcode']=t.code or ""
|
||||
return data
|
||||
|
||||
def get_line(self,ids,context={}):
|
||||
obj=self.browse(ids)[0]
|
||||
if not obj.file_id.file:
|
||||
raise Exception("File not found!")
|
||||
fname=obj.file_id.file
|
||||
if obj.pcode=='SSO':
|
||||
hcode=obj.hcode_id.code or ""
|
||||
if not hcode:
|
||||
raise Exception("Wrong HCode")
|
||||
try:
|
||||
n,sf=fname.split(".")
|
||||
except Exception as e:
|
||||
print("ERROR: wrong file ", e)
|
||||
|
||||
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.pcode=='UC':
|
||||
fpath=get_file_path(fname)
|
||||
node='HDBills'
|
||||
lines=utils.read_xml(fpath,node=node)
|
||||
hcode=fname.split("_")[0]
|
||||
else:
|
||||
raise Exception("Type %s is not support"%obj.pcode or "")
|
||||
|
||||
if not lines:
|
||||
raise Exception("No data to match")
|
||||
return lines
|
||||
|
||||
def get_report_data(self,ids,context={}):
|
||||
defaults=self.default_get(context=context)
|
||||
print('defaults ', defaults)
|
||||
date_from=defaults.get('date_from')
|
||||
date_to=defaults.get('date_to')
|
||||
branch_id=None
|
||||
department_id=None
|
||||
inv_state=defaults.get('inv_state')
|
||||
view_type=defaults.get('view_type')
|
||||
pcode=''
|
||||
obj=None
|
||||
if ids:
|
||||
obj=self.browse(ids)[0]
|
||||
date_from=obj.date_from
|
||||
date_to=obj.date_to
|
||||
branch_id=obj.branch_id.id
|
||||
department_id=obj.department_id.id
|
||||
inv_state=obj.inv_state
|
||||
view_type=obj.view_type
|
||||
pcode=obj.pcode
|
||||
lines=[]
|
||||
invoices=[]
|
||||
total_invoice=0
|
||||
total_match_invoice=0
|
||||
total_epo=0
|
||||
total_srv=0
|
||||
total_fee=0
|
||||
total_amount=0
|
||||
def get_invoices():
|
||||
invoices=[]
|
||||
dom=[
|
||||
['date','>=',date_from],
|
||||
['date','<=',date_to],
|
||||
]
|
||||
if inv_state:
|
||||
dom.append(['state','=',inv_state])
|
||||
if branch_id and not department_id:
|
||||
dom.append(['department_id.branch_id','=',branch_id])
|
||||
elif department_id:
|
||||
dom.append(['department_id','=',department_id])
|
||||
print('dom ', dom)
|
||||
field_names=['date','number','amount_total','amount_due','patient_id','state']
|
||||
for inv in get_model('account.invoice').search_read(dom,field_names):
|
||||
vals={
|
||||
'id': inv['id'],
|
||||
'patient_id': None,
|
||||
'patient_name': '',
|
||||
'patient_hn': '',
|
||||
}
|
||||
for field_name in field_names:
|
||||
if field_name=='patient_id' and inv['patient_id']:
|
||||
patient=get_model('clinic.patient').browse(inv['patient_id'][0])
|
||||
vals['patient_id']=patient.id
|
||||
vals['patient_name']=patient.name
|
||||
vals['patient_nospace_name']=patient.name_check
|
||||
vals['patient_cid']=patient.card_no
|
||||
vals['patient_hn']=patient.hn_no
|
||||
else:
|
||||
vals[field_name]=inv[field_name]
|
||||
vals[field_name]=inv[field_name]
|
||||
invoices.append(vals)
|
||||
return invoices
|
||||
inv_match_ids=[]
|
||||
if view_type=='invoice':
|
||||
lines=get_invoices()
|
||||
total_invoice=len(lines)
|
||||
else:
|
||||
if obj and obj.pcode=='SSO':
|
||||
invoices=get_invoices()
|
||||
total_invoice=len(invoices)
|
||||
rlines=obj.get_line()
|
||||
no=1
|
||||
for rline in rlines:
|
||||
date_treatment=rline.get("dttran")
|
||||
date=date_treatment[0:10]
|
||||
time=date_treatment[11:]
|
||||
if not time:
|
||||
continue
|
||||
epo=rline.get('epoadm29') or 0
|
||||
fee=rline.get('amount23') or 0
|
||||
srv=rline.get('allow37') or 0
|
||||
name=rline.get("name14")
|
||||
name_nospace=name.replace(" ","")
|
||||
pid=rline.get('pid')
|
||||
hn=rline.get('hn')
|
||||
hn=''.join([x for x in hn if x.isdigit()])
|
||||
total_fee+=fee
|
||||
total_epo+=epo
|
||||
total_srv+=srv
|
||||
amount=fee+epo+srv
|
||||
total_amount+=amount
|
||||
line_vals={
|
||||
'no': no,
|
||||
'date':date,
|
||||
'patient_name': name,
|
||||
'pid': pid,
|
||||
'hn': hn,
|
||||
'fee': fee,
|
||||
'srv': srv,
|
||||
'epo': epo,
|
||||
'amount': amount,
|
||||
}
|
||||
for item_amt in ['fee','srv','epo']:
|
||||
for inv in invoices:
|
||||
if inv['patient_id']:
|
||||
# check card no first then HN finally patient name
|
||||
if pid==inv['patient_cid'] or hn==inv['patient_hn'] or name_nospace==inv['patient_nospace_name']:
|
||||
#inv_amt=inv['amount_due']
|
||||
inv_amt=inv['amount_total']
|
||||
inv_date=inv['date']
|
||||
if inv_date==date and inv_amt==line_vals[item_amt]:
|
||||
line_vals['inv_%s'%(item_amt)]=inv['number']
|
||||
line_vals['inv_%s_id'%(item_amt)]=inv['id']
|
||||
line_vals['inv_%s_state'%(item_amt)]=inv['state']
|
||||
if inv['state']=='waiting_payment':
|
||||
inv_match_ids.append(inv['id'])
|
||||
total_match_invoice+=1
|
||||
break
|
||||
lines.append(line_vals)
|
||||
no+=1
|
||||
elif obj and obj.pcode=='UC':
|
||||
invoices=get_invoices()
|
||||
total_invoice=len(invoices)
|
||||
rlines=obj.get_line()
|
||||
no=1
|
||||
for rline in rlines:
|
||||
#{'amount': '1500.0000',
|
||||
#'cstat': None,
|
||||
#'dttran': '2014-09-27T10:00:00',
|
||||
#'epostat': 'E',
|
||||
#'hdflag': 'COU',
|
||||
#'hdrate': '1500.0000',
|
||||
#'hn': '98511252',
|
||||
#'hreg': 'NHSO1',
|
||||
#'invno': '437941480',
|
||||
#'paid': '0.0000',
|
||||
#'paychk': '1',
|
||||
#'reimbpay': '0.0000',
|
||||
#'rid': '2190',
|
||||
#'station': '01'}
|
||||
date,time=(rline['dttran'] or "").split("T")
|
||||
fee=0
|
||||
if rline.get('amount'):
|
||||
fee=float(rline['amount'])
|
||||
total_fee+=fee
|
||||
hn=rline['hn']
|
||||
hn=hn.replace(" ", "")
|
||||
pname=''
|
||||
pname_check=''
|
||||
pid=''
|
||||
for pt in get_model("clinic.patient").search_browse([['hn_no','=',hn]]):
|
||||
pname=pt.name or ""
|
||||
pname_check=pt.name_check or ""
|
||||
pid=pt.card_no or ""
|
||||
vals={
|
||||
'date':date,
|
||||
'patient_name': pname,
|
||||
'pid': pid,
|
||||
'hn': hn,
|
||||
'fee': fee,
|
||||
'srv': 0,
|
||||
'epo': 0,
|
||||
'inv_id': None,
|
||||
'inv_number': '',
|
||||
'inv_state': '',
|
||||
'no': no,
|
||||
}
|
||||
for inv in invoices:
|
||||
if inv['patient_id']:
|
||||
if pid==inv['patient_cid'] or hn==inv['patient_hn'] or pname_check==inv['patient_nospace_name']:
|
||||
if date==inv['date'] and fee==inv['amount_due']:
|
||||
vals['inv_id']=inv['id']
|
||||
vals['inv_number']=inv['number']
|
||||
vals['inv_state']=inv['state']
|
||||
if inv['state']=='waiting_payment':
|
||||
inv_match_ids.append(inv['id'])
|
||||
total_match_invoice+=1
|
||||
break
|
||||
lines.append(vals)
|
||||
no+=1
|
||||
pc=0
|
||||
if total_invoice:
|
||||
pc=(total_match_invoice/total_invoice)*100
|
||||
if inv_match_ids and obj:
|
||||
obj.write({
|
||||
'inv_ids': str(inv_match_ids),
|
||||
})
|
||||
data={
|
||||
'lines': lines,
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'total_item': len(lines),
|
||||
'total_fee': total_fee,
|
||||
'total_epo': total_epo,
|
||||
'total_srv': total_srv,
|
||||
'total_invoice': total_invoice,
|
||||
'total_match_invoice': total_match_invoice,
|
||||
'pc_match': pc,
|
||||
'pc_unmatch': 100-pc,
|
||||
'total_unmatch_invoice': total_invoice-total_match_invoice,
|
||||
'total_amount': total_amount,
|
||||
'view_type': view_type,
|
||||
'pcode': pcode,
|
||||
}
|
||||
return data
|
||||
|
||||
PaymentMatching.register()
|
|
@ -6,6 +6,7 @@ class Product(Model):
|
|||
'patient_types': fields.Many2Many("clinic.patient.type","Patient Types"),
|
||||
'departments': fields.One2Many('clinic.department.product','product_id','Departments'),
|
||||
'report_visible': fields.Boolean("Report Visible"),
|
||||
'account_products': fields.One2Many('clinic.setting.account.product','product_id','Account Products'),
|
||||
}
|
||||
|
||||
Product.register()
|
||||
|
|
|
@ -19,6 +19,7 @@ class ReportAccountHDCaseSummary(Model):
|
|||
'reimbursable': fields.Selection([['yes','Yes'],['no','No']],'Claim'),
|
||||
'walkin': fields.Selection([['yes','Yes'],['no','No']],'Walkin'),
|
||||
'cycle_id': fields.Many2One("clinic.cycle","Cycle"),
|
||||
'pay_type': fields.Selection([['cash','Cash'],['credit','Credit']],'Pay Type'),
|
||||
'product_id': fields.Many2One("product","Product"),
|
||||
}
|
||||
|
||||
|
@ -76,6 +77,7 @@ class ReportAccountHDCaseSummary(Model):
|
|||
walkin=defaults.get('walkin')
|
||||
ptype_id=None
|
||||
cycle_id=None
|
||||
pay_type=''
|
||||
if ids:
|
||||
obj=self.browse(ids)[0]
|
||||
branch_id=obj.branch_id.id
|
||||
|
@ -87,6 +89,7 @@ class ReportAccountHDCaseSummary(Model):
|
|||
cycle_id=obj.cycle_id.id
|
||||
reimbursable=obj.reimbursable or ""
|
||||
product_id=obj.product_id.id
|
||||
pay_type=obj.pay_type
|
||||
walkin=obj.walkin
|
||||
dom=[
|
||||
['hd_case_id.date','>=', date_from],
|
||||
|
@ -214,7 +217,20 @@ class ReportAccountHDCaseSummary(Model):
|
|||
else:
|
||||
records[hdcase_id]['misc']+=amt
|
||||
lines=[]
|
||||
|
||||
# nurse would like to see only receipt
|
||||
del_invoice=False
|
||||
del_receipt=False
|
||||
if pay_type and reimbursable=='no' and pay_type=='cash':
|
||||
del_invoice=True
|
||||
elif pay_type and reimbursable=='no' and pay_type=='credit':
|
||||
del_receipt=True
|
||||
|
||||
for hdcase_id, vals in records.items():
|
||||
if del_invoice and vals['inv_number']:
|
||||
continue
|
||||
elif del_receipt and vals['pm_number']:
|
||||
continue
|
||||
lines.append(vals)
|
||||
company_name=company.name or ""
|
||||
if department_id:
|
||||
|
|
|
@ -141,14 +141,14 @@ class ReportCycleItem(Model):
|
|||
return number
|
||||
|
||||
total_epo=0
|
||||
total_ivr=0
|
||||
for line in hdcase.lines:
|
||||
prod=line.product_id
|
||||
if prod.categ_id:
|
||||
if prod.categ_id.code=='EPO':
|
||||
total_epo+=line.qty or 0
|
||||
else:
|
||||
pass
|
||||
#print('>>> ', hdcase.number, prod.id, prod.name)
|
||||
if prod.categ_id.code=='IVR':
|
||||
total_ivr+=line.qty or 0
|
||||
|
||||
lines.append({
|
||||
'dlz_drop': dlz_drop,
|
||||
|
@ -166,6 +166,7 @@ class ReportCycleItem(Model):
|
|||
'hdcase_number': reformat_number(hdcase.number),
|
||||
'hdcase_id': hdcase.id,
|
||||
'mdc_name': hdcase.mdc_name or hdcase.epo,
|
||||
'iron_name': hdcase.iron_name or '',
|
||||
'fee': abs(hdcase.fee),
|
||||
'dlz_name': hdcase.dlz_name,
|
||||
'dlz_use': dlz_use,
|
||||
|
@ -182,6 +183,7 @@ class ReportCycleItem(Model):
|
|||
'dpt_id': dpt.id,
|
||||
'dpt_name': dpt.name or "",
|
||||
'total_epo': total_epo,
|
||||
'total_ivr': total_ivr,
|
||||
})
|
||||
month_str=utils.MONTHS['th_TH'][int(month)]
|
||||
company_name=company.name or ""
|
||||
|
@ -219,6 +221,10 @@ class ReportCycleItem(Model):
|
|||
sub_mdc+=x['mdc'] or 0
|
||||
if not epos.get(x['mdc_name']):
|
||||
epos[x['mdc_name']]=0
|
||||
#XXX
|
||||
if not epos.get(x['iron_name']):
|
||||
epos[x['iron_name']]=0
|
||||
epos[x['iron_name']]+=x['total_ivr'] or 0 #XXX
|
||||
epos[x['mdc_name']]+=x['total_epo'] or 0
|
||||
count+=1
|
||||
line['date_txt']=line['date']
|
||||
|
@ -267,6 +273,7 @@ class ReportCycleItem(Model):
|
|||
'description': v['description'],
|
||||
'qty': v['qty'],
|
||||
})
|
||||
vscl_lines=sorted(vscl_lines,key=lambda x: x['description'])
|
||||
ptype_lines=[]
|
||||
total_pt=0
|
||||
pkeys=list(ptypes.keys())
|
||||
|
|
|
@ -101,8 +101,12 @@ class ReportMedicalDetail(Model):
|
|||
dom.append(['hd_case_id.branch_id','=',branch_id])
|
||||
if department_id:
|
||||
dom.append(['hd_case_id.department_id','=',department_id])
|
||||
if prod_categ_id:
|
||||
dom.append(['product_categ_id.id','child_of',prod_categ_id])
|
||||
st=get_model("clinic.setting").browse(1)
|
||||
ct_ids=[]
|
||||
for categ in st.product_categ_view:
|
||||
ct_ids.append(categ.id)
|
||||
if ct_ids:
|
||||
dom.append(['product_categ_id.id','in',ct_ids])
|
||||
if product_id:
|
||||
dom.append(['product_id','=',product_id])
|
||||
if types and ids:
|
||||
|
|
|
@ -86,13 +86,17 @@ class ReportMedicalSummary(Model):
|
|||
dom=[]
|
||||
dom.append(['type','=','stock'])
|
||||
dom.append(['report_visible','=',True])
|
||||
if prod_categ_id:
|
||||
dom.append(['categ_id.id','child_of',prod_categ_id])
|
||||
st=get_model("clinic.setting").browse(1)
|
||||
ct_ids=[]
|
||||
for categ in st.product_categ_view:
|
||||
ct_ids.append(categ.id)
|
||||
if ct_ids:
|
||||
dom.append(['categ_id.id','in',ct_ids])
|
||||
categ_ids=set()
|
||||
for prod in get_model("product").search_browse(dom):
|
||||
prod_code=prod.code or ""
|
||||
categ=prod.categ_id
|
||||
if categ and categ.parent_id:
|
||||
if categ:
|
||||
categ_ids.update({categ.id})
|
||||
products[prod_code]={}
|
||||
for patient_type_id,type_name in patient_types.items():
|
||||
|
@ -124,10 +128,6 @@ class ReportMedicalSummary(Model):
|
|||
continue
|
||||
if categ and categ.id not in list(categ_ids):
|
||||
continue
|
||||
#if line.type=='fee' or prod.type=='service':
|
||||
#continue
|
||||
#if prod_categ_id and prod_categ_id != prod.categ_id.id:
|
||||
#continue
|
||||
products[prod_code][patient_type_id]['qty']+=line.qty
|
||||
|
||||
lines=[]
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from calendar import monthrange
|
||||
|
||||
|
@ -54,7 +53,6 @@ class ClinicSetting(Model):
|
|||
'schd_to': fields.Date("To"),
|
||||
'department_id': fields.Many2One("clinic.department","Department"),
|
||||
'branch_id': fields.Many2One("clinic.branch","Branch"),
|
||||
'shop_categs': fields.Many2Many("product.categ","Categs"),
|
||||
'shop_type_id': fields.Many2One("clinic.patient.type","Patient Type"),
|
||||
'skip_type_id': fields.Many2One("clinic.patient.type","Skip Type"), # Matching HD Case
|
||||
"cash_account_id": fields.Many2One("account.account","Cash Account",multi_company=True),
|
||||
|
@ -65,6 +63,7 @@ class ClinicSetting(Model):
|
|||
'next_date': fields.DateTime("Next Gen"),
|
||||
'staff_from_id': fields.Many2One("clinic.staff","Staff From"),
|
||||
'staff_to_id': fields.Many2One("clinic.staff","Staff To"),
|
||||
'product_categ_view': fields.Many2Many("product.categ","Product Category View"),
|
||||
}
|
||||
|
||||
_defaults={
|
||||
|
|
|
@ -8,8 +8,8 @@ class SettingAccountProduct(Model):
|
|||
|
||||
_fields={
|
||||
"setting_id": fields.Many2One("clinic.setting","Setting",required=True,on_delete="cascade"),
|
||||
"patient_type_id": fields.Many2One("clinic.patient.type","Patient Type",search=True,required=True),
|
||||
'categ_id': fields.Many2One("product.categ","Category",search=True,required=True),
|
||||
"patient_type_id": fields.Many2One("clinic.patient.type","Patient Type",search=True),
|
||||
'categ_id': fields.Many2One("product.categ","Category",search=True),
|
||||
"product_id": fields.Many2One("product","Product",search=True,required=True),
|
||||
"ar_credit_id": fields.Many2One("account.account","Income Credit",multi_company=True,search=True),
|
||||
"ar_debit_id": fields.Many2One("account.account","AR Debit",multi_company=True,search=True),
|
||||
|
|
|
@ -13,8 +13,6 @@ class Shop(Model):
|
|||
|
||||
def _get_all(self,ids,context={}):
|
||||
res={}
|
||||
st=get_model("clinic.setting").browse(1)
|
||||
shop_categs=[x.id for x in st.shop_categs]
|
||||
for obj in self.browse(ids):
|
||||
sub_total=0
|
||||
tax_amount=0
|
||||
|
@ -30,7 +28,6 @@ class Shop(Model):
|
|||
'tax_amount': tax_amount,
|
||||
'total': total,
|
||||
'due_amount': total,
|
||||
'shop_categs': shop_categs,
|
||||
}
|
||||
return res
|
||||
|
||||
|
@ -54,7 +51,6 @@ class Shop(Model):
|
|||
"invoices": fields.One2Many("account.invoice","related_id","Invoices"),
|
||||
"payments": fields.One2Many("account.payment","related_id","Payments"),
|
||||
'dom_str': fields.Char("Dom Str"),
|
||||
'shop_categs': fields.Many2Many("product.categ","Categs",function="_get_all",function_multi=True,store=True),
|
||||
"related_id": fields.Reference([["sale.order","Sales Order"],["purchase.order","Purchase Order"],["project","Project"],["job","Service Order"],["service.contract","Service Contract"]],"Related To"),
|
||||
'company_id': fields.Many2One("company","Company"),
|
||||
"pay_type": fields.Selection([("cash","Cash"),("credit","Credit")],"Pay Type"),
|
||||
|
@ -70,11 +66,6 @@ class Shop(Model):
|
|||
|
||||
_order="date desc"
|
||||
|
||||
def _get_shop_categs(self,context={}):
|
||||
st=get_model("clinic.setting").browse(1)
|
||||
shop_categs=[x.id for x in st.shop_categs]
|
||||
return shop_categs
|
||||
|
||||
def _get_related(self,context={}):
|
||||
related_id=None
|
||||
if context.get('refer_id'):
|
||||
|
@ -169,7 +160,6 @@ class Shop(Model):
|
|||
'branch_id': _get_branch,
|
||||
'department_id': _get_department,
|
||||
'state': 'draft',
|
||||
'shop_categs': _get_shop_categs,
|
||||
'related_id': _get_related,
|
||||
'patient_id': _get_patient,
|
||||
'contact_id': _get_contact,
|
||||
|
@ -320,23 +310,8 @@ class Shop(Model):
|
|||
prod_acc=cst.get_product_account
|
||||
partner=obj.contact_id
|
||||
context['branch_id']=obj.branch_id.id
|
||||
number=self._get_credit_number(context=context),
|
||||
vals={
|
||||
'number': number,
|
||||
"type": "out",
|
||||
"inv_type": "invoice",
|
||||
"tax_type": "tax_in",
|
||||
'due_date': obj.due_date,
|
||||
"ref": obj.number or "",
|
||||
'department_id': obj.department_id.id,
|
||||
"related_id": "clinic.shop,%s"%obj.id,
|
||||
"currency_id": currency_id,
|
||||
"company_id": company_id,
|
||||
'partner_id': partner.id,
|
||||
'hdcase_reconcile': True,
|
||||
"lines": [],
|
||||
}
|
||||
track_id=obj.branch_id.track_id.id
|
||||
inv_lines=[]
|
||||
for line in obj.lines:
|
||||
if line.amount < 1:
|
||||
continue
|
||||
|
@ -348,7 +323,7 @@ class Shop(Model):
|
|||
raise Exception("No Income Credit Account for product [%s] %s"%(prod.code, prod.name))
|
||||
if not ar_debit_id:
|
||||
raise Exception("No Ar Debit Account for product [%s] %s"%(prod.code, prod.name))
|
||||
vals['lines'].append(('create',{
|
||||
inv_lines.append(('create',{
|
||||
"product_id": prod.id,
|
||||
"description": line.description or "",
|
||||
"qty": line.qty,
|
||||
|
@ -359,9 +334,38 @@ class Shop(Model):
|
|||
'ar_debit_id': ar_debit_id,
|
||||
'track_id': track_id,
|
||||
}))
|
||||
inv_id=get_model("account.invoice").create(vals,context=context)
|
||||
inv=get_model("account.invoice").browse(inv_id)
|
||||
inv.post()
|
||||
def group_invoice_line(invoice_lines):
|
||||
invoice_vals={}
|
||||
for mode,invoice_line in invoice_lines:
|
||||
ar_debit_id=invoice_line['ar_debit_id']
|
||||
if not invoice_vals.get(ar_debit_id):
|
||||
invoice_vals[ar_debit_id]=[]
|
||||
del invoice_line['ar_debit_id']
|
||||
invoice_vals[ar_debit_id].append((mode,invoice_line))
|
||||
return invoice_vals
|
||||
invoices=group_invoice_line(inv_lines)
|
||||
for account_receiveable_id, lines in invoices.items():
|
||||
context['date']=obj.date
|
||||
number=self._get_credit_number(context=context),
|
||||
vals={
|
||||
'number': number,
|
||||
"type": "out",
|
||||
"inv_type": "invoice",
|
||||
"tax_type": "tax_in",
|
||||
'due_date': obj.due_date,
|
||||
"ref": obj.number or "",
|
||||
'department_id': obj.department_id.id,
|
||||
"related_id": "clinic.shop,%s"%obj.id,
|
||||
"currency_id": currency_id,
|
||||
"company_id": company_id,
|
||||
'patient_partner_id':partner.id, #to check before post
|
||||
'partner_id': partner.id,
|
||||
"lines": lines,
|
||||
'account_id': account_receiveable_id,
|
||||
}
|
||||
inv_id=get_model("account.invoice").create(vals,context=context)
|
||||
inv=get_model("account.invoice").browse(inv_id)
|
||||
inv.post()
|
||||
obj.make_pickings()
|
||||
obj.write({
|
||||
'state': 'waiting_payment',
|
||||
|
@ -442,6 +446,7 @@ class Shop(Model):
|
|||
'pick_type': 'out',
|
||||
'journal_id': pick_vals['journal_id'],
|
||||
'branch_id': obj.branch_id.id,
|
||||
'date': obj.date,
|
||||
}
|
||||
pick_id=picking_obj.create(pick_vals,context=context)
|
||||
pick=picking_obj.browse(pick_id)
|
||||
|
@ -460,6 +465,7 @@ class Shop(Model):
|
|||
raise Exception("No Income Account")
|
||||
company_id=get_active_company()
|
||||
context['branch_id']=obj.branch_id.id
|
||||
context['date']=obj.date
|
||||
number=self._get_cash_number(context=context),
|
||||
vals={
|
||||
'number': number,
|
||||
|
@ -497,6 +503,7 @@ class Shop(Model):
|
|||
context={
|
||||
'type': 'in',
|
||||
'branch_id': obj.branch_id.id,
|
||||
'date': obj.date,
|
||||
}
|
||||
payment_id=get_model("account.payment").create(vals,context=context)
|
||||
payment=get_model('account.payment').browse(payment_id)
|
||||
|
@ -893,6 +900,10 @@ class Shop(Model):
|
|||
for pick in shop.pickings:
|
||||
pick_id=pick.id
|
||||
pick_number=pick.number
|
||||
st=get_model('clinic.setting').browse(1)
|
||||
ct_ids=[]
|
||||
for ct in st.product_categ_view:
|
||||
ct_ids.append(ct.id)
|
||||
for line in shop.lines:
|
||||
prod=line.product_id
|
||||
categ=line.categ_id
|
||||
|
@ -903,8 +914,10 @@ class Shop(Model):
|
|||
fee=0
|
||||
dlz=0
|
||||
mdc_names=[]
|
||||
if categ.parent_id:
|
||||
if categ.parent_id.code=='MDC':
|
||||
#if categ.parent_id:
|
||||
#if categ.parent_id.code=='MDC': #XXX
|
||||
if categ:
|
||||
if categ.id in ct_ids:
|
||||
mdc+=amount
|
||||
name=prod.name or ""
|
||||
name=name.split("-")
|
||||
|
@ -941,7 +954,7 @@ class Shop(Model):
|
|||
'fee': fee,
|
||||
'mdc': mdc,
|
||||
'mdc_name': ','.join([n for n in mdc_names]),
|
||||
'dlz_name': "", #XXX
|
||||
'dlz_name': "",
|
||||
'dlz_id': "",
|
||||
'dlz': dlz,
|
||||
'lab': lab,
|
||||
|
|
|
@ -229,8 +229,17 @@ class VisitBoard(Model):
|
|||
visit_color=''
|
||||
sickbed_name='N/A'
|
||||
sickbed_id=None
|
||||
found_hdcase=False
|
||||
is_paid=False
|
||||
is_waiting=False
|
||||
if visit.hd_cases:
|
||||
hd_case=visit.hd_cases[0]
|
||||
if hd_case.state in ('waiting_payment', 'paid'):
|
||||
found_hdcase=True
|
||||
if hd_case.state=='waiting_payment':
|
||||
is_waiting=True
|
||||
elif hd_case.state=='paid':
|
||||
is_paid=True
|
||||
sickbed_name=hd_case.sickbed_id.name or "N/A"
|
||||
sickbed_id=hd_case.sickbed_id.id
|
||||
hd_case_id=hd_case.id,
|
||||
|
@ -288,7 +297,7 @@ class VisitBoard(Model):
|
|||
'patient_type_id': patient.type_id.id or None,
|
||||
'doctor_name': visit.doctor_id.name,
|
||||
'doctor_id': visit.doctor_id.id,
|
||||
'hd_case_number': hd_case_number,
|
||||
'hd_case_number': (hd_case_number or '').replace('HDC/',''),
|
||||
'hd_case_state': hd_case_state,
|
||||
'hd_case_state_txt':HD_STATE.get(hd_case_state,''),
|
||||
'hd_case_id': hd_case_id,
|
||||
|
@ -304,7 +313,12 @@ class VisitBoard(Model):
|
|||
'details5':'',
|
||||
'no': no,
|
||||
'note': visit.note,
|
||||
'cost': 0,
|
||||
'is_paid': is_paid,
|
||||
'is_waiting': is_waiting,
|
||||
}
|
||||
if found_hdcase:
|
||||
line['cost']=hd_case.total_amount or 0
|
||||
lines.append(line)
|
||||
no+=1
|
||||
if not types.get(visit_date):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
- location
|
||||
- staff
|
||||
- patient
|
||||
|
||||
mathching payment:
|
||||
target
|
||||
get invoice all invoice
|
||||
can match any
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,179 @@
|
|||
<div class="row" style="margin-top:10px;">
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" style="width:{{currency pc_match}}%">
|
||||
{{currency pc_match}}% Match (success)
|
||||
</div>
|
||||
<div class="progress-bar progress-bar-danger" role="progressbar" style="width:{{currency pc_unmatch}}%">
|
||||
{{currency pc_unmatch}}% Un Match (fail)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<th style="text-align:center;width:25%">Total Item Waiting To Matching</th>
|
||||
<th style="text-align:center;width:25%">Total Invoice</th>
|
||||
<th style="text-align:center;width:25%">Match</th>
|
||||
<th style="text-align:center;width:25%">Un Match</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:center">{{currency total_item}}</td>
|
||||
<td style="text-align:center">{{currency total_invoice}}</td>
|
||||
<td style="text-align:center">
|
||||
{{currency total_match_invoice}}
|
||||
</td>
|
||||
<td style="text-align:center">
|
||||
{{currency total_unmatch_invoice}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<table class="table table-hover">
|
||||
{{#ifeq view_type 'invoice'}}
|
||||
<thead class="scroll-header">
|
||||
<th>Invoice Date</th>
|
||||
<th>Number</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#if lines}}
|
||||
{{#each lines}}
|
||||
<tr>
|
||||
<td>{{date}}</td>
|
||||
<td>{{number}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
{{/if}}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
</tfoot>
|
||||
{{else}}
|
||||
{{#ifeq pcode "SSO"}}
|
||||
<thead class="scroll-header">
|
||||
<th style="text-align:center">No.</th>
|
||||
<th style="text-align:center">Date</th>
|
||||
<th style="text-align:center">PID</th>
|
||||
<th style="text-align:center">HN</th>
|
||||
<th style="text-align:center">Patient</th>
|
||||
<th style="text-align:center">Fee</th>
|
||||
<th style="text-align:center">Inv Fee</th>
|
||||
<th style="text-align:center">EPO</th>
|
||||
<th style="text-align:center">Inv EPO</th>
|
||||
<th style="text-align:center">Service</th>
|
||||
<th style="text-align:center">Inv Service</th>
|
||||
<th style="text-align:center">Amount</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#if lines}}
|
||||
{{#each lines}}
|
||||
<tr>
|
||||
<td>{{no}}</td>
|
||||
<td style="width:8%">{{date}}</td>
|
||||
<td>{{pid}}</td>
|
||||
<td>{{hn}}</td>
|
||||
<td>{{patient_name}}</td>
|
||||
<td style="text-align:right">{{currency fee}}</td>
|
||||
<td>
|
||||
<a style="text-decoration:None" href="ui#form_view_xml=cust_invoice_form&active_id={{inv_fee_id}}&name=cust_invoice&mode=form" target="_blank">
|
||||
{{#if inv_fee_id}}
|
||||
{{#ifeq inv_fee_state "paid"}}
|
||||
<span class="label label-success">
|
||||
{{else}}
|
||||
<span class="label label-info">
|
||||
{{/ifeq}}
|
||||
{{inv_fee}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</a>
|
||||
</td>
|
||||
<td style="text-align:right">{{currency epo}}</td>
|
||||
<td>
|
||||
<a style="text-decoration:None" href="ui#form_view_xml=cust_invoice_form&active_id={{inv_epo_id}}&name=cust_invoice&mode=form" target="_blank">
|
||||
{{#if inv_epo_id}}
|
||||
<span class="label label-info">
|
||||
{{inv_epo}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</a>
|
||||
</td>
|
||||
<td style="text-align:right">{{currency srv}}</td>
|
||||
<td>
|
||||
<a href="ui#form_view_xml=cust_invoice_form&active_id={{inv_srv_id}}&name=cust_invoice&mode=form" target="_blank">
|
||||
{{#if inv_srv_id}}
|
||||
<span class="label label-info">
|
||||
{{inv_srv}}
|
||||
</span>
|
||||
{{/if}}
|
||||
</a>
|
||||
</td>
|
||||
<td style="text-align:right">{{currency amount}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
{{/if}}
|
||||
</tbody>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th style="text-align:right;">{{currency total_fee}}</th>
|
||||
<th></th>
|
||||
<th style="text-align:right;">{{currency total_epo}}</th>
|
||||
<th></th>
|
||||
<th style="text-align:right">{{currency total_srv}}</th>
|
||||
<th></th>
|
||||
<th style="text-align:right">{{currency total_amount}}</th>
|
||||
<tfoot>
|
||||
</tfoot>
|
||||
{{else}}
|
||||
{{#ifeq pcode "UC"}}
|
||||
<thead class="scroll-header">
|
||||
<th>No.</th>
|
||||
<th>Date</th>
|
||||
<th>HN</th>
|
||||
<th>ID</th>
|
||||
<th>Patient</th>
|
||||
<th>Fee</th>
|
||||
<th>Invoice</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each lines}}
|
||||
<tr>
|
||||
<td>{{no}}</td>
|
||||
<td>{{date}}</td>
|
||||
<td>{{hn}}</td>
|
||||
<td>{{pid}}</td>
|
||||
<td>{{patient_name}}</td>
|
||||
<td>{{currency fee}}</td>
|
||||
<td>
|
||||
{{#if inv_number}}
|
||||
<a href="ui#form_view_xml=cust_invoice_form&active_id={{inv_id}}&name=cust_invoice&mode=form" target="_blank">
|
||||
<span class="label label-info">
|
||||
{{inv_number}}
|
||||
</span>
|
||||
</a>
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th>{{currency total_fee}}</th>
|
||||
<th></th>
|
||||
</tfoot>
|
||||
{{else}}
|
||||
TODO
|
||||
{{/ifeq}}
|
||||
{{/ifeq}}
|
||||
{{/ifeq}}
|
||||
</table>
|
||||
</div>
|
|
@ -8,8 +8,8 @@
|
|||
<thead class="scroll-header">
|
||||
<th>วันที่</th>
|
||||
<th>รอบ</th>
|
||||
<th>No</th>
|
||||
<th>HDC#</th>
|
||||
<th>No.</th>
|
||||
<th>HDC/</th>
|
||||
<th>ชื่อ-สกุล</th>
|
||||
<th>แพทย์</th>
|
||||
<th>สิทธ์</th>
|
||||
|
@ -32,7 +32,7 @@
|
|||
{{/ifeq}}
|
||||
{{#if cseq_txt}}
|
||||
<th>{{date_txt}}</th>
|
||||
<th>{{cseq_txt}}</th>
|
||||
<th style="width:2%;text-align:center">{{cseq_txt}}</th>
|
||||
<td style="text-align:center">{{no}}</td>
|
||||
<td style="width:6%"><a href="/ui#name=clinic_hd_case&active_id={{hdcase_id}}&mode=form">{{hdcase_number}}</a></td>
|
||||
<td><a href="/ui#name=clinic_patient&active_id={{pid}}&mode=form">{{pname}}</a></td>
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
<th style="text-align:center">สิทธ์</th>
|
||||
<th style="text-align:center">แพทย์</th>
|
||||
<th style="text-align:center">ชั้น</th>
|
||||
<th style="text-align:center">เตียง</th>
|
||||
<th style="text-align:center">บันทึกการรักษา</th>
|
||||
<th style="text-align:center">HDC/</th>
|
||||
<!--<th style="text-align:center">ค่าตอบแทน</th>-->
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each lines }}
|
||||
|
@ -49,11 +49,6 @@
|
|||
<td style="background-color:{{visit_color}}">{{patient_type}}</td>
|
||||
<td style="background-color:{{visit_color}}"><a href="/ui#name=clinic_staff&active_id={{doctor_id}}&mode=form">{{doctor_name}}</a></td>
|
||||
<td style="background-color:{{visit_color}}"><a href="/ui#name=clinic_department&active_id={{department_id}}&mode=form">{{department_name}}</a></td>
|
||||
{{#if sickbed_id}}
|
||||
<td style="background-color:{{visit_color}}"><a href="/ui#name=clinic_sickbed&active_id={{sickbed_id}}&mode=form">{{sickbed_name}}</a></td>
|
||||
{{else}}
|
||||
<td style="background-color:{{visit_color}}">{{sickbed_name}}</td>
|
||||
{{/if}}
|
||||
<td style="background-color:{{visit_color}}">
|
||||
<a href="/ui#name=clinic_hd_case&active_id={{hd_case_id}}&mode=form">
|
||||
{{#ifeq number "Waiting"}}
|
||||
|
@ -83,6 +78,17 @@
|
|||
</span>
|
||||
</a>
|
||||
</td>
|
||||
<!--
|
||||
{{#if is_paid}}
|
||||
<td style="background-color:{{visit_color}};text-align:right;color:green">{{currency cost}}</td>
|
||||
{{else}}
|
||||
{{#if is_waiting}}
|
||||
<td style="background-color:{{visit_color}};text-align:right;color:blue">{{currency cost}}</td>
|
||||
{{else}}
|
||||
<td style="background-color:{{visit_color}};text-align:right">{{currency cost}}</td>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
-->
|
||||
{{/if}}
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
|
Loading…
Reference in New Issue