Files
shopship/apps/banker/api/crud_serializers.py
T
mobiniqow 831e656fa3 Fix OTP/SMS, ledger accounting, order tracking, and add reviews app
- 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)
2026-09-15 23:18:05 +03:30

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"]