refactor: ship Custom Fields and Property Setters as module customizations
Move the Sales Invoice withholding fields and both Property Setters from
fixtures to default_thai_company/custom/{sales_invoice,payment_entry}.json
with sync_on_migrate. sync_customizations updates Custom Fields in place
instead of the delete/re-insert that fixtures do on every migrate.
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"custom_fields": [],
|
||||
"custom_perms": [],
|
||||
"doctype": "Payment Entry",
|
||||
"links": [],
|
||||
"property_setters": [
|
||||
{
|
||||
"_assign": null,
|
||||
"_comments": null,
|
||||
"_liked_by": null,
|
||||
"_user_tags": null,
|
||||
"creation": "2026-09-11 17:18:28.670630",
|
||||
"default_value": null,
|
||||
"doc_type": "Payment Entry",
|
||||
"docstatus": 0,
|
||||
"doctype_or_field": "DocField",
|
||||
"field_name": "apply_tax_withholding_amount",
|
||||
"idx": 0,
|
||||
"is_system_generated": 0,
|
||||
"modified": "2026-09-11 12:00:00",
|
||||
"modified_by": "Administrator",
|
||||
"module": null,
|
||||
"name": "Payment Entry-apply_tax_withholding_amount-depends_on",
|
||||
"owner": "Administrator",
|
||||
"property": "depends_on",
|
||||
"property_type": "Data",
|
||||
"row_name": null,
|
||||
"value": "eval:doc.party_type == 'Supplier' || (doc.party_type == 'Customer' && doc.payment_type == 'Receive')"
|
||||
}
|
||||
],
|
||||
"sync_on_migrate": 1
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
{
|
||||
"custom_fields": [
|
||||
{
|
||||
"_assign": null,
|
||||
"_comments": null,
|
||||
"_liked_by": null,
|
||||
"_user_tags": null,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"columns": 0,
|
||||
"creation": "2026-09-11 17:18:48.182536",
|
||||
"default": null,
|
||||
"depends_on": "eval:doc.tax_withholding_category",
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"dt": "Sales Invoice",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "amount_after_withholding",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"idx": 80,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "withholding_tax_amount",
|
||||
"is_system_generated": 0,
|
||||
"is_virtual": 0,
|
||||
"label": "Net Payable After Withholding Tax",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-09-11 17:18:48.182536",
|
||||
"modified_by": "Administrator",
|
||||
"module": null,
|
||||
"name": "Sales Invoice-amount_after_withholding",
|
||||
"no_copy": 1,
|
||||
"non_negative": 0,
|
||||
"options": "currency",
|
||||
"owner": "Administrator",
|
||||
"permlevel": 0,
|
||||
"placeholder": null,
|
||||
"precision": null,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 1,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"read_only_depends_on": null,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"_assign": null,
|
||||
"_comments": null,
|
||||
"_liked_by": null,
|
||||
"_user_tags": null,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"columns": 0,
|
||||
"creation": "2026-09-11 17:18:44.710456",
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"dt": "Sales Invoice",
|
||||
"fetch_from": "customer.tax_withholding_category",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "tax_withholding_category",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"idx": 57,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "taxes_and_charges",
|
||||
"is_system_generated": 0,
|
||||
"is_virtual": 0,
|
||||
"label": "Tax Withholding Category",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-09-11 18:00:00",
|
||||
"modified_by": "Administrator",
|
||||
"module": null,
|
||||
"name": "Sales Invoice-tax_withholding_category",
|
||||
"no_copy": 0,
|
||||
"non_negative": 0,
|
||||
"options": "Tax Withholding Category",
|
||||
"owner": "Administrator",
|
||||
"permlevel": 0,
|
||||
"placeholder": null,
|
||||
"precision": null,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"read_only_depends_on": null,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"_assign": null,
|
||||
"_comments": null,
|
||||
"_liked_by": null,
|
||||
"_user_tags": null,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": null,
|
||||
"columns": 0,
|
||||
"creation": "2026-09-11 17:18:47.244523",
|
||||
"default": null,
|
||||
"depends_on": "eval:doc.tax_withholding_category",
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"dt": "Sales Invoice",
|
||||
"fetch_from": null,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "withholding_tax_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"hide_border": 0,
|
||||
"hide_days": 0,
|
||||
"hide_seconds": 0,
|
||||
"idx": 79,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_preview": 0,
|
||||
"in_standard_filter": 0,
|
||||
"insert_after": "rounded_total",
|
||||
"is_system_generated": 0,
|
||||
"is_virtual": 0,
|
||||
"label": "Withholding Tax",
|
||||
"length": 0,
|
||||
"link_filters": null,
|
||||
"mandatory_depends_on": null,
|
||||
"modified": "2026-09-11 18:00:00",
|
||||
"modified_by": "Administrator",
|
||||
"module": null,
|
||||
"name": "Sales Invoice-withholding_tax_amount",
|
||||
"no_copy": 1,
|
||||
"non_negative": 0,
|
||||
"options": "currency",
|
||||
"owner": "Administrator",
|
||||
"permlevel": 0,
|
||||
"placeholder": null,
|
||||
"precision": null,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 1,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"read_only_depends_on": null,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"show_dashboard": 0,
|
||||
"sort_options": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": null
|
||||
}
|
||||
],
|
||||
"custom_perms": [],
|
||||
"doctype": "Sales Invoice",
|
||||
"links": [],
|
||||
"property_setters": [
|
||||
{
|
||||
"_assign": null,
|
||||
"_comments": null,
|
||||
"_liked_by": null,
|
||||
"_user_tags": null,
|
||||
"creation": "2026-09-11 17:18:28.581896",
|
||||
"default_value": null,
|
||||
"doc_type": "Sales Invoice",
|
||||
"docstatus": 0,
|
||||
"doctype_or_field": "DocType",
|
||||
"field_name": null,
|
||||
"idx": 0,
|
||||
"is_system_generated": 1,
|
||||
"modified": "2026-09-10 13:55:13.996942",
|
||||
"modified_by": "Administrator",
|
||||
"module": null,
|
||||
"name": "Sales Invoice-main-default_print_format",
|
||||
"owner": "Administrator",
|
||||
"property": "default_print_format",
|
||||
"property_type": "Data",
|
||||
"row_name": null,
|
||||
"value": "Default Standard Sales Invoice"
|
||||
}
|
||||
],
|
||||
"sync_on_migrate": 1
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
[
|
||||
{
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Sales Invoice",
|
||||
"fetch_from": "customer.tax_withholding_category",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "tax_withholding_category",
|
||||
"fieldtype": "Link",
|
||||
"insert_after": "taxes_and_charges",
|
||||
"label": "Tax Withholding Category",
|
||||
"modified": "2026-09-11 18:00:00.000000",
|
||||
"name": "Sales Invoice-tax_withholding_category",
|
||||
"options": "Tax Withholding Category",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.tax_withholding_category",
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Sales Invoice",
|
||||
"fieldname": "withholding_tax_amount",
|
||||
"fieldtype": "Currency",
|
||||
"insert_after": "rounded_total",
|
||||
"label": "Withholding Tax",
|
||||
"modified": "2026-09-11 18:00:00.000000",
|
||||
"name": "Sales Invoice-withholding_tax_amount",
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"print_hide_if_no_value": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"bold": 1,
|
||||
"depends_on": "eval:doc.tax_withholding_category",
|
||||
"docstatus": 0,
|
||||
"doctype": "Custom Field",
|
||||
"dt": "Sales Invoice",
|
||||
"fieldname": "amount_after_withholding",
|
||||
"fieldtype": "Currency",
|
||||
"insert_after": "withholding_tax_amount",
|
||||
"label": "Net Payable After Withholding Tax",
|
||||
"modified": "2026-09-11 18:00:00.000000",
|
||||
"name": "Sales Invoice-amount_after_withholding",
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"print_hide_if_no_value": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
]
|
||||
@@ -1,34 +0,0 @@
|
||||
[
|
||||
{
|
||||
"default_value": null,
|
||||
"doc_type": "Sales Invoice",
|
||||
"docstatus": 0,
|
||||
"doctype": "Property Setter",
|
||||
"doctype_or_field": "DocType",
|
||||
"field_name": null,
|
||||
"is_system_generated": 1,
|
||||
"modified": "2026-09-10 13:55:13.996942",
|
||||
"module": null,
|
||||
"name": "Sales Invoice-main-default_print_format",
|
||||
"property": "default_print_format",
|
||||
"property_type": "Data",
|
||||
"row_name": null,
|
||||
"value": "Default Standard Sales Invoice"
|
||||
},
|
||||
{
|
||||
"default_value": null,
|
||||
"doc_type": "Payment Entry",
|
||||
"docstatus": 0,
|
||||
"doctype": "Property Setter",
|
||||
"doctype_or_field": "DocField",
|
||||
"field_name": "apply_tax_withholding_amount",
|
||||
"is_system_generated": 0,
|
||||
"modified": "2026-09-11 12:00:00.000000",
|
||||
"module": null,
|
||||
"name": "Payment Entry-apply_tax_withholding_amount-depends_on",
|
||||
"property": "depends_on",
|
||||
"property_type": "Data",
|
||||
"row_name": null,
|
||||
"value": "eval:doc.party_type == 'Supplier' || (doc.party_type == 'Customer' && doc.payment_type == 'Receive')"
|
||||
}
|
||||
]
|
||||
@@ -84,38 +84,13 @@ jinja = {
|
||||
# Fixtures
|
||||
# --------
|
||||
|
||||
# Custom Fields and Property Setters live in default_thai_company/custom/*.json
|
||||
# (synced in place on install and migrate); fixtures are for whole documents.
|
||||
fixtures = [
|
||||
{"doctype": "Letter Head", "filters": [["name", "in", ["Default Letter Head"]]]},
|
||||
{"doctype": "Address Template", "filters": [["name", "in", ["Thailand"]]]},
|
||||
{"doctype": "Print Format", "filters": [["name", "in", ["Default Standard Sales Invoice"]]]},
|
||||
{
|
||||
"doctype": "Property Setter",
|
||||
"filters": [
|
||||
[
|
||||
"name",
|
||||
"in",
|
||||
[
|
||||
"Sales Invoice-main-default_print_format",
|
||||
"Payment Entry-apply_tax_withholding_amount-depends_on",
|
||||
],
|
||||
]
|
||||
],
|
||||
},
|
||||
{"doctype": "Tax Withholding Category", "filters": [["name", "like", "WHT %"]]},
|
||||
{
|
||||
"doctype": "Custom Field",
|
||||
"filters": [
|
||||
[
|
||||
"name",
|
||||
"in",
|
||||
[
|
||||
"Sales Invoice-tax_withholding_category",
|
||||
"Sales Invoice-withholding_tax_amount",
|
||||
"Sales Invoice-amount_after_withholding",
|
||||
],
|
||||
]
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
# Installation
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from frappe.modules.import_file import import_file_by_path
|
||||
from frappe.modules.utils import sync_customizations_for_doctype
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
from frappe.utils import nowdate
|
||||
|
||||
@@ -10,7 +13,7 @@ ABBR = "_TWC"
|
||||
CUSTOMER = "_Test WHT Customer"
|
||||
ITEM = "_Test WHT Service"
|
||||
FIXTURE = frappe.get_app_path("default_thai_company", "fixtures", "tax_withholding_category.json")
|
||||
CUSTOM_FIELDS = frappe.get_app_path("default_thai_company", "fixtures", "custom_field.json")
|
||||
CUSTOM_DIR = frappe.get_app_path("default_thai_company", "default_thai_company", "custom")
|
||||
|
||||
|
||||
class TestTaxWithholding(FrappeTestCase):
|
||||
@@ -20,8 +23,9 @@ class TestTaxWithholding(FrappeTestCase):
|
||||
# Fixture categories must exist before the company is created so the
|
||||
# Company hook has something to link; force=True re-imports.
|
||||
import_file_by_path(FIXTURE, force=True, data_import=True)
|
||||
import_file_by_path(CUSTOM_FIELDS, force=True, data_import=True)
|
||||
frappe.clear_cache(doctype="Sales Invoice")
|
||||
for fname in ("sales_invoice.json", "payment_entry.json"):
|
||||
with open(f"{CUSTOM_DIR}/{fname}") as f:
|
||||
sync_customizations_for_doctype(json.load(f), CUSTOM_DIR, fname)
|
||||
|
||||
frappe.get_doc(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user