Skip to main content

Django app which implements ledgers to store cumulative data.

Project description

django-ledgersv0.1.0

Django app which implements ledgers to store cumulative data.

Description

A Ledger is an abstraction over Django ORM which consists of 2 tables:

  • movements — stores periodic data about ledger's state change.
  • totals — stores pre-calculated cumulative result for some period.

Ledger's state is changed via Documents — an "atomic" abstraction over set of simultaneous changes.

Examples

Warehouse remains

Items:

from django.db import models


class Item(models.Model):
    name = models.CharField(max_length=200, unique=True)

can be stored at Warehouse:

class Warehouse(models.Model):
    name = models.CharField()

via Warehouse Balance Ledger:

from ledgers.enum import CumulativeLedgerRecordActionEnum
from ledgers.ledger import CumulativeLedger
from ledgers.ledger.fields import dimensions, resources


class BalanceAtWarehousesLedger(CumulativeLedger):
    warehouse = dimensions.ForeignKey(
        to=Warehouse,
        null=False,
    )
    item = dimensions.ForeignKey(
        to=Item,
        null=False,
    )
    amount = resources.Integer()
    comment = models.CharField(max_length=200, null=False, default='')
    
    @classmethod
    def movements_for_itemmovement(cls, doc):
        # noinspection PyCallingNonCallable
        return (
            cls.mvm_model(
                period=doc.execution_date,
                registrator=doc,
                line_index=0,
                action=CumulativeLedgerRecordActionEnum.OUTCOME,
                warehouse_id=doc.from_warehouse_id,
                item_id=doc.item_id,
                amount=doc.amount,
            ),
            cls.mvm_model(
                period=doc.execution_date,
                registrator=doc,
                line_index=1,
                action=CumulativeLedgerRecordActionEnum.INCOME,
                warehouse_id=doc.to_warehouse_id,
                item_id=doc.item_id,
                amount=doc.amount,
            ),
        )

and changed via Item Movement:

class ItemMovement(Document):
    class DocumentMeta(Document.DocumentMeta):
        related_ledgers = [BalanceAtWarehousesLedger]
        default_prefix = 'MVM'

    from_warehouse = models.ForeignKey(
        Warehouse,
        on_delete=models.CASCADE,
        null=False,
        blank=False,
        related_name='+',
    )
    to_warehouse = models.ForeignKey(
        Warehouse,
        on_delete=models.CASCADE,
        null=False,
        blank=False,
        related_name='+',
    )
    item = models.ForeignKey(
        Item,
        on_delete=models.CASCADE,
        null=False,
        blank=False,
    )
    amount = models.IntegerField(
        null=False,
        blank=False,
    )

Then, on creating an ItemMovement:

from ledgers.enum import DocumentStateEnum

# prepare instances
t_shirt = Item.objects.get_or_create(name='T-shirt')
london_warehouse = Warehouse.objects.get_or_create(name='London')
tokyo_warehouse = Warehouse.objects.get_or_create(name='Tokyo')

# prepare and save document
doc = ItemMovement(
    state=DocumentStateEnum.ACTIVE,
    item=t_shirt,
    from_warehouse=london_warehouse,
    to_warehouse=tokyo_warehouse,
    amount=100,
)
doc.save()

Movements and totals tables will be updated, and actual remains for any period can be fetched:

from example.exampleapp.models import Item, Warehouse, BalanceAtWarehousesLedger
from datetime import timedelta


# prepare instances
t_shirt = Item.objects.get_or_create(name='T-shirt')
london_warehouse = Warehouse.objects.get_or_create(name='London')
tokyo_warehouse = Warehouse.objects.get_or_create(name='Tokyo')

remains_before_document_date = BalanceAtWarehousesLedger.remains_qs(
    period=doc.execution_date - timedelta(days=1),
)
remains_after_document_date = BalanceAtWarehousesLedger.remains_qs()

