rechu.models package

Submodules

rechu.models.base module

Base model for receipt cataloging.

class rechu.models.base.Base(**kwargs: Any)[source]

Bases: DeclarativeBase

Base ORM model class for receipt models.

metadata: ClassVar[MetaData] = MetaData()

Refers to the _schema.MetaData collection that will be used for new _schema.Table objects.

registry: ClassVar[registry] = <sqlalchemy.orm.decl_api.registry object>

Refers to the _orm.registry in use where new _orm.Mapper objects will be associated.

rechu.models.product module

Models for product metadata.

final class rechu.models.product.DiscountMatch(**kwargs)[source]

Bases: Base, Match

Discount label model for a product matching string.

id: MappedColumn[int]
is_pattern: MappedColumn[bool]
label: MappedColumn[str]
product: Relationship[Product]
product_id: MappedColumn[int]
set_is_pattern(key: str, value: str) str[source]

Determine if the discount label is a regular expression matcher.

class rechu.models.product.Indicator(*values)[source]

Bases: str, Enum

Price matcher indicators that are not dates or units.

MAXIMUM = 'maximum'
MINIMUM = 'minimum'
final class rechu.models.product.LabelMatch(**kwargs)[source]

Bases: Base, Match

Label model for a product matching string.

id: MappedColumn[int]
is_pattern: MappedColumn[bool]
name: MappedColumn[str]
product: Relationship[Product]
product_id: MappedColumn[int]
set_is_pattern(key: str, value: str) str[source]

Determine if the label name is a regular expression matcher.

class rechu.models.product.Match[source]

Bases: object

Model that matches a field of a product.

final class rechu.models.product.PriceMatch(**kwargs)[source]

Bases: Base, Match

Price model for a product matching value, which may be part of a value range or time interval.

id: MappedColumn[int]
indicator: MappedColumn[str | None]
product: Relationship[Product]
product_id: MappedColumn[int]
value: MappedColumn[Price]
final class rechu.models.product.Product(**kwargs)[source]

Bases: Base

Product model for metadata.

alcohol: MappedColumn[str | None]
brand: MappedColumn[str | None]
category: MappedColumn[str | None]
check_merge(other: Product) None[source]

Check if the other product is compatible with merging into this product.

clear() None[source]

Remove all matchers, properties, identifiers and range products, but not the generic product or its properties that we inherit now.

copy() Product[source]

Copy the product.

description: MappedColumn[str | None]
discounts: Relationship[list[DiscountMatch]]
generic: Relationship[Product | None]
generic_id: MappedColumn[int | None]
gtin: MappedColumn[GTIN | None]
property has_patterns: bool

Determine whether any of the label or discount matchers have regular expressions to match receipt product and discount labels against, rather than plain strings.

id: MappedColumn[int]
labels: Relationship[list[LabelMatch]]
merge(other: Product, replace: bool = True) bool[source]

Merge attributes of the other product into this one.

This replaces values and the primary key in this product, except for the shop identifier (which must be the same) and the matchers (where unique matchers from the other product are added).

This is similar to a session merge except no database changes are done and the matchers are more deeply merged.

If replace is disabled, then simple property fields that already have a value are not changed. Matchers are always updated.

Returns whether the product has changed, with new matchers or different values.

portions: MappedColumn[int | None]
prices: Relationship[list[PriceMatch]]
range: Relationship[list[Product]]
replace(new: Product) bool[source]

Replace all matchers, properties, identifiers and range products with those defined in the new product, or with the generic product’s inherited properties; the original generic product is kept.

Returns whether the new product is not empty.

shop: MappedColumn[str]
shop_meta: Relationship[Shop]
sku: MappedColumn[str | None]
type: MappedColumn[str | None]
volume: MappedColumn[Quantity | None]
weight: MappedColumn[Quantity | None]

rechu.models.receipt module

Models for receipt data.

final class rechu.models.receipt.Discount(**kwargs)[source]

Bases: Base

Discount model for a discount action mentioned on a receipt.

id: MappedColumn[int]
items: Relationship[list[ProductItem]]
label: MappedColumn[str]
position: MappedColumn[int]
price_decrease: MappedColumn[Price]
receipt: Relationship[Receipt]
receipt_key: MappedColumn[str]
final class rechu.models.receipt.DiscountItems(**kwargs)[source]

Bases: Base

Association table for products involved in discounts.

discount_id: MappedColumn[int]
product_id: MappedColumn[int]
final class rechu.models.receipt.ProductItem(**kwargs)[source]

Bases: Base

Product model for a product item mentioned on a receipt.

amount: MappedColumn[float]
discount_indicator: MappedColumn[str | None]
property discount_indicators: list[str]

Retrieve a list of discrete portions of the discount indicator.

discounts: Relationship[list[Discount]]
id: MappedColumn[int]
label: MappedColumn[str]
position: MappedColumn[int]
price: MappedColumn[Price]
product: Relationship[Product | None]
product_id: MappedColumn[int | None]
quantity: MappedColumn[Quantity]
receipt: Relationship[Receipt]
receipt_key: MappedColumn[str]
unit: MappedColumn[Unit | None]
final class rechu.models.receipt.Receipt(**kwargs)[source]

