haikal/inventory/services.py
2025-06-22 13:25:54 +03:00

162 lines
5.6 KiB
Python

"""
Services module
"""
import requests
import json
from requests import Session
from pyvin import VIN
from django.conf import settings
from .models import CarMake
def get_make(item):
"""
Fetches a car make object from the database based on the provided item. The function
first attempts an exact case-insensitive match on the full string. If no match is found,
it splits the input string by spaces and checks for a match with each fragment, stopping
as soon as a match is found.
:param item: A string representing the name or a part of the name of the car make to search.
:type item: str
:return: The first matching CarMake object found, or None if no match is found.
:rtype: CarMake or None
"""
data = CarMake.objects.filter(name__iexact=item).first()
if not data:
r = item.split(" ")
for i in r:
if data := CarMake.objects.filter(name__iexact=i).first():
break
return data
def get_model(item, make):
"""
Searches for a car model associated with a specific make by performing an
exact case-insensitive match. If no match is found, it attempts to match
based on individual words split from the input item.
:param item: A string representing the name of the car model to search for.
:param make: An object representing the car manufacturer, which contains the
associated car models.
:return: Returns the first car model object that matches the search criteria,
or None if no match is found.
"""
data = make.carmodel_set.filter(name__iexact=item).first()
if not data:
r = item.split(" ")
for i in r:
if data := make.carmodel_set.filter(name__iexact=i).first():
break
return data
def normalize_name(name):
"""
Normalizes a given name by removing spaces and hyphens and converting it to lowercase.
This function is useful for ensuring consistent formatting of names by
removing unwanted characters and applying a uniform casing. The output
is designed to be a simple, standardized string version of the input name.
:param name: The name string to be normalized.
:type name: str
:return: A normalized string with no spaces or hyphens, all in lowercase.
:rtype: str
"""
return name.replace(" ", "").replace("-", "").lower()
def decodevin(vin):
"""
Decodes a Vehicle Identification Number (VIN) using multiple decoding functions
and returns the decoded result. This function attempts to decode the VIN using
three different functions in sequence and returns the first successful result.
If none of the decoding functions produce a valid result, the function returns None.
:param vin: The Vehicle Identification Number (VIN) to be decoded.
:type vin: str
:return: The decoded result if any decoding function is successful, or None if
all decoding attempts fail.
:rtype: dict | None
"""
if result := decode_vin(vin):
return result
elif result := elm(vin):
return result
# elif result:=decode_vin_haikalna(vin):
# return result
else:
return None
def decode_vin(vin):
"""
Decodes a given Vehicle Identification Number (VIN) to extract vehicle details such as
maker, model, and model year.
This function takes a VIN string as input, processes it using the VIN utility, and attempts
to extract essential information about the vehicle. It returns a dictionary containing the
decoded details if all required fields are successfully retrieved; otherwise, it returns None.
:param vin: The Vehicle Identification Number to be decoded.
:type vin: str
:return: A dictionary containing decoded vehicle details with keys "maker", "model", and
"modelYear", or None if any of these fields cannot be determined.
:rtype: dict | None
"""
v = VIN(vin)
data = {}
if v:
data = {
"maker": v.Make,
"model": v.Model,
"modelYear": v.ModelYear,
}
return data if all([x for x in data.values()]) else None
def elm(vin):
"""
Fetches vehicle information using the provided VIN (Vehicle Identification Number)
through the ELM API service.
This function sends a GET request to the ELM API endpoint with the VIN parameter
to retrieve details about a vehicle, including its maker, model, and model year.
The function processes the API's JSON response to extract relevant data and
returns it if all required fields are available.
:param vin: Vehicle Identification Number required to query the ELM API
service for vehicle information.
:type vin: str
:return: A dictionary containing the vehicle's `maker`, `model`, and `modelYear`
if all fields are present. Returns None if any of these fields are missing.
:rtype: dict or None
"""
headers = {
"Content-Type": "application/json",
"app-id": settings.ELM_APP_ID,
"app-key": settings.ELM_APP_KEY,
"client-id": settings.ELM_CLIENT_ID,
}
url = (
"https://vehicle-maintenance.api.elm.sa/api/v1/vehicles/vehicle-info?vin=" + vin
)
payload = {}
response = requests.request("GET", url, headers=headers, data=payload)
response = json.loads(response.text)
data = {}
if response.get("data"):
data = {
"maker": response["data"]["maker"],
"model": response["data"]["model"] if response["data"]["model"] else " ",
"modelYear": response["data"]["modelYear"],
}
print([x for x in data.values()])
return data if all([x for x in data.values()]) else None