print(list(remains_before_document_date))
# [
#   {
#       'warehouse_id': 1,
#       'item_id': 1,
#       'amount_remains': 0
#   },
#   {
#       'warehouse_id': 2,
#       'item_id': 1,
#       'amount_remains': 0
#   }
# ]

print(list(remains_after_document_date))
# [
#   {
#       'warehouse_id': 1,
#       'item_id': 1,
#       'amount_remains': -10
#   },
#   {
#       'warehouse_id': 2,
#       'item_id': 1,
#       'amount_remains': 10
#   }
# ]

Features

django-ledgers @ v0.1.0 can:

  • store push tokens from FCM or HMS
  • link push tokens with their users and applications
  • store push notifications
  • store push notifications extra kwargs (e.g. deeplinks)
  • compose recipients via UI based on user-specified conditions
  • watch notifications schedule on calendar
  • send scheduled push notifications
  • store applications as swappable model

Usage example

TODO

exampleproj

Example project is a showcase django project. You can reference to it for usage cases, examples, testing. You must never deploy exampleproj in production due to exposed SECRET_KEY.

Getting Started

Dependencies

Python packages

  • django
  • django-cte

Installing

Using Python Package Index

  • make sure to use latest pip:

    python3 -m pip install --upgrade pip
    
  • install django-ledgers:

    python3 -m pip install django-ledgers
    

OR download package from releases

  • download release asset (.tar.gz or .whl)

  • make sure to use latest pip:

    python3 -m pip install --upgrade pip
    
  • install djangoFCM from file:

    python3 -m pip install /path/to/downloaded/asset.tar.gz # or .whl
    

OR clone from repository

  • clone project:

    git clone \
            --depth=1 \
            --branch=master \
            git@github.com:omelched/django-ledgers.git \
            </path/to/downloads>
    
  • move /django-ledgers/ledgers solely to folder containing django apps

    mv      </path/to/downloads>/django-ledgers/ledgers \
            </path/to/django/project/apps>
    
  • remove leftovers

    rm -rf  </path/to/downloads>/django-ledgers
    

Configuring

Installing application

Add django-ledgers to INSTALLED_APPS in your Django project settings.py.

If you installed package the third way, </path/to/django/project/apps> must be added to PYTHONPATH. If you not sure add code below in your Django project manage.py before calling main():

sys.path.append('</path/to/django/project/apps>')

Subclass ledgers.ledger.cumulative.CumulativeLedger and ledgers.models.documents.document.Document.

Migrations

Execute database migrations:

python example/manage.py migrate

Collect static:

python example/manage.py collectstatic

Authors

@omelched (Denis Omelchenko)

Contributors

tumbleweed

Changelist

django-ledgers version history and changelist available at releases page.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

This project is inspired by 1C ORM. More on topic:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-ledgers-0.1.0.tar.gz (18.0 kB view details)

Uploaded Source

Built Distribution

django_ledgers-0.1.0-py3-none-any.whl (23.6 kB view details)

Uploaded Python 3

File details

Details for the file django-ledgers-0.1.0.tar.gz.

File metadata

  • Download URL: django-ledgers-0.1.0.tar.gz
  • Upload date:
  • Size: 18.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.4

File hashes

Hashes for django-ledgers-0.1.0.tar.gz
Algorithm Hash digest
SHA256 07796b6b45c7fde6ed5ab414128b28c557c1013d3d68c8d12ff27d99018de20a
MD5 80fc91253045002b3fd31cdcbb9d2c7a
BLAKE2b-256 b852973b73a79761d6754f0ee4662417ef4f125832a58245c64269f8155a3b7f

See more details on using hashes here.

File details

Details for the file django_ledgers-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_ledgers-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5522274e97c2b6082c8866ef959e92ba9be6015469a0c44e653775fff571758c
MD5 700bdb04e9324dd70fc7bf34f56b0a73
BLAKE2b-256 b0ef093d45d56690151f86b2893008e1f55f260e1c45ffa27ce7d3894813622f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page