Skip to content

Commit

Permalink
feat: allow VAT ID Check for Customers
Browse files Browse the repository at this point in the history
  • Loading branch information
barredterra committed Jan 15, 2024
1 parent 9b12af5 commit 70571e3
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,22 @@

frappe.ui.form.on("VAT ID Check", {
setup: function (frm) {
frm.set_query("customer_address", function (doc) {
frm.add_fetch("party", "tax_id", "party_vat_id");

frm.set_query("party_type", function (doc) {
return {
filters: {
name: ["in", ["Customer", "Supplier"]],
},
};
});

frm.set_query("party_address", function (doc) {
return {
query: "frappe.contacts.doctype.address.address.address_query",
filters: {
link_doctype: "Customer",
link_name: doc.customer,
link_doctype: doc.party_type,
link_name: doc.party,
},
};
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"customer",
"customer_vat_id",
"customer_address",
"party_type",
"party",
"party_vat_id",
"party_address",
"column_break_hmgxr",
"status",
"section_break_6ctcl",
Expand All @@ -33,14 +34,6 @@
"request_id"
],
"fields": [
{
"fieldname": "customer",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Customer",
"options": "Customer",
"set_only_once": 1
},
{
"fieldname": "column_break_hmgxr",
"fieldtype": "Column Break"
Expand Down Expand Up @@ -83,17 +76,6 @@
"fieldtype": "Section Break",
"label": "Result"
},
{
"fetch_from": "customer.tax_id",
"fetch_if_empty": 1,
"fieldname": "customer_vat_id",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Customer VAT ID",
"reqd": 1,
"set_only_once": 1
},
{
"fetch_from": "company.tax_id",
"fetch_if_empty": 1,
Expand All @@ -110,13 +92,6 @@
"options": "Planned\nRunning\nCompleted\nService Unavailable\nInvalid Input\nError",
"read_only": 1
},
{
"fieldname": "customer_address",
"fieldtype": "Link",
"label": "Customer Address",
"options": "Address",
"set_only_once": 1
},
{
"fetch_from": "customer.customer_name",
"fetch_if_empty": 1,
Expand Down Expand Up @@ -207,10 +182,42 @@
{
"fieldname": "column_break_cjvyk",
"fieldtype": "Column Break"
},
{
"fieldname": "party_type",
"fieldtype": "Link",
"label": "Party Type",
"options": "DocType"
},
{
"fieldname": "party",
"fieldtype": "Dynamic Link",
"in_standard_filter": 1,
"label": "Party",
"options": "party_type",
"set_only_once": 1
},
{
"fieldname": "party_address",
"fieldtype": "Link",
"label": "Party Address",
"options": "Address",
"set_only_once": 1
},
{
"fetch_from": "customer.tax_id",
"fetch_if_empty": 1,
"fieldname": "party_vat_id",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Party VAT ID",
"reqd": 1,
"set_only_once": 1
}
],
"links": [],
"modified": "2023-07-14 19:27:17.103880",
"modified": "2024-01-15 19:51:41.796509",
"modified_by": "Administrator",
"module": "ERPNext Germany",
"name": "VAT ID Check",
Expand Down Expand Up @@ -266,5 +273,5 @@
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"title_field": "customer_vat_id"
"title_field": "party_vat_id"
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def before_insert(self):
)
self.requester_vat_id = f"{requester_country_code}{requester_vat_number}"

country_code, vat_number = parse_vat_id(self.customer_vat_id)
self.customer_vat_id = f"{country_code}{vat_number}"
country_code, vat_number = parse_vat_id(self.party_vat_id)
self.party_vat_id = f"{country_code}{vat_number}"

def after_insert(self):
frappe.enqueue(
Expand All @@ -39,7 +39,7 @@ def run_check(doc: VATIDCheck):
return

try:
country_code, vat_number = parse_vat_id(doc.customer_vat_id)
country_code, vat_number = parse_vat_id(doc.party_vat_id)
except ValueError:
doc.db_set({"status": "Invalid Input", "is_valid": False}, notify=True)
return
Expand Down
12 changes: 11 additions & 1 deletion erpnext_germany/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,17 @@ def get_register_fields(insert_after: str):
"parenttype": "Customize Form",
"group": "Pre Sales",
"link_doctype": "VAT ID Check",
"link_fieldname": "customer",
"link_fieldname": "party",
"custom": 1,
},
{
"doctype": "DocType Link",
"parent": "Supplier",
"parentfield": "links",
"parenttype": "Customize Form",
"group": "Vendor Evaluation",
"link_doctype": "VAT ID Check",
"link_fieldname": "party",
"custom": 1,
},
]
4 changes: 4 additions & 0 deletions erpnext_germany/patches.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[pre_model_sync]

[post_model_sync]
execute:from erpnext_germany.install import after_install; after_install() # 7
erpnext_germany.patches.add_tax_exemption_reason_fields
execute:from erpnext_germany.install import insert_custom_records; insert_custom_records()
erpnext_germany.patches.dynamic_party_in_vat_id_check
41 changes: 41 additions & 0 deletions erpnext_germany/patches/dynamic_party_in_vat_id_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import frappe
from frappe.model.utils.rename_field import rename_field


def execute():
"""Copy data to renamed fields in VAT ID Check.
party_type -> "Customer",
customer -> party,
customer_vat_id -> party_vat_id,
customer_address -> party_address,
Add link to Supplier connections.
Update link in Customer connections.
"""
dt = "VAT ID Check"

frappe.db.sql("UPDATE `tabVAT ID Check` SET party_type = 'Customer'")

rename_field(dt, "customer", "party")
rename_field(dt, "customer_vat_id", "party_vat_id")
rename_field(dt, "customer_address", "party_address")

# Add link to Supplier connections
frappe.get_doc(
{
"doctype": "DocType Link",
"parent": "Supplier",
"parentfield": "links",
"parenttype": "Customize Form",
"group": "Vendor Evaluation",
"link_doctype": dt,
"link_fieldname": "party",
"custom": 1,
}
).insert(ignore_if_duplicate=True)

# Update link in Customer connections
customer_link = frappe.db.exists("DocType Link", {"link_doctype": dt, "link_fieldname": "customer"})
if customer_link:
frappe.db.set_value("DocType Link", customer_link, "link_fieldname", "party")
82 changes: 61 additions & 21 deletions erpnext_germany/tasks.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,30 @@
import frappe
from erpnext import get_default_company
from erpnext_germany.utils.eu_vat import parse_vat_id
from frappe.query_builder import DocType
from pypika import Interval
from pypika import functions as fn


def all():
check_some_customers()
check_some_parties()


def get_customers(batch_size=4):
"""Return a list of n customers who didn't have their VAT ID checked in the last 3 months."""
from frappe.query_builder import DocType
from pypika import Interval
from pypika import functions as fn

customers = DocType("Customer")
vat_id_checks = DocType("VAT ID Check")
last_check = (
frappe.qb.from_(vat_id_checks)
.select(
vat_id_checks.customer,
fn.Max(vat_id_checks.creation).as_("creation"),
)
.groupby(vat_id_checks.customer)
)
last_check = get_last_check_query("Customer")

return (
frappe.qb.from_(customers)
.left_join(last_check)
.on(customers.name == last_check.customer)
.on(customers.name == last_check.party)
.select(
fn.LiteralValue("'Customer'"),
customers.name,
customers.customer_name,
customers.customer_primary_address,
customers.tax_id
customers.tax_id,
)
.where(
customers.tax_id.notnull()
Expand All @@ -47,22 +39,70 @@ def get_customers(batch_size=4):
)


def check_some_customers():
def get_suppliers(batch_size=4):
"""Return a list of n suppliers who didn't have their VAT ID checked in the last 3 months."""
suppliers = DocType("Supplier")
last_check = get_last_check_query("Supplier")

return (
frappe.qb.from_(suppliers)
.left_join(last_check)
.on(suppliers.name == last_check.party)
.select(
fn.LiteralValue("'Supplier'"),
suppliers.name,
suppliers.supplier_name,
suppliers.supplier_primary_address,
suppliers.tax_id,
)
.where(
suppliers.tax_id.notnull()
& (suppliers.disabled == 0)
& (
last_check.creation.isnull()
| (last_check.creation < fn.Now() - Interval(months=3))
)
)
.limit(batch_size)
.run()
)


def get_last_check_query(party_type: str):
vat_id_checks = DocType("VAT ID Check")
return (
frappe.qb.from_(vat_id_checks)
.select(
vat_id_checks.party,
fn.Max(vat_id_checks.creation).as_("creation"),
)
.where(
(vat_id_checks.party_type == party_type)
& (vat_id_checks.status == "Completed")
)
.groupby(vat_id_checks.party)
)


def check_some_parties():
"""Check VAT IDs of customers who didn't have their VAT ID checked in the last 3 months."""
requester_vat_id = None
if company := get_default_company():
requester_vat_id = frappe.get_cached_value("Company", company, "tax_id")

for customer, customer_name, primary_address, vat_id in get_customers():
for party_type, party, party_name, primary_address, vat_id in (
get_customers() + get_suppliers()
):
try:
parse_vat_id(vat_id)
except ValueError:
continue

doc = frappe.new_doc("VAT ID Check")
doc.customer = customer
doc.trader_name = customer_name
doc.customer_vat_id = vat_id
doc.party_type = party_type
doc.party = party
doc.trader_name = party_name
doc.party_vat_id = vat_id
doc.company = company
doc.requester_vat_id = requester_vat_id
if primary_address:
Expand Down

0 comments on commit 70571e3

Please sign in to comment.