Merge branch 'conv_bal'
commit
f7bab5a48a
|
@ -3,4 +3,8 @@
|
||||||
<field name="department_id" span="2"/>
|
<field name="department_id" span="2"/>
|
||||||
<field name="patient_partner_id" span="2"/>
|
<field name="patient_partner_id" span="2"/>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="memo" position="after">
|
||||||
|
<field name="account_id" span="2"/>
|
||||||
|
<field name="hdcase_reconcile" span="2"/>
|
||||||
|
</field>
|
||||||
</inherit>
|
</inherit>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<inherit inherit="fin_settings">
|
<inherit inherit="fin_settings">
|
||||||
|
<!--
|
||||||
<field name="rounding_account_id" position="after">
|
<field name="rounding_account_id" position="after">
|
||||||
<field name="acc_prod_match"/>
|
<field name="acc_prod_match"/>
|
||||||
</field>
|
</field>
|
||||||
|
-->
|
||||||
</inherit>
|
</inherit>
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
from . import clinic_setting
|
from . import clinic_setting
|
||||||
from . import update_account_tracking
|
#from . import conv_bal
|
||||||
#from . import print_labor_cost
|
from . import repost_invoice
|
||||||
#from . import hdcase
|
|
||||||
#from . import remove_conv_bal
|
|
||||||
#from . import import_acc
|
|
||||||
#from . import update_labor_cost_line
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
from netforce.model import get_model
|
||||||
|
from netforce import migration
|
||||||
|
from netforce.access import set_active_user, set_active_company
|
||||||
|
|
||||||
|
class Migration(migration.Migration):
|
||||||
|
_name="clinic.conv.bal"
|
||||||
|
_version="2.10.0"
|
||||||
|
|
||||||
|
def migrate(self):
|
||||||
|
set_active_user(1)
|
||||||
|
set_active_company(1)
|
||||||
|
#for mv in get_model("account.move").search_browse([['number','ilike', 'OPEN']]):
|
||||||
|
#mv.to_draft()
|
||||||
|
#mv.delete()
|
||||||
|
cbv_id=24
|
||||||
|
cbv=get_model("conv.bal").browse(cbv_id)
|
||||||
|
cbv.write({
|
||||||
|
'date_fmt': '%Y-%m-%d',
|
||||||
|
'file': 'tb.csv',
|
||||||
|
})
|
||||||
|
print("import acc file (step 1) running ...")
|
||||||
|
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={})
|
||||||
|
get_model("conv.bal").import_sale([cbv.id],context={})
|
||||||
|
|
||||||
|
print("import purch file (step 3) running ...")
|
||||||
|
cbv.write({
|
||||||
|
'file': 'ap.csv',
|
||||||
|
'date_fmt': '%d/%m/%Y',
|
||||||
|
})
|
||||||
|
get_model("conv.bal").import_purch_file([cbv.id],context={})
|
||||||
|
get_model("conv.bal").import_purch([cbv.id],context={})
|
||||||
|
|
||||||
|
cbv.write({
|
||||||
|
'date_fmt': '%Y-%m-%d',
|
||||||
|
})
|
||||||
|
|
||||||
|
print(">> next 3")
|
||||||
|
print("create_open_entry...")
|
||||||
|
cbv.create_open_entry()
|
||||||
|
print("create_sale_invoices...")
|
||||||
|
cbv.create_sale_invoices()
|
||||||
|
print("create_purch_invoices...")
|
||||||
|
cbv.create_purch_invoices()
|
||||||
|
print("Done!")
|
||||||
|
return True
|
||||||
|
|
||||||
|
Migration.register()
|
|
@ -1,41 +0,0 @@
|
||||||
from netforce.model import get_model
|
|
||||||
from netforce import migration
|
|
||||||
from netforce.access import set_active_user, get_active_user, set_active_company
|
|
||||||
|
|
||||||
class Migration(migration.Migration):
|
|
||||||
_name="import.acc"
|
|
||||||
_version="2.11.0"
|
|
||||||
|
|
||||||
def migrate(self):
|
|
||||||
set_active_company(1)
|
|
||||||
cbv_id=24
|
|
||||||
cbv=get_model("conv.bal").browse(cbv_id)
|
|
||||||
#cbv.write({
|
|
||||||
#'file': 'tb.csv',
|
|
||||||
#})
|
|
||||||
#print("import acc file (step 1) running ...")
|
|
||||||
#get_model("conv.bal").import_acc([cbv.id],context={})
|
|
||||||
|
|
||||||
#cbv.write({
|
|
||||||
#'file': 'ar.csv',
|
|
||||||
#})
|
|
||||||
#print("import sale file (step 2)running ...")
|
|
||||||
#get_model("conv.bal").import_sale_file([cbv.id],context={})
|
|
||||||
|
|
||||||
#print("import purch file (step 3) running ...")
|
|
||||||
#cbv.write({
|
|
||||||
#'file': 'ap.csv',
|
|
||||||
#})
|
|
||||||
#get_model("conv.bal").import_purch([cbv.id],context={})
|
|
||||||
#print("create invoice from setep 1 to 3 is running...")
|
|
||||||
#print("create_open_entry...")
|
|
||||||
#print('Done!')
|
|
||||||
#cbv.create_open_entry()
|
|
||||||
#print("create_sale_invoices...")
|
|
||||||
#cbv.create_sale_invoices()
|
|
||||||
#print("create_purch_invoices...")
|
|
||||||
#cbv.create_purch_invoices()
|
|
||||||
print("Done!")
|
|
||||||
return True
|
|
||||||
|
|
||||||
Migration.register()
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
from netforce.model import get_model
|
||||||
|
from netforce import migration
|
||||||
|
from netforce.access import set_active_user, set_active_company
|
||||||
|
|
||||||
|
class Migration(migration.Migration):
|
||||||
|
_name="clinic.repos.invoice"
|
||||||
|
_version="2.10.0"
|
||||||
|
|
||||||
|
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([]):
|
||||||
|
for inv in hdcase.invoices:
|
||||||
|
if inv.state=='waiting_payment':
|
||||||
|
print('hdcase:repost ---> ', inv.number)
|
||||||
|
inv.to_draft()
|
||||||
|
inv.write({
|
||||||
|
'hdcase_reconcile': True,
|
||||||
|
})
|
||||||
|
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()
|
||||||
|
print("Done!")
|
||||||
|
return True
|
||||||
|
|
||||||
|
Migration.register()
|
|
@ -140,3 +140,6 @@ from . import share_location
|
||||||
from . import report_cycle_setting
|
from . import report_cycle_setting
|
||||||
from . import print_labor_cost
|
from . import print_labor_cost
|
||||||
from . import print_labor_cost_line
|
from . import print_labor_cost_line
|
||||||
|
from . import conv_bal
|
||||||
|
from . import conv_sale_invoice
|
||||||
|
from . import account_move_line
|
||||||
|
|
|
@ -9,6 +9,7 @@ class AccountInvoice(Model):
|
||||||
'department_id': fields.Many2One("clinic.department","Department",search=True),
|
'department_id': fields.Many2One("clinic.department","Department",search=True),
|
||||||
'patient_partner_id': fields.Many2One("partner","Patient",search=True),
|
'patient_partner_id': fields.Many2One("partner","Patient",search=True),
|
||||||
'hdcase_credit': fields.Boolean("HD Case Credit"),
|
'hdcase_credit': fields.Boolean("HD Case Credit"),
|
||||||
|
'hdcase_reconcile': fields.Boolean("HD Case Reconcile"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_number(self,context={}):
|
def _get_number(self,context={}):
|
||||||
|
@ -240,15 +241,19 @@ class AccountInvoice(Model):
|
||||||
line["credit"]=-amt
|
line["credit"]=-amt
|
||||||
|
|
||||||
is_match=False
|
is_match=False
|
||||||
if settings.acc_prod_match and obj.type=='out':
|
if obj.hdcase_reconcile and obj.type=='out':
|
||||||
print("#POST: clinic customize")
|
print("#POST: clinic customize")
|
||||||
cst=get_model('clinic.setting').browse(1)
|
cst=get_model('clinic.setting').browse(1)
|
||||||
prod_acc=cst.get_product_account
|
prod_acc=cst.get_product_account
|
||||||
move_vals["lines"]=[]
|
move_vals["lines"]=[]
|
||||||
for line in group_lines:
|
for line in group_lines:
|
||||||
desc=line['description']
|
desc=line['description']
|
||||||
|
if not desc:
|
||||||
|
print("skip no description ", obj.number)
|
||||||
|
continue
|
||||||
ar_debit_id=None
|
ar_debit_id=None
|
||||||
#ar_credit_id=None
|
#ar_credit_id=None
|
||||||
|
# search from patient_type
|
||||||
for prod_id in get_model('product').search([['name','=',desc]]):
|
for prod_id in get_model('product').search([['name','=',desc]]):
|
||||||
for ptype_id in get_model("clinic.patient.type").search([['contact_id','=',partner.id]]):
|
for ptype_id in get_model("clinic.patient.type").search([['contact_id','=',partner.id]]):
|
||||||
acc=prod_acc(prod_id,ptype_id,'credit')
|
acc=prod_acc(prod_id,ptype_id,'credit')
|
||||||
|
@ -256,8 +261,16 @@ class AccountInvoice(Model):
|
||||||
ar_debit_id=acc.get("ar_debit_id")
|
ar_debit_id=acc.get("ar_debit_id")
|
||||||
if ar_debit_id:
|
if ar_debit_id:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# search from patient
|
||||||
if not ar_debit_id:
|
if not ar_debit_id:
|
||||||
raise Exception("Missing AR Debit Account for product %s"%(desc))
|
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={
|
line_vals={
|
||||||
"description": desc,
|
"description": desc,
|
||||||
"account_id": ar_debit_id,
|
"account_id": ar_debit_id,
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
from netforce.model import Model
|
||||||
|
|
||||||
|
class AccountMoveLine(Model):
|
||||||
|
_inherit="account.move.line"
|
||||||
|
|
||||||
|
|
||||||
|
AccountMoveLine.register()
|
|
@ -1,3 +1,6 @@
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
|
||||||
from netforce.model import Model, fields, get_model
|
from netforce.model import Model, fields, get_model
|
||||||
|
|
||||||
class AccountPayment(Model):
|
class AccountPayment(Model):
|
||||||
|
@ -58,9 +61,447 @@ class AccountPayment(Model):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
#customize
|
||||||
|
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"})
|
||||||
|
#Cutomize
|
||||||
|
for rec_lines in reconcile_ids:
|
||||||
|
get_model("account.move.line").reconcile(rec_lines)
|
||||||
|
obj.create_prepay_invoice()
|
||||||
|
|
||||||
def post(self,ids,context={}):
|
def post(self,ids,context={}):
|
||||||
obj=self.browse(ids)[0]
|
obj=self.browse(ids)[0]
|
||||||
res=None
|
res=None
|
||||||
|
if obj.hdcase_reconcile:
|
||||||
|
obj.clinic_post()
|
||||||
if obj.rd_cust:
|
if obj.rd_cust:
|
||||||
res={}
|
res={}
|
||||||
print("RD Customize")
|
print("RD Customize")
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
import csv
|
||||||
|
import datetime
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
from netforce.model import Model, fields, get_model
|
||||||
|
from netforce.utils import get_file_path
|
||||||
|
|
||||||
|
class ConvBal(Model):
|
||||||
|
_inherit="conv.bal"
|
||||||
|
|
||||||
|
def create_sale_invoices(self,ids,context={}):
|
||||||
|
obj=self.browse(ids)[0]
|
||||||
|
desc="Conversion balance %s"%obj.date
|
||||||
|
for inv in obj.sale_invoices:
|
||||||
|
vals={
|
||||||
|
"type": "out",
|
||||||
|
"inv_type": inv.amount_due>=0 and "invoice" or "credit",
|
||||||
|
"partner_id": inv.contact_id.id,
|
||||||
|
"date": inv.date,
|
||||||
|
"due_date": inv.due_date,
|
||||||
|
"number": inv.number,
|
||||||
|
"ref": inv.ref,
|
||||||
|
"memo": desc,
|
||||||
|
"lines": [],
|
||||||
|
"state": "waiting_payment",
|
||||||
|
"account_id": inv.account_id.id,
|
||||||
|
"reconcile_move_line_id": inv.move_line_id.id,
|
||||||
|
"currency_id": inv.account_id.currency_id.id,
|
||||||
|
"currency_rate": inv.amount_due/inv.amount_cur if inv.amount_cur else None,
|
||||||
|
"department_id": inv.department_id.id,
|
||||||
|
}
|
||||||
|
line_vals={
|
||||||
|
"description": desc,
|
||||||
|
"amount": abs(inv.amount_cur or inv.amount_due),
|
||||||
|
"track_id": inv.track_id.id,
|
||||||
|
}
|
||||||
|
vals["lines"].append(("create",line_vals))
|
||||||
|
res=get_model("account.invoice").search([["number","=",inv.number]])
|
||||||
|
if res:
|
||||||
|
inv2_id=res[0]
|
||||||
|
inv2=get_model("account.invoice").browse(inv2_id)
|
||||||
|
#ratchawat
|
||||||
|
inv2.write({
|
||||||
|
'lines': vals['lines'],
|
||||||
|
})
|
||||||
|
#if abs(inv2.amount_total)-abs(inv.amount_due)>0.001: # XXX
|
||||||
|
#raise Exception("Failed to update invoice %s: different amount"%inv.number)
|
||||||
|
if inv2.state=="draft":
|
||||||
|
raise Exception("Failed to update invoice %s: invalid state"%inv.number)
|
||||||
|
inv2.write({
|
||||||
|
"move_id": obj.move_id.id,
|
||||||
|
"reconcile_move_line_id": inv.move_line_id.id,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
get_model("account.invoice").create(vals)
|
||||||
|
|
||||||
|
def import_sale_file(self,ids,context):
|
||||||
|
obj=self.browse(ids)[0]
|
||||||
|
path=get_file_path(obj.file)
|
||||||
|
data=open(path).read()
|
||||||
|
rd=csv.reader(StringIO(data))
|
||||||
|
headers=next(rd)
|
||||||
|
headers=[h.strip() for h in headers]
|
||||||
|
del_ids=get_model("conv.sale.invoice").search([["conv_id","=",obj.id]])
|
||||||
|
get_model("conv.sale.invoice").delete(del_ids)
|
||||||
|
for row in rd:
|
||||||
|
#print("row",row)
|
||||||
|
row+="," #XXX append blank column for Amount Cur
|
||||||
|
line=dict(zip(headers,row))
|
||||||
|
#print("line",line)
|
||||||
|
track_id=None
|
||||||
|
department_id=None
|
||||||
|
department_name=line.get("Department")
|
||||||
|
if department_name:
|
||||||
|
for dpt in get_model("clinic.department").search_browse([['name','=',department_name]]):
|
||||||
|
department_id=dpt.id
|
||||||
|
track_id=dpt.branch_id.track_id.id
|
||||||
|
if not line.get("Number"):
|
||||||
|
continue
|
||||||
|
number=line["Number"].strip()
|
||||||
|
if not number:
|
||||||
|
continue
|
||||||
|
|
||||||
|
##XXX remove invoice
|
||||||
|
#for inv in get_model('account.invoice').search_browse([['number','=', number]]):
|
||||||
|
#print('number --> ', number)
|
||||||
|
#inv.to_draft()
|
||||||
|
#inv.delete()
|
||||||
|
#continue
|
||||||
|
|
||||||
|
ref=line["Reference"].strip()
|
||||||
|
contact_name=line["Contact"].strip()
|
||||||
|
res=get_model("partner").search([["name","=",contact_name]])
|
||||||
|
if not res:
|
||||||
|
raise Exception("Contact not found: '%s'"%contact_name)
|
||||||
|
contact_id=res[0]
|
||||||
|
date=datetime.datetime.strptime(line["Date"].strip(),obj.date_fmt).strftime("%Y-%m-%d")
|
||||||
|
due_date=datetime.datetime.strptime(line["Due Date"].strip(),obj.date_fmt).strftime("%Y-%m-%d")
|
||||||
|
amount_due=float(line["Amount Due"].strip().replace(",","") or 0)
|
||||||
|
acc_code=line["Account"].strip()
|
||||||
|
amount_cur=float(line["Amount Cur"].strip().replace(",","") or 0)
|
||||||
|
acc_codes=acc_code.split(",")
|
||||||
|
amts=[] #XXX
|
||||||
|
for m in line['Memo'].split(","):
|
||||||
|
amt=m.split(":")[1]
|
||||||
|
amt=amt.strip()
|
||||||
|
if amt:
|
||||||
|
amt=float(amt)
|
||||||
|
amts.append(amt)
|
||||||
|
if len(acc_codes) > 1:
|
||||||
|
count=0
|
||||||
|
print("*"*80)
|
||||||
|
for acc_code in acc_codes:
|
||||||
|
acc_code=acc_code.strip()
|
||||||
|
res=get_model("account.account").search([["code","=",acc_code]])
|
||||||
|
if not res:
|
||||||
|
raise Exception("Account code not found: %s"%acc_code)
|
||||||
|
acc_id=res[0]
|
||||||
|
amount_due=amts[count]
|
||||||
|
vals={
|
||||||
|
"conv_id": obj.id,
|
||||||
|
"number": number,
|
||||||
|
"ref": ref,
|
||||||
|
"contact_id": contact_id,
|
||||||
|
"date": date,
|
||||||
|
"due_date": due_date,
|
||||||
|
"amount_due": amount_due,
|
||||||
|
"account_id": acc_id,
|
||||||
|
"amount_cur": amount_due, #XXX
|
||||||
|
'track_id': track_id,
|
||||||
|
'department_id': department_id,
|
||||||
|
}
|
||||||
|
get_model("conv.sale.invoice").create(vals)
|
||||||
|
count+=1
|
||||||
|
elif len(amts) >= 1 and len(acc_codes)<=1:
|
||||||
|
acc_code=acc_codes[0].strip()
|
||||||
|
res=get_model("account.account").search([["code","=",acc_code]])
|
||||||
|
if not res:
|
||||||
|
raise Exception("Account code not found: %s"%acc_code)
|
||||||
|
acc_id=res[0]
|
||||||
|
for amt in amts:
|
||||||
|
amount_due=amt
|
||||||
|
vals={
|
||||||
|
"conv_id": obj.id,
|
||||||
|
"number": number,
|
||||||
|
"ref": ref,
|
||||||
|
"contact_id": contact_id,
|
||||||
|
"date": date,
|
||||||
|
"due_date": due_date,
|
||||||
|
"amount_due": amount_due,
|
||||||
|
"account_id": acc_id,
|
||||||
|
"amount_cur": amount_due, #XXX
|
||||||
|
'track_id': track_id,
|
||||||
|
'department_id': department_id,
|
||||||
|
}
|
||||||
|
get_model("conv.sale.invoice").create(vals)
|
||||||
|
else:
|
||||||
|
res=get_model("account.account").search([["code","=",acc_code]])
|
||||||
|
if not res:
|
||||||
|
raise Exception("Account code not found: %s"%acc_code)
|
||||||
|
acc_id=res[0]
|
||||||
|
vals={
|
||||||
|
"conv_id": obj.id,
|
||||||
|
"number": number,
|
||||||
|
"ref": ref,
|
||||||
|
"contact_id": contact_id,
|
||||||
|
"date": date,
|
||||||
|
"due_date": due_date,
|
||||||
|
"amount_due": amount_due,
|
||||||
|
"account_id": acc_id,
|
||||||
|
"amount_cur": amount_cur,
|
||||||
|
'track_id': track_id,
|
||||||
|
'department_id': department_id,
|
||||||
|
}
|
||||||
|
get_model("conv.sale.invoice").create(vals)
|
||||||
|
return {
|
||||||
|
"next": {
|
||||||
|
"name": "conv_bal",
|
||||||
|
"active_id": obj.id,
|
||||||
|
"view_xml": "conv_bal2",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvBal.register()
|
|
@ -0,0 +1,12 @@
|
||||||
|
from netforce.model import Model, fields
|
||||||
|
|
||||||
|
class ConvSaleInvoice(Model):
|
||||||
|
_inherit="conv.sale.invoice"
|
||||||
|
_transient=True
|
||||||
|
_fields={
|
||||||
|
"department_id": fields.Many2One("clinic.department","Department"),
|
||||||
|
"track_id": fields.Many2One("account.track.categ","Track1"),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ConvSaleInvoice.register()
|
|
@ -681,6 +681,7 @@ class HDCase(Model):
|
||||||
"lines": [],
|
"lines": [],
|
||||||
"company_id": company_id,
|
"company_id": company_id,
|
||||||
'hdcase_credit': False,
|
'hdcase_credit': False,
|
||||||
|
'hdcase_reconcile': True,
|
||||||
}
|
}
|
||||||
vals["partner_id"]=partner.id
|
vals["partner_id"]=partner.id
|
||||||
vals['lines']=rmb_lines
|
vals['lines']=rmb_lines
|
||||||
|
@ -711,6 +712,7 @@ class HDCase(Model):
|
||||||
"company_id": company_id,
|
"company_id": company_id,
|
||||||
'partner_id':partner.id,
|
'partner_id':partner.id,
|
||||||
'hdcase_credit': True,
|
'hdcase_credit': True,
|
||||||
|
'hdcase_reconcile': True,
|
||||||
}
|
}
|
||||||
vals['lines']=normb_lines
|
vals['lines']=normb_lines
|
||||||
if patient_partner:
|
if patient_partner:
|
||||||
|
|
|
@ -333,6 +333,7 @@ class Shop(Model):
|
||||||
"currency_id": currency_id,
|
"currency_id": currency_id,
|
||||||
"company_id": company_id,
|
"company_id": company_id,
|
||||||
'partner_id': partner.id,
|
'partner_id': partner.id,
|
||||||
|
'hdcase_reconcile': True,
|
||||||
"lines": [],
|
"lines": [],
|
||||||
}
|
}
|
||||||
track_id=obj.branch_id.track_id.id
|
track_id=obj.branch_id.track_id.id
|
||||||
|
|
Loading…
Reference in New Issue