diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2025-05-17 12:04:41 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2025-05-17 12:04:41 +0700 |
| commit | f5d261ee2d263603d5becb32832765863c9dd9e8 (patch) | |
| tree | e60deede1f1ff730164874c1f556d5de7faa3019 | |
| parent | cb1e9095e79faddd7d2f006a7c7700bff37076fa (diff) | |
| parent | b0e740a60dee28cba5d0e0e3efb0c19f76441d72 (diff) | |
Merge branch 'odoo-backup' of bitbucket.org:altafixco/indoteknik-addons into odoo-backup
| -rw-r--r-- | indoteknik_custom/models/coretax_fatur.py | 88 | ||||
| -rwxr-xr-x | indoteknik_custom/models/purchase_order_line.py | 3 | ||||
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 10 | ||||
| -rwxr-xr-x | indoteknik_custom/views/purchase_order.xml | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/views/sale_order.xml | 8 |
5 files changed, 81 insertions, 29 deletions
diff --git a/indoteknik_custom/models/coretax_fatur.py b/indoteknik_custom/models/coretax_fatur.py index b4bffbd2..92ff1a72 100644 --- a/indoteknik_custom/models/coretax_fatur.py +++ b/indoteknik_custom/models/coretax_fatur.py @@ -4,19 +4,23 @@ 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", ) - + + export_file = fields.Binary(string="Export File", ) + export_filename = fields.Char(string="Export File", ) + + DISCOUNT_ACCOUNT_ID = 463 + 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 : + + if total_sum == 0: return '0000000000000000' # Hitung jumlah digit @@ -39,22 +43,16 @@ class CoretaxFaktur(models.Model): # 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' + 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') @@ -64,30 +62,72 @@ 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 + # Filter product + 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 + 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) + ) + ) + + # Calculate total product amount (before discount) + total_product_amount = sum(line.price_subtotal for line in product_lines) + if total_product_amount == 0: + total_product_amount = 1 # Avoid division by zero + + # Calculate total discount amount + 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 invoice.invoice_line_ids: - otherTaxBase = round(line.price_subtotal * (11/12)) if line.price_subtotal else 0 + + for line in product_lines: + # Calculate prorated discount + line_proportion = line.price_subtotal / total_product_amount + line_discount = total_discount_amount * line_proportion + + # unit_price = line.price_unit + 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_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, 'Price').text = str(round(subtotal / quantity, 2)) if subtotal else '0' + 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(round(otherTaxBase * 0.12, 2)) + ET.SubElement(good_service, 'VAT').text = str(vat_amount) ET.SubElement(good_service, 'STLGRate').text = '0' ET.SubElement(good_service, 'STLG').text = '0' diff --git a/indoteknik_custom/models/purchase_order_line.py b/indoteknik_custom/models/purchase_order_line.py index 033469b8..315795d5 100755 --- a/indoteknik_custom/models/purchase_order_line.py +++ b/indoteknik_custom/models/purchase_order_line.py @@ -385,3 +385,6 @@ class PurchaseOrderLine(models.Model): line.delivery_amt_line = delivery_amt * contribution else: line.delivery_amt_line = 0 + + + diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 66d7d148..bdf8f1eb 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -4,6 +4,7 @@ from odoo import fields, models, api, _ from odoo.exceptions import UserError, ValidationError from datetime import datetime, timedelta import logging, random, string, requests, math, json, re, qrcode, base64 +import pytz from io import BytesIO from collections import defaultdict @@ -330,6 +331,10 @@ class SaleOrder(models.Model): ('hold', 'Hold'), ('approve', 'Approve') ], tracking=True, string='State Cancel', copy=False) + date_hold = fields.Datetime(string='Date Hold', tracking=True, readonly=True, help='Waktu ketika SO di Hold' + ) + date_unhold = fields.Datetime(string='Date Unhold', tracking=True, readonly=True, help='Waktu ketika SO di Unhold' + ) def _compute_total_margin_excl_third_party(self): for order in self: @@ -368,9 +373,10 @@ class SaleOrder(models.Model): } } - def hold_unhold_qty_outgoing_so(self): + def hold_unhold_qty_outgoing_so(self): if self.hold_outgoing == True: self.hold_outgoing = False + self.date_unhold = fields.Datetime.now() else: pick = self.env['stock.picking'].search([ ('sale_id', '=', self.id), @@ -380,6 +386,8 @@ class SaleOrder(models.Model): for picking in pick: picking.do_unreserve() self.hold_outgoing = True + self.date_hold = fields.Datetime.now() + def _validate_uniform_taxes(self): for order in self: diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml index b58139c6..0fbbb5e7 100755 --- a/indoteknik_custom/views/purchase_order.xml +++ b/indoteknik_custom/views/purchase_order.xml @@ -36,7 +36,6 @@ </button> <button name="button_unlock" position="after"> <button name="create_bill_pelunasan" string="Create Bill Pelunasan" type="object" class="oe_highlight" attrs="{'invisible': [('state', 'not in', ('purchase', 'done')), ('bills_pelunasan_id', '!=', False)]}"/> - </button> <field name="date_order" position="before"> <field name="sale_order_id" attrs="{'readonly': [('state', 'not in', ['draft'])]}"/> diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 10682e93..a599a7b8 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -96,9 +96,11 @@ <attribute name="invisible">1</attribute> </field> <field name="user_id" position="after"> - <field name="hold_outgoing" readonly="1"/> - <field name="helper_by_id" readonly="1"/> - <field name="compute_fullfillment" invisible="1"/> + <field name="hold_outgoing" readonly="1" /> + <field name="date_hold" readonly="1" widget="datetime" /> + <field name="date_unhold" readonly="1" widget="datetime" /> + <field name="helper_by_id" readonly="1" /> + <field name="compute_fullfillment" invisible="1" /> </field> <field name="tag_ids" position="after"> <field name="eta_date_start"/> |
