diff --git a/netforce_clinic/layouts/clinic_tax_rate_form.xml b/netforce_clinic/layouts/clinic_tax_rate_form.xml new file mode 100644 index 0000000..74483a9 --- /dev/null +++ b/netforce_clinic/layouts/clinic_tax_rate_form.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/netforce_clinic/models/__init__.py b/netforce_clinic/models/__init__.py index d4e1fa4..cdbc078 100644 --- a/netforce_clinic/models/__init__.py +++ b/netforce_clinic/models/__init__.py @@ -128,3 +128,6 @@ from . import compute_labor_cost from . import login from . import sequence from . import report_shop +from . import account_tax_component +from . import report_thai_wht_certif +from . import num2word diff --git a/netforce_clinic/models/account_tax_component.py b/netforce_clinic/models/account_tax_component.py new file mode 100644 index 0000000..3350c00 --- /dev/null +++ b/netforce_clinic/models/account_tax_component.py @@ -0,0 +1,29 @@ +from netforce.model import Model, fields + +class TaxComponent(Model): + _inherit="account.tax.component" + _fields={ + "sequence": fields.Selection([ + ["1","1"], + ["2","2"], + ["3","3"], + ["4","4"], + ["4.1.1","4.1.1"], + ["4.1.2","4.1.2"], + ["4.1.3","4.1.3"], + ["4.1.4","4.1.4"], + ["4.2.1","4.2.1"], + ["4.2.2","4.2.2"], + ["4.2.3","4.2.3"], + ["4.2.4","4.2.4"], + ["4.2.5","4.2.5"], + ["5","5"], + ["6","6"], + ],"Sequence"), #report sequence + } + + _defaults={ + 'sequence': 5, + } + +TaxComponent.register() diff --git a/netforce_clinic/models/num2word.py b/netforce_clinic/models/num2word.py new file mode 100644 index 0000000..28a51aa --- /dev/null +++ b/netforce_clinic/models/num2word.py @@ -0,0 +1,85 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +sym={ + "en": { + "sep": " ", + "0": "zero", + "x": ["one","two","three","four","five" ,"six","seven","eight","nine"], + "1x": ["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"], + "x0": ["twenty","thirty","fourty","fifty","sixty","seventy","eighty","ninety"], + "100": "hundred", + "1K": "thousand", + "1M": "million", + }, + "th": { + "sep": "", + "0": "ศูนย์", + "x": ["หนึ่ง","สอง","สาม","สี่","ห้า" ,"หก","เจ็ด","แปด","เก้า"], + "x0": ["สิบ","ยี่สิบ","สามสิบ","สี่สิบ","ห้าสิบ","หกสิบ","เจ็ดสิบ","แปดสิบ","เก้าสิบ"], + "x1": "เอ็ด", + "100": "ร้อย", + "1K": "พัน", + "10K": "หมื่น", + "100K": "แสน", + "1M":"ล้าน", + } +} + +def num2word(n,l="en"): + #TODO:Support Thai Stang + if n==0: + return sym[l]["0"] + " " + elif n<10: + return sym[l]["x"][n-1] + elif n<100: + if l=="en": + if n<20: + return sym[l]["1x"][n-10] + else: + return sym[l]["x0"][n//10-2]+(n%10 and sym[l]["sep"]+num2word(n%10,l) or "") + elif l=="th": + return sym[l]["x0"][n//10-1]+(n%10 and (n%10==1 and sym[l]["x1"] or sym[l]["x"][n%10-1]) or "") + elif n<1000: + return sym[l]["x"][n//100-1]+sym[l]["sep"]+sym[l]["100"]+(n%100 and sym[l]["sep"]+num2word(n%100,l) or "") + + elif n<1000000: + if l=="en": + return num2word(n/1000,l)+sym[l]["sep"]+sym[l]["1K"]+(n%1000 and sym[l]["sep"]+num2word(n%1000,l) or "") + elif l=="th": + if n<10000: + return sym[l]["x"][n//1000-1]+sym[l]["1K"]+(n%1000 and num2word(n%1000,l) or "") + elif n<100000: + print(">>>>>",n) + return sym[l]["x"][n//10000-1]+sym[l]["10K"]+(n%10000 and num2word(n%10000,l) or "") + else: + return sym[l]["x"][n//100000-1]+sym[l]["100K"]+(n%100000 and num2word(n%100000,l) or "") + elif n<1000000000: + return num2word(n//1000000,l)+sym[l]["sep"]+sym[l]["1M"]+sym[l]["sep"]+(n%1000000 and num2word(n%1000000,l) or "") + else: + return "N/A" + +def num2word_th(n,l="th"): + base=0 + end=0 + number = n + if type(n) == type(''): + number=float(n) + word = '' + if type(number) in (type(0),type(0.0)): + number = ('%.2f'%number).split('.') + base = num2word(int(number[0]),l=l) + if int(number[1])!=0: + end = num2word(int(number[1]),l=l) + if base==0 and end==0: + word='ศุนย์บาทถ้วน' + if base!=0 and end==0: + word=base+'บาทถ้วน' + if base!=0 and end!=0: + word=base+'บาท'+end+'สตางค์' + return word + +if __name__ == '__main__': + import sys + n=sys.stdin.readline() + #print num2word_th(n) diff --git a/netforce_clinic/models/report_thai_wht_certif.py b/netforce_clinic/models/report_thai_wht_certif.py new file mode 100644 index 0000000..8f6ceb7 --- /dev/null +++ b/netforce_clinic/models/report_thai_wht_certif.py @@ -0,0 +1,97 @@ +from netforce.model import Model, fields, get_model +from datetime import * +from dateutil.relativedelta import * +from netforce.access import get_active_company +from . import num2word + +def fmt_thai_tax_no(tax_no): + s=tax_no or "" + s.replace("-","") + if len(s)<13: + s+=" "*(13-len(s)) + return s + +class ReportThaiWHTCertif(Model): + _inherit="report.thai.wht.certif" + + def get_report_data(self,ids,context={}): + if not ids: + return {} + obj=self.browse(ids)[0] + company_id=get_active_company() + comp=get_model("company").browse(company_id) + settings=get_model("settings").browse(1) + pmt=obj.payment_id + contact=pmt.partner_id + data={ + "company_tax_no": fmt_thai_tax_no(settings.tax_no), + "company_name": comp.name, + "dept_addr": settings.default_address_id.address_text.replace("\n",", "), # XXX + "tax_no": fmt_thai_tax_no(contact.tax_no), + "partner_name": contact.name, + "partner_addr": contact.default_address_id.address_text.replace("\n",", ") if contact.default_address_id else None, # XXX + "date": datetime.strptime(pmt.date,"%Y-%m-%d").strftime("%d/%m/%Y"), + "lines": [{}], # XXX + } + move=pmt.move_id + if not move: + raise Exception("Journal entry not found") + base={} + tax={} + contact_type=None + wht_no=None + for line in move.lines: + comp=line.tax_comp_id + if not comp: + continue + if comp.type!="wht" or comp.trans_type!="in": + continue + if not wht_no: + wht_no=line.tax_no + else: + if wht_no!=line.tax_no: + raise Exception("Multiple WHT numbers for same payment") + if not contact_type: + contact_type=comp.contact_type + else: + if contact_type!=comp.contact_type: + raise Exception("Different WHT contact types for same payment") + print('sequence ', comp.sequence) + exp_code=comp.sequence or "5" + #if comp.exp_type=="salary": + #exp_code="1" + #elif comp.exp_type=="commission": + #exp_code="2" + #elif comp.exp_type=="royalty": + #exp_code="3" + #elif comp.exp_type=="interest": + #exp_code="4" + #elif comp.exp_type in ("rental","service","transport","advert"): + #exp_code="5" + #else: + #exp_code="6" + if exp_code=="6": + data["desc"]=comp.description + base.setdefault(exp_code,0) + tax.setdefault(exp_code,0) + base[exp_code]+=line.tax_base + tax[exp_code]+=line.credit-line.debit + if not wht_no: + raise Exception("WHT number not found") + data["number"]=wht_no + if contact_type=="individual": + data["num_user1"]="x" + data["num_user2"]="" + elif contact_type=="company": + data["num_user1"]="" + data["num_user2"]="x" + for exp_code,amt in base.items(): + data["amt_"+exp_code]=amt + for exp_code,amt in tax.items(): + data["tax_"+exp_code]=amt + data["sum_amt"]=sum(base.values()) + data["sum_tax"]=sum(tax.values()) + data["total_word"]=num2word.num2word_th(data["sum_tax"],l='th') + return data + +ReportThaiWHTCertif.register() diff --git a/netforce_clinic/reports/report_labor_cost.xlsx b/netforce_clinic/reports/report_labor_cost.xlsx new file mode 100644 index 0000000..87e827a Binary files /dev/null and b/netforce_clinic/reports/report_labor_cost.xlsx differ diff --git a/netforce_clinic/templates/report_labor_cost.hbs b/netforce_clinic/templates/report_labor_cost.hbs index 84ffe7e..75c337d 100644 --- a/netforce_clinic/templates/report_labor_cost.hbs +++ b/netforce_clinic/templates/report_labor_cost.hbs @@ -1,6 +1,7 @@

จาก {{date_from}} ถึง {{date_to}} +

{{#ifeq report_type "detail"}}