当前位置:   article > 正文

Django用admin开发的产康中心进销存系统-4_用django-admin开发的系统

用django-admin开发的系统

1.财务(finance)模块

1.1.models.py 设定

1.1.1.结账记录

记录每个月的结帐情况。

STATUS_CHOICES = (
    ('0', '开始产生'),
    ('9', '已锁定'),
)


class Account(models.Model):
    his = models.CharField(max_length=7, primary_key=True, unique=True, verbose_name='计算月份')
    status = models.CharField(max_length=1, choices=STATUS_CHOICES, default='0', verbose_name='状态')
    created = models.DateTimeField(auto_now_add=True, verbose_name='建立时间')
    create_user = models.ForeignKey('auth.User', verbose_name='建立人员', on_delete=models.PROTECT,
                                    related_name='account_create_user')
    updated = models.DateTimeField(verbose_name='异动时间', null=True)
    update_user = models.ForeignKey('auth.User', verbose_name='异动人员', on_delete=models.PROTECT,
                                    related_name='account_update_user', null=True)

    def __str__(self):
        return '{}'.format(self.his)

    class Meta:
        verbose_name = '结账记录'
        verbose_name_plural = verbose_name
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

1.1.2.结账金额

每个月所有合作门店的项目金额(目前只有[营业额]与[手工费用])。

ACCOUNT_CHOICES = (
    ('1', '营业额'),
    ('2', '手工费用'),
)


class AccountDetail(models.Model):
    account = models.ForeignKey(Account, verbose_name='结账月份', on_delete=models.PROTECT)
    type = models.CharField(max_length=1, verbose_name='类型', choices=ACCOUNT_CHOICES)
    amount = models.DecimalField(max_digits=16, decimal_places=2, verbose_name='金额')

    def __str__(self):
        return '{}-{}'.format(self.account, ACCOUNT_CHOICES[int(self.type) - 1][1])

    class Meta:
        verbose_name = '结账金额'
        verbose_name_plural = verbose_name
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

1.1.3.门店结账金额

每个月每个合作门店的项目金额(目前只有[营业额]与[手工费用])。

class SccountDetail(models.Model):
    account = models.ForeignKey(Account, verbose_name='结账月份', on_delete=models.PROTECT)
    store = models.ForeignKey(Store, verbose_name='所门分店', on_delete=models.PROTECT)
    type = models.CharField(max_length=1, verbose_name='类型', choices=ACCOUNT_CHOICES)
    amount = models.DecimalField(max_digits=16, decimal_places=2, verbose_name='金额')

    def __str__(self):
        return '{}-{}'.format(self.account, ACCOUNT_CHOICES[int(self.type) - 1][1])

    class Meta:
        verbose_name = '门店结账金额'
        verbose_name_plural = verbose_name
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

1.1.4.每月职员手工费用

顾客来门店享受论次服务有效期间服务记录后,每个月每个合作门店该给服务员工的手工费用金额。

class FeeCost(models.Model):
    account = models.ForeignKey(Account, verbose_name='结账记录', on_delete=models.PROTECT)
    store = models.ForeignKey(Store, verbose_name='所属门店', on_delete=models.PROTECT)
    employee = models.ForeignKey(Employee, verbose_name='职员', on_delete=models.PROTECT)
    amount = models.DecimalField(max_digits=16, decimal_places=2, default=0.0, verbose_name='金额')

    def __str__(self):
        return '{}-{}-{}-{}'.format(self.id, self.account, self.store, self.employee)

    class Meta:
        verbose_name = '每月职员手工费用'
        verbose_name_plural = verbose_name
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

1.1.5.手工费用明细

员工服务完顾客后,就会根据员工对于该服务的手工费用,自动产生手工费用明细

SERVICE_CHOICES = (
    ('2', '论次服务记录'),
    ('3', '有效期间服务记录'),
)


