diff options
| author | Indoteknik . <it@fixcomart.co.id> | 2025-06-25 14:54:16 +0700 |
|---|---|---|
| committer | Indoteknik . <it@fixcomart.co.id> | 2025-06-25 14:54:16 +0700 |
| commit | e30c678ed5eb53f67d95d02645f6662462ec07d0 (patch) | |
| tree | 1412fba94e67702328b1f7725ac6220cbc5d316b | |
| parent | e483cf1634b16df7c9ecc4a89007dbc253b68da1 (diff) | |
(andri) kembalikan perhitungan coretax
| -rw-r--r-- | indoteknik_custom/models/coretax_fatur.py | 105 |
1 files changed, 80 insertions, 25 deletions
diff --git a/indoteknik_custom/models/coretax_fatur.py b/indoteknik_custom/models/coretax_fatur.py index 4397d7a1..54eb0f8e 100644 --- a/indoteknik_custom/models/coretax_fatur.py +++ b/indoteknik_custom/models/coretax_fatur.py @@ -51,7 +51,8 @@ class CoretaxFaktur(models.Model): 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, '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') @@ -61,49 +62,103 @@ class CoretaxFaktur(models.Model): 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, '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, '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 - # Ambil lines - product_lines = invoice.invoice_line_ids.filtered( - lambda l: not l.display_type and l.product_id and l.account_id and l.account_id.id != self.DISCOUNT_ACCOUNT_ID and l.quantity != -1 + # Handle product lines based on down_payments flag + if down_payments and invoice.invoice_origin: + # Get from sale.order.line for down payment + sale_order = invoice.sale_id + if sale_order: + product_lines = sale_order.order_line.filtered( + lambda l: l.product_id and not l.is_downpayment and not l.display_type and not l.product_id.id == 229625 + ) + # Convert sale order lines to invoice-like format + converted_lines = [] + for line in product_lines: + converted_lines.append({ + 'name': line.name, + 'product_id': line.product_id, + 'price_subtotal': line.price_subtotal, + 'quantity': line.product_uom_qty, + 'price_unit': line.price_unit, + 'account_id': line.order_id.analytic_account_id or False, + }) + product_lines = converted_lines + else: + product_lines = [] + else: + # Normal case - get from invoice lines + product_lines = invoice.invoice_line_ids.filtered( + lambda l: not l.display_type and hasattr(l, 'account_id') and + l.account_id and l.product_id and + l.account_id.id != self.DISCOUNT_ACCOUNT_ID and + l.quantity != -1 + ) + + # Filter discount (always from invoice) + discount_lines = invoice.invoice_line_ids.filtered( + lambda l: not l.display_type and ( + (hasattr(l, 'account_id') and l.account_id and + l.account_id.id == self.DISCOUNT_ACCOUNT_ID) or + (l.quantity == -1) + ) ) - invoice_untaxed = invoice.amount_untaxed - if invoice_untaxed == 0: - invoice_untaxed = 1 # Hindari div zero + # Calculate totals + total_product_amount = sum(line.get('price_subtotal', 0) if isinstance(line, dict) + else line.price_subtotal for line in product_lines) + if total_product_amount == 0: + total_product_amount = 1 # Avoid division by zero + + total_discount_amount = abs(sum(line.price_subtotal for line in discount_lines)) # Tambahkan elemen ListOfGoodService list_of_good_service = ET.SubElement(tax_invoice, 'ListOfGoodService') for line in product_lines: - line_price_subtotal = line.price_subtotal - line_quantity = line.quantity - line_name = line.name - line_price_unit = line.price_unit - - # Hitung proporsi & tax base per line - line_proportion = line_price_subtotal / invoice_untaxed - line_tax_base = round(invoice.amount_untaxed * line_proportion, 2) - other_tax_base = round(line_tax_base * (11 / 12), 2) - vat_amount = round(other_tax_base * 0.12, 2) - - # Isi XML + # Handle both dict (converted sale lines) and normal invoice lines + if isinstance(line, dict): + line_price_subtotal = line['price_subtotal'] + line_quantity = line['quantity'] + line_name = line['name'] + line_price_unit = line['price_unit'] + else: + line_price_subtotal = line.price_subtotal + line_quantity = line.quantity + line_name = line.name + line_price_unit = line.price_unit + + # Calculate prorated discount + line_proportion = line_price_subtotal / total_product_amount + line_discount = total_discount_amount * line_proportion + + subtotal = line_price_subtotal + quantity = line_quantity + total_discount = round(line_discount, 2) + + # Calculate other tax values + otherTaxBase = round(subtotal * (11 / 12), 2) if subtotal else 0 + vat_amount = round(otherTaxBase * 0.12, 2) + + # Create the line in XML 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_unit, 2)) if line_price_unit 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(line_tax_base) - ET.SubElement(good_service, 'OtherTaxBase').text = str(other_tax_base) + ET.SubElement(good_service, 'Qty').text = str(quantity) + ET.SubElement(good_service, 'TotalDiscount').text = str(total_discount) + ET.SubElement(good_service, 'TaxBase').text = str(round(subtotal)) if 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(vat_amount) ET.SubElement(good_service, 'STLGRate').text = '0' |
