Source code for amazonorders.entity.transaction
__copyright__ = "Copyright (c) 2024-2025 Alex Laird"
__license__ = "MIT"
import logging
import re
from datetime import date
from typing import Union, Optional
from bs4 import Tag
from amazonorders.conf import AmazonOrdersConfig
from amazonorders.entity.parsable import Parsable
from amazonorders.exception import AmazonOrdersError
logger = logging.getLogger(__name__)
[docs]
class Transaction(Parsable):
"""
An Amazon Transaction.
"""
def __init__(self,
parsed: Tag,
config: AmazonOrdersConfig,
completed_date: date) -> None:
super().__init__(parsed, config)
#: The Transaction completed date.
self.completed_date: date = completed_date
#: The Transaction payment method.
self.payment_method: str = self.safe_simple_parse(
selector=self.config.selectors.FIELD_TRANSACTION_PAYMENT_METHOD_SELECTOR
)
#: The Transaction grand total.
self.grand_total: float = self.safe_parse(self._parse_grand_total)
#: The Transaction was a refund or not.
self.is_refund: bool = self.grand_total > 0
#: The Transaction Order number.
self.order_number: str = self.safe_parse(self._parse_order_number)
#: The Transaction Order details link.
self.order_details_link: str = self.safe_parse(self._parse_order_details_link)
#: The Transaction seller name.
self.seller: str = self.safe_simple_parse(
selector=self.config.selectors.FIELD_TRANSACTION_SELLER_NAME_SELECTOR
)
def __repr__(self) -> str:
return f"<Transaction {self.completed_date}: \"Order #{self.order_number}, Grand Total: {self.grand_total}\">"
def __str__(self) -> str: # pragma: no cover
return f"Transaction {self.completed_date}: Order #{self.order_number}, Grand Total: {self.grand_total}"
def _parse_grand_total(self) -> Union[float, int, None]:
value = self.simple_parse(self.config.selectors.FIELD_TRANSACTION_GRAND_TOTAL_SELECTOR)
value = self.to_currency(value)
if value is None: # pragma: no cover
err_msg = ("Order.grand_total did not populate, but it's required. "
"Check if Amazon changed the HTML.")
if not self.config.warn_on_missing_required_field:
raise AmazonOrdersError(err_msg)
else:
logger.warning(err_msg)
return value
def _parse_order_number(self) -> Optional[str]:
value = self.simple_parse(self.config.selectors.FIELD_TRANSACTION_ORDER_NUMBER_SELECTOR)
if value is None: # pragma: no cover
err_msg = ("Transaction.order_number did not populate, but it's required. "
"Check if Amazon changed the HTML.")
if not self.config.warn_on_missing_required_field:
raise AmazonOrdersError(err_msg)
else:
logger.warning(err_msg)
return None
match = re.match(".*#([0-9-]+)$", value)
value = match.group(1) if match else ""
return value
def _parse_order_details_link(self) -> Optional[str]:
value = self.simple_parse(self.config.selectors.FIELD_TRANSACTION_ORDER_LINK_SELECTOR, attr_name="href")
if not value and self.order_number:
value = f"{self.config.constants.ORDER_DETAILS_URL}?orderID={self.order_number}"
return value