831e656fa3
- Add MessageTemplate.runtime_field_labels so mobile's per-field execution-time labels are actually persisted (were silently dropped) - Fix AdvanceOrderStageView reading the wrong extra-input key, and be honest about SMS send failures instead of always claiming success - Add admin gift-gem SMS notification via Kavenegar - Post real double-entry Transactions for plain (non-invoice) ledger entries so trial balance, the معین screen, and CSV/XLSX exports actually include everyday income/expense entries; backfill existing historical entries via data migration - Rewrite CSV ledger export to produce an actual دفتر معین structure (per-account running balance) instead of a flat row dump - Add invoice percent/promotional discounts, tax presets, ledger discount-percent handling, product SKU/category/expiry fields, and manual ledger-book archiving (replacing auto-archive on new book) - Add reviews app (models, API, admin) for the comments/reviews feature - Update tests for the above; fix two stale assertions left over from earlier work in this branch (معین sheet name, book auto-close)
80 lines
3.1 KiB
Python
80 lines
3.1 KiB
Python
from rest_framework import serializers
|
|
|
|
from apps.banker.models import (
|
|
Contact,
|
|
ContactField,
|
|
ContactGroup,
|
|
MessageTemplate,
|
|
StructuredTemplate,
|
|
StructuredTemplateField,
|
|
)
|
|
|
|
# سریالایزرهای CRUD واقعی (create/update/delete تکی) — برخلاف سریالایزرهای
|
|
# backup در serializers.py، اینها اعتبارسنجی یکتابودن id فعال دارند چون هر
|
|
# رکورد فقط یکبار create میشود، نه هر بار جایگزین کامل.
|
|
|
|
|
|
class ContactGroupCrudSerializer(serializers.ModelSerializer):
|
|
is_general = serializers.BooleanField(read_only=True)
|
|
|
|
class Meta:
|
|
model = ContactGroup
|
|
fields = ["id", "name", "color", "is_general", "member_ids"]
|
|
|
|
|
|
class ContactFieldCrudSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = ContactField
|
|
fields = ["id", "group", "label", "sort_order"]
|
|
|
|
def validate_group(self, group: ContactGroup) -> ContactGroup:
|
|
# قبلا گروه عمومی فیلد سفارشی نداشت (برای کاربرانی که نیاز به
|
|
# پیچیدگی نمیخواستند)؛ چون الان کل مفهوم «گروه» از UX برداشته شده
|
|
# و همهچیز روی همان یک گروه عمومی کار میکند، این محدودیت دیگر
|
|
# معنی ندارد و مانع تعریف هر فیلدی میشد.
|
|
request = self.context["request"]
|
|
if group.user_id != request.user.id:
|
|
raise serializers.ValidationError("این گروه متعلق به شما نیست.")
|
|
return group
|
|
|
|
|
|
class ContactCrudSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Contact
|
|
fields = ["id", "name", "phone", "device_contact_id", "field_values", "channel_ids"]
|
|
|
|
|
|
class MessageTemplateCrudSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = MessageTemplate
|
|
fields = ["id", "group", "name", "body", "mode", "runtime_field_labels"]
|
|
|
|
def validate_group(self, group: ContactGroup | None) -> ContactGroup | None:
|
|
if group is None:
|
|
return group
|
|
request = self.context["request"]
|
|
if group.user_id != request.user.id:
|
|
raise serializers.ValidationError("این گروه متعلق به شما نیست.")
|
|
return group
|
|
|
|
|
|
class StructuredTemplateFieldCrudSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = StructuredTemplateField
|
|
fields = ["id", "template", "label", "sort_order"]
|
|
|
|
def validate_template(self, template: StructuredTemplate) -> StructuredTemplate:
|
|
request = self.context["request"]
|
|
if template.user_id != request.user.id:
|
|
raise serializers.ValidationError("این قالب متعلق به شما نیست.")
|
|
return template
|
|
|
|
|
|
class StructuredTemplateCrudSerializer(serializers.ModelSerializer):
|
|
fields = StructuredTemplateFieldCrudSerializer(many=True, read_only=True)
|
|
|
|
class Meta:
|
|
model = StructuredTemplate
|
|
fields = ["id", "name", "fields", "updated_at"]
|
|
read_only_fields = ["updated_at"]
|