1.服务记录(service)模块
1.1.models.py 设定
1.1.1.论次服务记录
当订单售出论次服务类商品,或是售出包含论次服务类商品的套盒类商品时,系统会自动抛一笔论次服务记录,当顾客来享受服务时,再用更新的方式完成该笔论次服务记录,并且在完成该笔服务记录时,系统会在自动抛一笔手工费用明细,记录哪家合作门店该支付给哪位员工多少手工费用。
class Cervice(models.Model):updated = models.DateTimeField(verbose_name='服务时间', null=True)order_detail = models.ForeignKey(OrderDetail, verbose_name='订单单身', on_delete=models.PROTECT)good = models.ForeignKey(Good, 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,related_name='cervice_employee', null=True)customer = models.ForeignKey(Customer, verbose_name='顾客', on_delete=models.PROTECT)notes = models.CharField(max_length=64, blank=True, 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='cervice_create_user')update_user = models.ForeignKey('auth.User', verbose_name='异动人员', on_delete=models.PROTECT,related_name='cervice_update_user', null=True)def __str__(self):return '{}'.format(self.pk)class Meta:verbose_name = '论次服务记录'verbose_name_plural = verbose_name
1.1.2.有效期间服务
同论次服务记录,当订单售出有效期间服务类商品,或是售出包含有效期间服务类商品的套盒类商品时,系统会自动抛一笔有效期间服务。
有效期间服务的意思是在一段时间内,顾客可以不限次数的来店享受该项服务,用订单售出有效期间服务类商品后,要先开卡,才会开始计算时间。
class Pervice(models.Model):created = models.DateTimeField(verbose_name='建立时间', default=datetime.now())order_detail = models.ForeignKey(OrderDetail, verbose_name='订单单身', on_delete=models.PROTECT)good = models.ForeignKey(Good, verbose_name='商品', on_delete=models.PROTECT)start_date = models.DateField(verbose_name='有效时间起', blank=True, null=True)end_date = models.DateField(verbose_name='有效时间讫', blank=True, null=True)customer = models.ForeignKey(Customer, verbose_name='顾客', on_delete=models.PROTECT)create_user = models.ForeignKey('auth.User', verbose_name='建立人员', on_delete=models.PROTECT,related_name='pervice_create_user')updated = models.DateTimeField(verbose_name='异动时间', null=True)update_user = models.ForeignKey('auth.User', verbose_name='异动人员', on_delete=models.PROTECT,related_name='pervice_update_user', null=True)def __str__(self):return '{}'.format(self.pk)class Meta:verbose_name = '有效期间服务'verbose_name_plural = verbose_namepermissions = (('active_pervice', '开卡权限'),)
1.1.3.有效期间服务记录
有效期间服务与有效期间服务记录的差别是,有效期间服务记录的是顾客购买了哪项服务商品,而有效期间服务记录则是记录顾客来享受服务的相关数据。
class PerviceDetail(models.Model):pervice = models.ForeignKey(Pervice, 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,related_name='pervicedetail_employee')notes = models.CharField(max_length=64, blank=True, 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='pervicedetail_create_user')updated = models.DateTimeField(verbose_name='异动时间', null=True)update_user = models.ForeignKey('auth.User', verbose_name='异动人员', on_delete=models.PROTECT,related_name='pervicedetail_update_user', null=True)def __str__(self):return '{}'.format(self.pk)class Meta:verbose_name = '有效期间服务记录'verbose_name_plural = verbose_name
1.2.admin.py 设定
1.2.1.CerviceAdmin呈现画面
在顾客来享受服务之后,可以把论次服务记录打印成纸本让顾客签名保存。
"""
论次服务记录检查
1.必须要有理疗师
2.理疗师必须先设定好该商品的手工费
3.如果已经抛了[手工费用明细]则不能再改
"""
class CerviceCheckForm(forms.ModelForm):def clean(self):id = self.instance.idcervice = Cervice.objects.get(id=id)employee = self.cleaned_data.get('employee')if employee is None:raise forms.ValidationError('请选择[理疗师]。')good = cervice.goodfees = Fee.objects.filter(good=good, employee=employee)if fees.count() == 0:raise forms.ValidationError('理疗师必须先设定好该商品的手工费。')fee_details = FeeDetail.objects.filter(type='2', service_id=cervice.id)if fee_details.count() > 0:raise forms.ValidationError('已抛[手工费用明细],不得修改。')@admin.register(Cervice)
class CerviceAdmin(admin.ModelAdmin):list_display = ['id', 'updated', 'order_detail', 'good', 'store', 'employee', 'customer', 'download_page']list_filter = ['customer']fields = ['updated', 'order_detail', 'good', 'store', 'employee', 'customer', 'notes','created', 'create_user', 'update_user']readonly_fields = ['order_detail', 'good', 'customer', 'created', 'create_user', 'updated', 'update_user']form = CerviceCheckFormview_on_site = Falsedef download_page(self, obj):return mark_safe('<a target="_blank" href="{}">下载档案</a>'.format(reverse('service:download_cervice_page', args=[obj.id])))download_page.short_description = '下载档案'def get_queryset(self, request):return super(CerviceAdmin, self).get_queryset(request).\select_related('order_detail', 'good', 'store', 'employee', 'customer', 'create_user', 'update_user')def save_model(self, request, obj, form, change):if not change:obj.create_user = request.usersuper().save_model(request, obj, form, change)else:fee_details = FeeDetail.objects.filter(type='2', service_id=obj.id)#如果还没抛[手工费用明细]if fee_details.count() == 0:obj.update_user = request.userobj.updated = datetime.now()fees = Fee.objects.filter(employee=obj.employee, good=obj.good)#抛一笔[手工费用明细]fee_detail = FeeDetail()fee_detail.type = 2fee_detail.service_id = obj.idfee_detail.store = obj.storefee_detail.employee = obj.employeefee_detail.amount = fees.first().pricefee_detail.save()super().save_model(request, obj, form, change)def has_add_permission(self, request, obj=None):return Falsedef has_delete_permission(self, request, obj=None):return False
1.2.2.PerviceAdmin呈现画面
本画面中,单头有效期间服务是由订单抛转而得,add权限关闭,单身有效期间服务记录则由登入人员新增。
"""
有效期间服务记录检查
1.理疗师必须先设定好该商品的手工费
"""
class PerviceDetailInlineFormset(forms.models.BaseInlineFormSet):def clean(self):for form in self.forms:if form.cleaned_data:pervice = form.cleaned_data.get('pervice')employee = form.cleaned_data.get('employee')#表示是新增的if isinstance(pervice, int) != True:fees = Fee.objects.filter(employee=employee, good=pervice.good)if fees.count() == 0:raise forms.ValidationError('理疗师[{}]必须先设定好商品[{}]的''手工费。'.format(employee.title, pervice.good.title))class PerviceDetailInline(admin.TabularInline):model = PerviceDetailformset = PerviceDetailInlineFormsetfields = ['pervice', 'store', 'employee', 'created', 'notes']readonly_fields = ['created']extra = 0def formfield_for_foreignkey(self, db_field, request, **kwargs):if db_field.name == 'store':profiles = Profile.objects.filter(user=request.user)if profiles.count() > 0:kwargs["queryset"] = Store.objects.filter(id=profiles.first().store.id)kwargs['initial'] = profiles.first().store.idelse:kwargs["queryset"] = Store.objects.filter(id=-1)return super().formfield_for_foreignkey(db_field, request, **kwargs)def has_change_permission(self, request, obj=None):return Falsedef has_delete_permission(self, request, obj=None):return False"""
有效期间服务检查
1.新增[有效期间服务记录]时开始时间必须有值
2.如果异动时间已经超过[有效时间讫]则显示错误
"""
class PerviceCheckForm(forms.ModelForm):def clean(self):id = self.instance.idpervice = Pervice.objects.get(id=id)start_date = pervice.start_dateend_date = pervice.end_dateif start_date is None:raise forms.ValidationError('请先对本笔[有效期间服务]进行开卡动作。')else:if end_date is not None:int_today = time.mktime(time.strptime(datetime.now().strftime('%Y-%m-%d'), '%Y-%m-%d'))int_end_date = time.mktime(time.strptime(end_date.strftime('%Y-%m-%d'), '%Y-%m-%d'))if int(int_today) > int(int_end_date):raise forms.ValidationError('今天已超过本笔[有效期间服务]的[有效时间讫]无法新增。')@admin.register(Pervice)
class PerviceAdmin(admin.ModelAdmin):list_display = ['id', 'created', 'order_detail', 'good', 'customer', 'start_date', 'end_date']fields = ['created', 'order_detail', 'good', 'customer', 'start_date', 'end_date','create_user', 'updated', 'update_user']readonly_fields = ['created', 'order_detail', 'good', 'customer', 'start_date', 'end_date','create_user', 'updated', 'update_user']actions = ['make_actived']form = PerviceCheckForminlines = [PerviceDetailInline]view_on_site = Falsedef save_model(self, request, obj, form, change):if change:#如果已开卡但是尚未有[有效时间讫]时if obj.start_date is not None and obj.end_date is None:period = obj.good.periodobj.end_date = obj.start_date + relativedelta(months=period)super().save_model(request, obj, form, change)def save_formset(self, request, form, formset, change):pervice_details = formset.save(commit=False)for pervice_detail in pervice_details:pervice_detail.create_user = request.userfee_detail = FeeDetail()fee_detail.type = '3'fee_detail.store = pervice_detail.storefee_detail.employee = pervice_detail.employeefees = Fee.objects.filter(employee=pervice_detail.employee, good=pervice_detail.pervice.good)fee_detail.amount = fees.first().pricepervice_detail.save()fee_detail.service_id = pervice_detail.idfee_detail.save()super().save_formset(request, form, formset, change)def get_queryset(self, request):return super(PerviceAdmin, self).get_queryset(request).\select_related('order_detail', 'good', 'customer', 'create_user', 'update_user')def has_add_permission(self, request, obj=None):return Falsedef has_delete_permission(self, request, obj=None):return Falsedef make_actived(self, request, queryset):rows = queryset.update(start_date=datetime.now())if rows > 0:self.message_user(request, '已完成开卡动作')make_actived.allowed_permissions = ('active',)make_actived.short_description = '开卡'def has_active_permission(self, request):opts = self.optscodename = get_permission_codename('active', opts)return request.user.has_perm('%s.%s' % (opts.app_label, codename))
1.2.3.PerviceDetailAdmin呈现画面
当登入人员在PerviceAdmin新增单身的有效期间服务记录后,再到这里来打印纸本让顾客签名,因此add/change/delete权限都是关闭的。
@admin.register(PerviceDetail)
class PerviceDetailAdmin(admin.ModelAdmin):list_display = ['id', 'pervice', 'store', 'employee', 'notes', 'download_page']view_on_site = Falsedef download_page(self, obj):return mark_safe('<a target="_blank" href="{}">下载档案</a>'.format(reverse('service:download_pervice_detail_page', args=[obj.id])))download_page.short_description = '下载档案'def has_add_permission(self, request, obj=None):return Falsedef has_change_permission(self, request, obj=None):return Falsedef has_delete_permission(self, request, obj=None):return False
1.3.urls.py 设定
打印论次服务记录与有效期间服务记录会用到的url设定。
app_name = 'service'urlpatterns = [path('cervice/<int:id>/download/', views.download_cervice_page, name='download_cervice_page'),path('pervice_detail/<int:id>/download/', views.download_pervice_detail_page, name='download_pervice_detail_page'),
]
1.4.views.py 设定
urls.py对应的功能实作。
@staff_member_required
def download_cervice_page(request, id):cervice = Cervice.objects.get(id=id)order_detail = cervice.order_detailtitle = settings.SITE_TITLElang = settings.SITE_LANGhtml = render_to_string('admin/service/cervice/document.html', locals())response = HttpResponse(content_type='application/pdf')response['Content-Disposition'] = 'filename="cervice_{}.pdf"'.format(cervice.id)weasyprint.HTML(string=html).write_pdf(response,stylesheets=[weasyprint.CSS(settings.STATIC_ROOT + 'admin/css/base.css')])return response@staff_member_required
def download_pervice_detail_page(request, id):pervice_detail = PerviceDetail.objects.get(id=id)order_detail = pervice_detail.pervice.order_detailtitle = settings.SITE_TITLElang = settings.SITE_LANGhtml = render_to_string('admin/service/pervice_detail/document.html', locals())response = HttpResponse(content_type='application/pdf')response['Content-Disposition'] = 'filename="pervice_detail_{}.pdf"'.format(pervice_detail.id)weasyprint.HTML(string=html).write_pdf(response,stylesheets=[weasyprint.CSS(settings.STATIC_ROOT + 'admin/css/base.css')])return response