Bases: Base

Receipt model for a receipt from a certain date at a shop with products and possibly discounts.

date: MappedColumn[date]
discounts: Relationship[list[Discount]]
filename: MappedColumn[str]
products: Relationship[list[ProductItem]]
shop: MappedColumn[str]
shop_meta: Relationship[Shop]
property total_discount: Price

Retrieve the total discount of the receipt.

property total_price: Price

Retrieve the total cost of the receipt after discounts.

updated: MappedColumn[datetime]

rechu.models.shop module

Models for shop metadata.

final class rechu.models.shop.DiscountIndicator(**kwargs)[source]

Bases: Base

Indicator model for a substring or regular expression that matches a receipt item’s discount indicator.

id: MappedColumn[int]
pattern: MappedColumn[str]
shop: Relationship[Shop]
shop_id: MappedColumn[int]
final class rechu.models.shop.Shop(**kwargs)[source]

Bases: Base

Shop metadata model.

copy() Shop[source]

Copy the shop.

discount_indicators: Relationship[list[DiscountIndicator]]
key: MappedColumn[str]
merge(other: Shop, replace: bool = True) bool[source]

Merge attributes of the other shop into this one.

This replaces values in this shop, except for the key which must be the same in order for .

This is similar to a session merge except no database changes are done.

If replace is disabled, then simple property fields that already have a value are not changed.

Returns whether the shop has changed with different values.

name: MappedColumn[str | None]
products: MappedColumn[str | None]
website: MappedColumn[str | None]
wikidata: MappedColumn[str | None]

Module contents

Models for receipt cataloging.

class rechu.models.Base(**kwargs: Any)[source]

Bases: DeclarativeBase

Base ORM model class for receipt models.

metadata: ClassVar[MetaData] = MetaData()

Refers to the _schema.MetaData collection that will be used for new _schema.Table objects.

registry: ClassVar[registry] = <sqlalchemy.orm.decl_api.registry object>

Refers to the _orm.registry in use where new _orm.Mapper objects will be associated.

class rechu.models.Product(**kwargs)[source]

Bases: Base

Product model for metadata.

alcohol: MappedColumn[str | None]
brand: MappedColumn[str | None]
category: MappedColumn[str | None]
check_merge(other: Product) None[source]

Check if the other product is compatible with merging into this product.

clear() None[source]

Remove all matchers, properties, identifiers and range products, but not the generic product or its properties that we inherit now.

copy() Product[source]

Copy the product.

description: MappedColumn[str | None]
discounts: Relationship[list[DiscountMatch]]
generic: Relationship[Product | None]
generic_id: MappedColumn[int | None]
gtin: MappedColumn[GTIN | None]
property has_patterns: bool

Determine whether any of the label or discount matchers have regular expressions to match receipt product and discount labels against, rather than plain strings.

id: MappedColumn[int]
labels: Relationship[list[LabelMatch]]
merge(other: Product, replace: bool = True) bool[source]

Merge attributes of the other product into this one.

This replaces values and the primary key in this product, except for the shop identifier (which must be the same) and the matchers (where unique matchers from the other product are added).

This is similar to a session merge except no database changes are done and the matchers are more deeply merged.

If replace is disabled, then simple property fields that already have a value are not changed. Matchers are always updated.

Returns whether the product has changed, with new matchers or different values.

portions: MappedColumn[int | None]
prices: Relationship[list[PriceMatch]]
range: Relationship[list[Product]]
replace(new: Product) bool[source]

Replace all matchers, properties, identifiers and range products with those defined in the new product, or with the generic product’s inherited properties; the original generic product is kept.

Returns whether the new product is not empty.

shop: MappedColumn[str]
shop_meta: Relationship[Shop]
sku: MappedColumn[str | None]
type: MappedColumn[str | None]
volume: MappedColumn[Quantity | None]
weight: MappedColumn[Quantity | None]
class rechu.models.Receipt(**kwargs)[source]

Bases: Base

Receipt model for a receipt from a certain date at a shop with products and possibly discounts.

date: MappedColumn[date]
discounts: Relationship[list[Discount]]
filename: MappedColumn[str]
products: Relationship[list[ProductItem]]
shop: MappedColumn[str]
shop_meta: Relationship[Shop]
property total_discount: Price

Retrieve the total discount of the receipt.

property total_price: Price

Retrieve the total cost of the receipt after discounts.

updated: MappedColumn[datetime]
class rechu.models.Shop(**kwargs)[source]

Bases: Base

Shop metadata model.

copy() Shop[source]

Copy the shop.

discount_indicators: Relationship[list[DiscountIndicator]]
key: MappedColumn[str]
merge(other: Shop, replace: bool = True) bool[source]

Merge attributes of the other shop into this one.

This replaces values in this shop, except for the key which must be the same in order for .

This is similar to a session merge except no database changes are done.

If replace is disabled, then simple property fields that already have a value are not changed.

Returns whether the shop has changed with different values.

name: MappedColumn[str | None]
products: MappedColumn[str | None]
website: MappedColumn[str | None]
wikidata: MappedColumn[str | None]