summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models/coretax_fatur.py
blob: b4bffbd2bc76ccce3425a394af33d241c74a6dbe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from odoo import models, fields
import xml.etree.ElementTree as ET
from xml.dom import minidom
import base64
import re

class CoretaxFaktur(models.Model):
    _name = 'coretax.faktur'
    _description = 'Export Faktur ke XML'
    
    export_file = fields.Binary(string="Export File",  )
    export_filename = fields.Char(string="Export File",  )
    
    def validate_and_format_number(slef, input_number):
        # Hapus semua karakter non-digit
        cleaned_number = re.sub(r'\D', '', input_number)
        
        total_sum = sum(int(char) for char in cleaned_number)
        if total_sum == 0 :
            return '0000000000000000'

        # Hitung jumlah digit
        digit_count = len(cleaned_number)

        # Jika jumlah digit kurang dari 15, tambahkan nol di depan
        if digit_count < 16:
            cleaned_number = cleaned_number.zfill(16)

        return cleaned_number

    def generate_xml(self, invoices=None):
        # Buat root XML
        root = ET.Element('TaxInvoiceBulk', {
            'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance",
            'xsi:noNamespaceSchemaLocation': "TaxInvoice.xsd"
        })
        ET.SubElement(root, 'TIN').text = '0742260227086000'

        # Tambahkan elemen ListOfTaxInvoice
        list_of_tax_invoice = ET.SubElement(root, 'ListOfTaxInvoice')

        # Dapatkan data faktur
        # inv_obj = self.env['account.move']
        # invoices = inv_obj.search([('is_efaktur_exported','=',True),
        #                            ('state','=','posted'),
        #                            ('efaktur_id','!=', False),
        #                            ('move_type','=','out_invoice')], limit = 5)
        
        for invoice in invoices:
            tax_invoice = ET.SubElement(list_of_tax_invoice, 'TaxInvoice')
            buyerTIN = self.validate_and_format_number(invoice.partner_id.npwp)
            nitku = invoice.partner_id.nitku
            formula = nitku if nitku else buyerTIN.ljust(len(buyerTIN) + 6, '0')
            buyerIDTKU = formula if sum(int(char) for char in buyerTIN) > 0  else '000000'

            # Tambahkan elemen faktur
            ET.SubElement(tax_invoice, 'TaxInvoiceDate').text = invoice.invoice_date.strftime('%Y-%m-%d') if invoice.invoice_date else ''
            ET.SubElement(tax_invoice, 'TaxInvoiceOpt').text = 'Normal'
            ET.SubElement(tax_invoice, 'TrxCode').text = '04'
            ET.SubElement(tax_invoice, 'AddInfo')
            ET.SubElement(tax_invoice, 'CustomDoc')
            ET.SubElement(tax_invoice, 'CustomDocMonthYear')
            ET.SubElement(tax_invoice, 'RefDesc').text = invoice.name
            ET.SubElement(tax_invoice, 'FacilityStamp')
            ET.SubElement(tax_invoice, 'SellerIDTKU').text = '0742260227086000000000'
            ET.SubElement(tax_invoice, 'BuyerTin').text = buyerTIN
            ET.SubElement(tax_invoice, 'BuyerDocument').text = 'TIN' if sum(int(char) for char in buyerTIN) > 0 else 'Other ID'
            ET.SubElement(tax_invoice, 'BuyerCountry').text = 'IDN'
            ET.SubElement(tax_invoice, 'BuyerDocumentNumber').text = '-' if sum(int(char) for char in buyerTIN) > 0 else str(invoice.partner_id.id)
            ET.SubElement(tax_invoice, 'BuyerName').text = invoice.partner_id.nama_wajib_pajak or ''
            ET.SubElement(tax_invoice, 'BuyerAdress').text = invoice.partner_id.alamat_lengkap_text or ''
            ET.SubElement(tax_invoice, 'BuyerEmail').text = invoice.partner_id.email or ''
            ET.SubElement(tax_invoice, 'BuyerIDTKU').text = buyerIDTKU

            # Tambahkan elemen ListOfGoodService
            list_of_good_service = ET.SubElement(tax_invoice, 'ListOfGoodService')
            for line in invoice.invoice_line_ids:
                otherTaxBase = round(line.price_subtotal * (11/12)) if line.price_subtotal else 0
                good_service = ET.SubElement(list_of_good_service, 'GoodService')
                ET.SubElement(good_service, 'Opt').text = 'A'
                ET.SubElement(good_service, 'Code').text = '000000'
                ET.SubElement(good_service, 'Name').text = line.name
                ET.SubElement(good_service, 'Unit').text = 'UM.0018'
                ET.SubElement(good_service, 'Price').text = str(round(line.price_subtotal/line.quantity, 2)) if line.price_subtotal else '0'
                ET.SubElement(good_service, 'Qty').text = str(line.quantity)
                ET.SubElement(good_service, 'TotalDiscount').text = '0'
                ET.SubElement(good_service, 'TaxBase').text = str(round(line.price_subtotal)) if line.price_subtotal else '0'
                ET.SubElement(good_service, 'OtherTaxBase').text = str(otherTaxBase)
                ET.SubElement(good_service, 'VATRate').text = '12'
                ET.SubElement(good_service, 'VAT').text = str(round(otherTaxBase * 0.12, 2))
                ET.SubElement(good_service, 'STLGRate').text = '0'
                ET.SubElement(good_service, 'STLG').text = '0'

        # Pretty print XML
        xml_str = ET.tostring(root, encoding='utf-8')
        xml_pretty = minidom.parseString(xml_str).toprettyxml(indent="    ")
        return xml_pretty

    def export_to_download(self, invoices):
        # Generate XML content
        xml_content = self.generate_xml(invoices)

        # Encode content to Base64
        xml_encoded = base64.b64encode(xml_content.encode('utf-8'))

        # Buat attachment untuk XML
        attachment = self.env['ir.attachment'].create({
            'name': 'Faktur_XML.xml',
            'type': 'binary',
            'datas': xml_encoded,
            'mimetype': 'application/xml',
            'store_fname': 'faktur_xml.xml',
        })

        # Kembalikan URL untuk download dengan header 'Content-Disposition'
        response = {
            'type': 'ir.actions.act_url',
            'url': '/web/content/{}?download=true'.format(attachment.id),
            'target': 'self',
        }

        return response