98 lines
2.8 KiB
Python
98 lines
2.8 KiB
Python
import datetime
|
|
import random
|
|
import string
|
|
from typing import Dict, Any, List, Set, Union
|
|
|
|
|
|
def generate_invoice_number(prefix="INV", length=6):
|
|
"""
|
|
Generate a unique invoice number.
|
|
|
|
Format: INV-{YEAR}{MONTH}-{RANDOM_ALPHANUMERIC}
|
|
Example: INV-202307-A1B2C3
|
|
|
|
Args:
|
|
prefix (str): Prefix for the invoice number
|
|
length (int): Length of the random string
|
|
|
|
Returns:
|
|
str: Generated invoice number
|
|
"""
|
|
# Get current date for year-month part
|
|
today = datetime.datetime.now()
|
|
year_month = today.strftime("%Y%m")
|
|
|
|
# Generate random alphanumeric string
|
|
characters = string.ascii_uppercase + string.digits
|
|
random_str = ''.join(random.choice(characters) for _ in range(length))
|
|
|
|
# Combine to form invoice number
|
|
invoice_number = f"{prefix}-{year_month}-{random_str}"
|
|
|
|
return invoice_number
|
|
|
|
|
|
def calculate_total_amount(items):
|
|
"""
|
|
Calculate the total amount of an invoice based on its items.
|
|
|
|
Args:
|
|
items (list): List of invoice items, each with quantity and unit_price
|
|
|
|
Returns:
|
|
float: Total amount
|
|
"""
|
|
total = 0.0
|
|
for item in items:
|
|
item_amount = item.quantity * item.unit_price
|
|
total += item_amount
|
|
|
|
return total
|
|
|
|
|
|
def filter_fields(data: Union[Dict[str, Any], List[Dict[str, Any]]], fields: str = None) -> Union[Dict[str, Any], List[Dict[str, Any]]]:
|
|
"""
|
|
Filter dictionary or list of dictionaries to only include specified fields.
|
|
|
|
Args:
|
|
data (Union[Dict[str, Any], List[Dict[str, Any]]]): The data to filter
|
|
fields (str, optional): Comma-separated string of fields to include.
|
|
If None, returns original data.
|
|
|
|
Returns:
|
|
Union[Dict[str, Any], List[Dict[str, Any]]]: Filtered data
|
|
|
|
Example:
|
|
>>> data = {"id": 1, "name": "John", "email": "john@example.com"}
|
|
>>> filter_fields(data, "id,name")
|
|
{"id": 1, "name": "John"}
|
|
"""
|
|
if fields is None:
|
|
return data
|
|
|
|
# Parse the fields parameter
|
|
fields_set: Set[str] = {field.strip() for field in fields.split(",")} if fields else set()
|
|
|
|
if not fields_set:
|
|
return data
|
|
|
|
# Handle list of dictionaries
|
|
if isinstance(data, list):
|
|
return [_filter_dict(item, fields_set) for item in data]
|
|
|
|
# Handle single dictionary
|
|
return _filter_dict(data, fields_set)
|
|
|
|
|
|
def _filter_dict(data: Dict[str, Any], fields_set: Set[str]) -> Dict[str, Any]:
|
|
"""
|
|
Filter a dictionary to only include specified fields.
|
|
|
|
Args:
|
|
data (Dict[str, Any]): Dictionary to filter
|
|
fields_set (Set[str]): Set of fields to include
|
|
|
|
Returns:
|
|
Dict[str, Any]: Filtered dictionary
|
|
"""
|
|
return {k: v for k, v in data.items() if k in fields_set} |