class FeeDetail(models.Model):
    feed = models.DateField(auto_now_add=True, verbose_name='费用日期')
    type = models.CharField(max_length=1, verbose_name='服务类型', choices=SERVICE_CHOICES)
    service_id = models.PositiveIntegerField(verbose_name='服务记录单号')
    store = models.ForeignKey(Store, verbose_name='门店', on_delete=models.PROTECT)
    employee = models.ForeignKey(Employee, verbose_name='职员', on_delete=models.PROTECT)
    amount = models.DecimalField(max_digits=16, decimal_places=2, default=0.0, verbose_name='金额')

    def __str__(self):
        return '{}-{}-{}-{}'.format(self.id, self.feed.strftime('%Y-%m-%d'), self.store, self.employee)

    class Meta:
        verbose_name = '手工费用明细'
        verbose_name_plural = verbose_name
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

1.2.admin.py 设定

1.2.1.AccountAdmin呈现画面

记录每个月的结算情况,AccountAdmin下有SccountDetailInline(门店结账金额)与AccountDetailInline(结账金额),记录该月份总营业额/手工费用与合作分店的营业额/手工费用。
第一个月的记录需从后台写入,接下来月份的空白资料则由上个月产生。

class SccountDetailInline(admin.TabularInline):
    model = SccountDetail
    fields = ['account', 'store', 'type', 'amount']
    extra = 0

    def get_queryset(self, request):
        return super(SccountDetailInline, self).get_queryset(request).order_by('store', 'type')

    def has_add_permission(self, request, obj=None):
        return False

    def has_change_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False


class AccountDetailInline(admin.TabularInline):
    model = AccountDetail
    fields = ['account', 'type', 'amount']
    extra = 0

    def has_add_permission(self, request, obj=None):
        return False

    def has_change_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False


@admin.register(Account)
class AccountAdmin(admin.ModelAdmin):
    list_display = ['his', 'status']
    fields = ['his', 'status', 'created', 'create_user', 'updated', 'update_user']
    readonly_fields = ['his', 'status', 'created', 'create_user', 'updated', 'update_user']
    inlines = [AccountDetailInline, SccountDetailInline]
    view_on_site = False

    def save_model(self, request, obj, form, change):
        if not change:
            obj.create_user = request.user
        else:
            obj.update_user = request.user
            obj.updated = datetime.now()

        super().save_model(request, obj, form, change)

    def has_add_permission(self, request, obj=None):
        return False

    def has_change_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2.2.FeeDetailAdmin呈现画面

手工费用明细是自动抛转,所以add/change/delete权限都是关闭的。

@admin.register(FeeDetail)
class FeeDetailAdmin(admin.ModelAdmin):
    list_display = ['id', 'feed', 'type', 'service_id', 'store', 'employee', 'amount']
    view_on_site = False

    def has_add_permission(self, request, obj=None):
        return False

    def has_change_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述

1.2.3.FeeCostAdmin呈现画面

记录每个月份合作门店该给员工多少手工费用(总额),此处金额是每月结账时自动产生的,所以add/change/delete权限也都是关闭的。

@admin.register(FeeCost)
class FeeCostAdmin(admin.ModelAdmin):
    list_display = ['id', 'account', 'store', 'employee', 'amount']
    view_on_site = False

    def has_add_permission(self, request, obj=None):
        return False

    def has_change_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述

1.3.urls.py 设定

主要是结账记录会用到的url设定。

app_name = 'finance'

