Files
encoach_frontend_new_v3/odoo/addons/l10n_ph/utils.py
Yamen Ahmad 3e83d8d7d5 feat: add complete EnCoach backend — Odoo 19 + all addons
Includes:
- Odoo 19 framework (odoo/)
- 27 custom EnCoach addons (new_project/custom_addons/)
  - encoach_core, encoach_api, encoach_lms_api, encoach_adaptive_api
  - encoach_exam, encoach_taxonomy, encoach_adaptive, encoach_assignment
  - encoach_ai, encoach_ai_grading, encoach_ai_generation, encoach_ai_media
  - encoach_courseware, encoach_communication, encoach_subscription
  - encoach_notification, encoach_approval, encoach_branding
  - encoach_classroom, encoach_registration, encoach_stats
  - encoach_faq, encoach_ticket, encoach_training, encoach_resources
  - encoach_adaptive_ai, encoach_sis
- 21 OpenEduCat Enterprise modules (new_project/enterprise-19/)
- 14 OpenEduCat Community modules (new_project/openeducat_erp-19.0/)
- Configuration: odoo.conf, requirements.txt, scripts
- 200+ REST API endpoints with JWT authentication
- SRS and test documentation

Made-with: Cursor
2026-04-01 17:10:04 +04:00

89 lines
3.3 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import io
import re
from odoo.tools.misc import format_date
from odoo.tools import html2plaintext
COLUMN_HEADER_MAP = {
"Reporting_Month": "invoice_date",
"Vendor_TIN": "vat",
"branchCode": "branch_code",
"companyName": "company_name",
"surName": "last_name",
"firstName": "first_name",
"middleName": "middle_name",
"address": "address",
"zip_code": "zip",
"nature": "tax_description",
"ATC": "atc",
"income_payment": "price_subtotal",
"ewt_rate": "amount",
"tax_amount": "tax_amount",
}
def _export_bir_2307(sheet_title, moves, file_format='xlsx'):
output = io.BytesIO()
if file_format == 'xls':
import xlwt # noqa: PLC0415
workbook = xlwt.Workbook(encoding='utf-8')
worksheet = workbook.add_sheet(sheet_title)
def write_row(row, col, data):
for token in data:
worksheet.write(row, col, token)
col += 1
else:
import xlsxwriter # noqa: PLC0415
workbook = xlsxwriter.Workbook(output, {
'in_memory': True,
'strings_to_formulas': False, # As we need to give a default value when using formulas, we need to handle them manually so this is not needed.
})
worksheet = workbook.add_worksheet(sheet_title)
write_row = worksheet.write_row
write_row(0, 0, list(COLUMN_HEADER_MAP.keys()))
worksheet_row = 1
for move in moves:
partner = move.commercial_partner_id
partner_address_info = [partner.street, partner.street2, partner.city, partner.state_id.name, partner.country_id.name]
first_name = middle_name = last_name = ''
if partner.company_type == 'person':
first_name = partner.first_name or ''
middle_name = partner.middle_name or ''
last_name = partner.last_name or ''
values = {
'invoice_date': format_date(move.env, move.invoice_date, date_format="MM/dd/yyyy"),
'vat': re.sub(r'-', '', partner.vat)[:9] if partner.vat else '',
'branch_code': partner.branch_code or '000',
'company_name': partner.name if partner.company_type == 'company' else '',
'first_name': first_name,
'middle_name': middle_name,
'last_name': last_name,
'address': ', '.join([val for val in partner_address_info if val]),
'zip': partner.zip or '',
}
aggregated_taxes = move._prepare_invoice_aggregated_taxes()
for invoice_line, tax_details_for_line in aggregated_taxes['tax_details_per_record'].items():
for tax, tax_detail in tax_details_for_line['tax_details'].items():
if not tax.l10n_ph_atc:
continue
values['tax_description'] = html2plaintext(tax.description) or ''
values['atc'] = tax.l10n_ph_atc
values['price_subtotal'] = tax_detail['base_amount']
values['amount'] = abs(tax.amount)
values['tax_amount'] = abs(tax_detail['tax_amount'])
write_row(worksheet_row, 0, [values[field] for field in COLUMN_HEADER_MAP.values()])
worksheet_row += 1
if file_format == 'xls':
workbook.save(output)
else:
workbook.close()
output.seek(0)
return output.read()