为django-oscar管理账户
项目描述
“管理账户”是指可以借记和贷记的资金分配。本包为与电子商务框架Oscar一起使用提供了管理账户功能。
账户可用于实现各种有趣的功能,包括
礼品卡
网络账户
忠诚度计划
基本上,任何涉及在封闭系统中跟踪资金流动的情况。
本包使用复式记账法,每笔交易都记录两次(一次记录来源,一次记录目的地)。这确保了账目始终平衡,并且有完整的交易活动审计记录。
如果你的项目管理资金,你应该使用这样的库。你的财务人员会感谢你。
功能
账户有一个信用额度,默认为0。账户可以设置无信用额度,使其成为系统中的“资金来源”。至少必须设置一个无信用额度的账户,才能使资金在系统中流动。
账户可以有:- 没有分配用户 - 一个“主要”用户 - 这是最常见的情况 - 一组分配的用户
一个用户可以有多个账户
账户可以有一个开始日期和结束日期,以便在有限的时间内使用
账户可以被限制,只能用于支付一系列产品。
账户可以进行分类
屏幕截图
安装
使用pip安装
pip install django-oscar-accounts
并将oscar_accounts.apps.AccountsConfig和oscar_accounts.dashboard.apps.AccountsDashboardConfig添加到INSTALLED_APPS中。运行manage.py migrate oscar_accounts将创建相应的数据库表。要创建一些初始核心账户和账户类型,请使用manage.py oscar_accounts_init。这些账户的名称可以通过设置来控制(见下文)。
为了使账户可以通过Oscar仪表板访问,您需要将其添加到您的OSCAR_DASHBOARD_NAVIGATION
from oscar.defaults import *
OSCAR_DASHBOARD_NAVIGATION.append(
{
'label': 'Accounts',
'icon': 'fas fa-globe',
'children': [
{
'label': 'Accounts',
'url_name': 'accounts_dashboard:accounts-list',
},
{
'label': 'Transfers',
'url_name': 'accounts_dashboard:transfers-list',
},
{
'label': 'Deferred income report',
'url_name': 'accounts_dashboard:report-deferred-income',
},
{
'label': 'Profit/loss report',
'url_name': 'accounts_dashboard:report-profit-loss',
},
]
})
此外,您还需要将url模式添加到您的urls.py
from django.apps import apps
# ...
urlpatterns = [
...
path('dashboard/accounts/', apps.get_app_config('accounts_dashboard').urls),
]
您还应该设置一个cronjob,该cronjob调用
./manage.py close_expired_accounts
以关闭任何过期的账户并将资金转移到“过期”账户。
API
使用管理器创建账户实例
from decimal import Decimal
import datetime
from django.contrib.auth import get_user_model
from oscar_accounts import models
User = get_user_model()
anonymous_account = models.Account.objects.create()
barry = User.objects.get(username="barry")
user_account = models.Account.objects.create(primary_user=barry)
no_credit_limit_account = models.Account.objects.create(credit_limit=None)
credit_limit_account = models.Account.objects.create(credit_limit=Decimal('1000.00'))
today = datetime.date.today()
next_week = today + datetime.timedelta(days=7)
date_limited_account = models.Account.objects.create(
start_date=today, end_date=next_week)
使用外观进行资金转账
from oscar_accounts import facade
staff_member = User.objects.get(username="staff")
trans = facade.transfer(source=no_credit_limit_account,
destination=user_account,
amount=Decimal('10.00'),
user=staff_member)
反向转账
facade.reverse(trans, user=staff_member,
description="Just an example")
如果提议的转账无效,将抛出异常。所有异常都是oscar_accounts.exceptions.AccountException的子类。您的客户端代码应查找此类异常并相应地处理它们。
客户端代码应仅使用oscar_accounts.models.Budget类和来自oscar_accounts.facade的两个函数 - 不需要其他任何内容。
错误处理
请注意,转账操作被包含在自己的数据库事务中,以确保只写入完整的转账。当使用Django的事务中间件时,您需要小心。如果您有一个未处理的异常,那么即使其他什么也没有,账户转账仍然会被提交。为了处理这种情况,您需要确保,如果在您的支付后代码中发生异常,则回滚任何转账。
以下是一个示例
from oscar_accounts import facade
def submit(self, order_total):
# Take payment first
transfer = facade.transfer(self.get_user_account(),
self.get_merchant_account(),
order_total)
# Create order models
try:
self.place_order()
except Exception, e:
# Something went wrong placing the order. Roll-back the previous
# transfer
facade.reverse(transfer)
在这种情况下,您将创建两个转账,但没有订单。虽然这并不是理想的,但这是处理订单创建过程中发生的异常的最佳方式。
多转账支付
项目通常会允许用户拥有多个账户,并使用多个账户来支付订单。这将涉及多个转账,并在您的应用程序代码中需要一些仔细的处理。
通常,编写围绕账户API的自定义包装器来封装您的业务逻辑和错误处理是有意义的。以下是一个示例:
from decimal import Decimal as D
from oscar_accounts import models, exceptions, facade
def redeem(order_number, user, amount):
# Get user's non-empty accounts ordered with the first to expire first
accounts = models.Account.active.filter(
user=user, balance__gt=0).order_by('end_date')
# Build up a list of potential transfers that cover the requested amount
transfers = []
amount_to_allocate = amount
for account in accounts:
to_transfer = min(account.balance, amount_to_allocate)
transfers.append((account, to_transfer))
amount_to_allocate -= to_transfer
if amount_to_allocate == D('0.00'):
break
if amount_to_allocate > D('0.00'):
raise exceptions.InsufficientFunds()
# Execute transfers to some 'Sales' account
destination = models.Account.objects.get(name="Sales")
completed_transfers = []
try:
for account, amount in transfers:
transfer = facade.transfer(
account, destination, amount, user=user,
description="Order %s" % order_number)
completed_transfers.append(transfer)
except exceptions.AccountException, transfer_exc:
# Something went wrong with one of the transfers (possibly a race condition).
# We try and roll back all completed ones to get us back to a clean state.
try:
for transfer in completed_transfers:
facade.reverse(transfer)
except Exception, reverse_exc:
# Uh oh: No man's land. We could be left with a partial
# redemption. This will require an admin to intervene. Make
# sure your logger mails admins on error.
logger.error("Order %s, transfers failed (%s) and reverse failed (%s)",
order_number, transfer_exc, reverse_exc)
logger.exception(reverse_exc)
# Raise an exception so that your client code can inform the user appropriately.
raise RedemptionFailed()
else:
# All transfers completed ok
return completed_transfers
如您所见,对无法执行所有转账的情况进行了仔细处理。
如果您使用Oscar,请确保为每次转账创建一个OrderSource实例(而不是将它们全部聚合到一个实例中)。这将提供更好的审计信息。以下是一些示例代码:
try:
transfers = api.redeem(order_number, user, total_incl_tax)
except Exception:
# Inform user of failed payment
else:
for transfer in transfers:
source_type, __ = SourceType.objects.get_or_create(name="Accounts")
source = Source(
source_type=source_type,
amount_allocated=transfer.amount,
amount_debited=transfer.amount,
reference=transfer.reference)
self.add_payment_source(source)
核心账户和账户类型
post-syncdb信号将创建账户类型和账户的通用结构。一些名称可以通过设置进行控制,如括号所示。
资产
销售
赎回(ACCOUNTS_REDEMPTIONS_NAME)-当使用账户支付某物时,资金将转入此处。
过期(ACCOUNTS_LAPSED_NAME)-当账户到期时,资金将转入此处。这是通过“close_expired_accounts”管理命令完成的。此账户的名称可以通过ACCOUNTS_LAPSED_NAME进行设置。
现金
“银行”(ACCOUNTS_BANK_NAME)-由客户支付创建新账户的源账户(例如,礼品卡)。此账户不会有信用额度,并且通常具有负余额,因为只有资金被转出。
未支付 - 这包含作为其他账户来源但未由客户支付的账户。例如,您可能允许管理员在仪表板中创建新账户。此类账户将是初始转账的源账户。
负债
递延收入 - 这包含客户账户/礼品卡。您可能希望在此类型内创建额外的账户类型以对账户进行分类。
示例交易
考虑以下账户和账户类型:
- 资产
- 销售
赎回
过期
- 现金
银行
- 未支付
商家资助
- 负债
递延收入
请注意,所有账户的初始余额都是0,所有余额的总和始终为0。
一位客户购买了一张50英镑的礼品卡
创建了一个类型为“递延收入”的新账户,并设置了结束日期 - 50英镑从银行转账到这个新账户
一位客户使用他们的50英镑礼品卡支付了30英镑的订单
30英镑从礼品卡账户转账到赎回账户
客户的礼品卡过期,卡上还剩20英镑
20英镑从礼品卡账户转账到过期账户
客户打电话投诉,一名员工创建了一张20英镑的新礼品卡
创建了一个类型为“递延收入”的新账户 - 20英镑从“商家资助”账户转账到这个新账户
设置
有一些设置可以控制命名和初始未支付和递延收入账户类型
ACCOUNTS_MIN_LOAD_VALUE 创建账户(或充值)的最小值
ACCOUNTS_MAX_INITIAL_VALUE 可以转账到账户的最大值。
OSCAR_ACCOUNTS_DASHBOARD_ITEMS_PER_PAGE 每页仪表板中显示的项目数量(默认=20)。
贡献
分支存储库,设置虚拟环境并运行
make install
使用以下命令运行测试
pytest
项目详细信息
下载文件
下载适用于您的平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源代码分发
构建分发
django-oscar-accounts-3.0.1.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 6256df19a1470f2db615fd06b444b60631b626c2fca3b68907a50f84c8f25ad5 |
|
MD5 | c28e867288c89850e14a613345126ede |
|
BLAKE2b-256 | a2010ea139faa1d9b3615e6c517364e9a14288559bb2cd8d9e66da5d0915df0d |
django_oscar_accounts-3.0.1-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e7a61dcc85bf23e3d887321416a43a4d2994afce5248a0c7f01da34288be8486 |
|
MD5 | 2e8b8a9e35ef45704f18cc014f9734e0 |
|
BLAKE2b-256 | b0bc1c5f648b1f61b0b7856e42f4b356dedab375c9ef3cbaef8ef11266a29806 |