urlpatterns = [
    path('account/ajax/status/', views.account_ajax_status, name='account_ajax_status'),
    path('account/ajax/lock', views.account_ajax_lock, name='account_ajax_lock'),
    path('account/ajax/unlock', views.account_ajax_unlock, name='account_ajax_unlock'),
    path('account/ajax/add', views.account_ajax_add, name='account_ajax_add'),
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

1.4.views.py 设定

urls.py对应的功能实作。

def account_ajax_status(request):
    return_dict = {}
    #判断使用者是否有权限检视结账记录
    if request.user.has_perm('finance.view_account'):
        his = request.GET.get('his')
        accounts = Account.objects.filter(his=his)
        if accounts.count() > 0:
            account = accounts.first()

            return_dict['code'] = 0
            return_dict['created'] = '1'
            return_dict['status'] = account.status
        else:
            return_dict['code'] = 1
            return_dict['msg'] = "[{}]月份的[结账记录]尚未产生。".format(his)
    else:
        return_dict['code'] = 1
        return_dict['msg'] = "您无权限检视[结账记录]。"

    return JsonResponse(return_dict)


#锁定[结账记录]并产生结帐金额
def account_ajax_lock(request):
    return_dict = {}
    #判断使用者是否有权限修改结账记录
    if request.user.has_perm('finance.change_account'):
        his = request.GET.get('his')

        try:
            time.strptime(his + '-01', "%Y-%m-%d")
        except:
            return_dict['code'] = 0
            return_dict['msg'] = "his格式错误"
        else:
            accounts = Account.objects.filter(his=his)

            if accounts.count() > 0:
                account = accounts.first()
                if account.status == '0':
                    #预防错误,先删除该月份的[结账金额]
                    account_details = AccountDetail.objects.filter(account=account)
                    if account_details.count() > 0:
                        for account_detail in account_details:
                            account_detail.delete()

                    #删除该月份的[分店结账金额]
                    sccount_details = SccountDetail.objects.filter(account=account)
                    if sccount_details.count() > 0:
                        for sccount_detail in sccount_details:
                            sccount_detail.delete()

                    #删除该月份的[每月职员手工费用]
                    fee_costs = FeeCost.objects.filter(account=account)
                    if fee_costs.count() > 0:
                        for fee_cost in fee_costs:
                            fee_cost.delete()

                    start_day = datetime.strptime(his + '-01', "%Y-%m-%d")
                    end_day = start_day + relativedelta(months=1) + relativedelta(days=-1)

                    #产生新的[结账金额]-1.营业额
                    turnover_detail = AccountDetail()
                    turnover_detail.account = account
                    turnover_detail.type = '1'

                    order_amount = Order.objects.filter(status='1', created__gte=start_day, created__lte=end_day).\
                        aggregate(sum_amount=Sum('amount'))
                    turnover_detail.amount = order_amount['sum_amount']

                    turnover_detail.save()

                    #产生新的[结账金额]-2.手工费用
                    feeamount_detail = AccountDetail()
                    feeamount_detail.account = account
                    feeamount_detail.type = '2'

                    fee_amount = FeeDetail.objects.filter(feed__gte=start_day, feed__lte=end_day).\
                        aggregate(sum_amount=Sum('amount'))
                    feeamount_detail.amount = fee_amount['sum_amount']

                    feeamount_detail.save()

                    #产生新的[分店结账金额]-1.各店营业额
                    stores = Store.objects.all()
                    for store in stores:
                        sturnover_detail = SccountDetail()
                        sturnover_detail.account = account
                        sturnover_detail.store = store
                        sturnover_detail.type = '1'

                        order_amount = Order.objects.filter(status='1', store=store, created__gte=start_day,
                            created__lte=end_day).aggregate(sum_amount=Sum('amount'))
                        sturnover_detail.amount = order_amount['sum_amount']

                        sturnover_detail.save()

                    #产生新的[分店结账金额]-2.手工费用
                    for store in stores:
                        sfeeamount_detail = SccountDetail()
                        sfeeamount_detail.account = account
                        sfeeamount_detail.store = store
                        sfeeamount_detail.type = '2'

                        fee_amount = FeeDetail.objects.filter(store=store, feed__gte=start_day, feed__lte=end_day).\
                            aggregate(sum_amount=Sum('amount'))
                        sfeeamount_detail.amount = fee_amount['sum_amount']

                        sfeeamount_detail.save()

                    #产生新的[每月职员手工费用]
                    feecost_amounts = FeeDetail.objects.filter(feed__gte=start_day, feed__lte=end_day).\
                            values('store_id', 'employee_id').annotate(sum_amount=Sum('amount'))
                    if feecost_amounts.count() > 0:
                        for feecost_amount in feecost_amounts:
                            fee_cost = FeeCost()
                            fee_cost.account = account
                            fee_cost.store = Store.objects.get(id=feecost_amount['store_id'])
                            fee_cost.employee = Employee.objects.get(id=feecost_amount['employee_id'])
                            fee_cost.amount = feecost_amount['sum_amount']
                            fee_cost.save()

                    account.status = '9'
                    account.updated = datetime.now()
                    account.update_user = request.user
                    account.save()

                    return_dict['code'] = 0
                    return_dict['status'] = account.status
                    return_dict['msg'] = "锁定[{}]月份的[结账记录]完成".format(his)
                else:
                    return_dict['code'] = 1
                    return_dict['msg'] = "[{}]月份的[结账记录]已锁定".format(his)
            else:
                return_dict['code'] = 1
                return_dict['msg'] = "[{}]月份的[结账记录]尚未产生".format(his)
    else:
        return_dict['code'] = 1
        return_dict['msg'] = "您无权限修改结账记录"

    return JsonResponse(return_dict)


#解除锁定[结账记录]并删除结帐金额
def account_ajax_unlock(request):
    return_dict = {}
    #判断使用者是否有权限删除结账记录
    if request.user.has_perm('finance.delete_account'):
        his = request.GET.get('his')

        try:
            time.strptime(his + '-01', "%Y-%m-%d")
        except:
            return_dict['code'] = 0
            return_dict['msg'] = "his格式错误"
        else:
            accounts = Account.objects.filter(his=his)

            if accounts.count() > 0:
                account = accounts.first()
                if account.status == '9':
                    #删除该月份的[结账金额]
                    account_details = AccountDetail.objects.filter(account=account)
                    if account_details.count() > 0:
                        for account_detail in account_details:
                            account_detail.delete()

                    #删除该月份的[分店结账金额]
                    sccount_details = SccountDetail.objects.filter(account=account)
                    if sccount_details.count() > 0:
                        for sccount_detail in sccount_details:
                            sccount_detail.delete()

                    #删除该月份的[每月职员手工费用]
                    fee_costs = FeeCost.objects.filter(account=account)
                    if fee_costs.count() > 0:
                        for fee_cost in fee_costs:
                            fee_cost.delete()

                    account.status = '0'
                    account.updated = datetime.now()
                    account.update_user = request.user
                    account.save()

                    return_dict['code'] = 0
                    return_dict['status'] = account.status
                    return_dict['msg'] = "解除锁定[{}]月份的[结账记录]完成".format(his)
                else:
                    return_dict['code'] = 1
                    return_dict['msg'] = "[{}]月份的[结账记录]尚未锁定".format(his)
            else:
                return_dict['code'] = 1
                return_dict['msg'] = "[{}]月份的[结账记录]尚未产生".format(his)
    else:
        return_dict['code'] = 1
        return_dict['msg'] = "您无权限删除结账记录"

    return JsonResponse(return_dict)


#新增[结账记录]
def account_ajax_add(request):
    return_dict = {}
    #判断使用者是否有权限新增结账记录
    if request.user.has_perm('finance.add_account'):
        his = request.GET.get('his')
        next_month = datetime.strptime(his + '-01','%Y-%m-%d') + relativedelta(months=1)
        next_his = next_month.strftime('%Y-%m')

        last_his = datetime.strftime(datetime.now() + relativedelta(months=-1), '%Y-%m')

        if last_his == next_his:
            accounts = Account.objects.filter(his=his)

            if accounts.count() > 0:
                account = accounts.first()
                if account.status == '9':
                    check_accounts = Account.objects.filter(his=next_his)
                    if check_accounts.count() == 0:
                        new_account = Account()
                        new_account.his = next_his
                        new_account.create_user = request.user
                        new_account.save()

                        return_dict['code'] = 0
                        return_dict['msg'] = "已新增[{}]月份的[结账记录]".format(new_account.his)
                    else:
                        return_dict['code'] = 1
                        return_dict['msg'] = "已有[{}]月份[结账记录]".format(next_his)
                else:
                    return_dict['code'] = 1
                    return_dict['msg'] = "产生[{}]月份结账记录之前请先锁定[{}]月份的结账记录".format(next_his, his)
            else:
                return_dict['code'] = 1
                return_dict['msg'] = "产生[{}]月份结账记录之前请先产生[{}]月份的结账记录".format(next_his, his)
        else:
            return_dict['code'] = 1
            return_dict['msg'] = "本月只能新增[{}]月份的[结账记录]".format(last_his)
    else:
        return_dict['code'] = 1
        return_dict['msg'] = "您无权限新增[结账记录]"

    return JsonResponse(return_dict)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/170079
推荐阅读
相关标签
  

闽ICP备14008679号