55 lines
1.7 KiB
Python
55 lines
1.7 KiB
Python
# ======= SHARED HELPERS =======
|
|
|
|
import frappe
|
|
from datetime import datetime
|
|
|
|
|
|
def resolve_customer_group(preferred=None):
|
|
"""Return a usable (non-group) Customer Group, or None.
|
|
|
|
Newer ERPNext rejects assigning a Customer to a "group" type Customer Group
|
|
(e.g. the root "All Customer Groups"), and `customer_group` is no longer a
|
|
mandatory field. So:
|
|
- if a valid, non-group Customer Group is configured -> use it
|
|
- otherwise return None and let the Customer be created without a group
|
|
"""
|
|
if preferred and frappe.db.exists("Customer Group", preferred):
|
|
if not frappe.db.get_value("Customer Group", preferred, "is_group"):
|
|
return preferred
|
|
return None
|
|
|
|
|
|
def resolve_territory(preferred=None):
|
|
"""Return a usable Territory, or None if the configured one is missing.
|
|
|
|
Mirrors :func:`resolve_customer_group`; Territory root nodes are still
|
|
accepted by ERPNext, so we only validate existence.
|
|
"""
|
|
if preferred and frappe.db.exists("Territory", preferred):
|
|
return preferred
|
|
return None
|
|
|
|
|
|
def _parse_load_date(value):
|
|
"""Parse the date formats the e-taxes loaders use ('YYYY-MM-DD' or
|
|
'DD-MM-YYYY[ HH:MM]'). Returns a datetime.date or None."""
|
|
if not value:
|
|
return None
|
|
token = str(value).strip().split(" ")[0]
|
|
for fmt in ("%Y-%m-%d", "%d-%m-%Y"):
|
|
try:
|
|
return datetime.strptime(token, fmt).date()
|
|
except ValueError:
|
|
continue
|
|
return None
|
|
|
|
|
|
def exceeds_one_year(date_from, date_to):
|
|
"""True if [date_from, date_to] spans more than one year (366 days).
|
|
|
|
Used to forbid loading more than a year of data in a single run — applies to
|
|
every e-taxes load (invoices, reference data, VAT) EXCEPT Company data."""
|
|
df = _parse_load_date(date_from)
|
|
dt = _parse_load_date(date_to)
|
|
return bool(df and dt and (dt - df).days > 366)
|