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)
This commit is contained in:
@@ -47,7 +47,7 @@ class ContactCrudSerializer(serializers.ModelSerializer):
|
||||
class MessageTemplateCrudSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = MessageTemplate
|
||||
fields = ["id", "group", "name", "body", "mode"]
|
||||
fields = ["id", "group", "name", "body", "mode", "runtime_field_labels"]
|
||||
|
||||
def validate_group(self, group: ContactGroup | None) -> ContactGroup | None:
|
||||
if group is None:
|
||||
|
||||
@@ -34,7 +34,7 @@ class ContactSerializer(serializers.ModelSerializer):
|
||||
class MessageTemplateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = MessageTemplate
|
||||
fields = ["id", "group_id", "name", "body", "mode"]
|
||||
fields = ["id", "group_id", "name", "body", "mode", "runtime_field_labels"]
|
||||
extra_kwargs = _ID_NO_UNIQUE_CHECK
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.15 on 2026-09-14 23:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('banker', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='messagetemplate',
|
||||
name='runtime_field_labels',
|
||||
field=models.JSONField(blank=True, default=list, verbose_name='فیلدهای زمان اجرا'),
|
||||
),
|
||||
]
|
||||
@@ -100,6 +100,11 @@ class MessageTemplate(models.Model):
|
||||
name = models.CharField(max_length=150, verbose_name=_("نام قالب"))
|
||||
body = models.TextField(verbose_name=_("متن قالب"))
|
||||
mode = models.CharField(max_length=10, choices=Mode.choices)
|
||||
# فیلدهای «زمان اجرا» — مقدارشان از دیتای مخاطب خوانده نمیشود، هر بار
|
||||
# موقع ارسال (یا رسیدن سفارش به مرحلهای که این قالب رویش است) از کاربر
|
||||
# پرسیده میشود. لیست است چون یک قالب میتواند چند فیلدِ اینچنینی
|
||||
# داشته باشد (مثلا هم «کد رهگیری» هم «مبلغ نهایی»).
|
||||
runtime_field_labels = models.JSONField(default=list, blank=True, verbose_name=_("فیلدهای زمان اجرا"))
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
class Meta:
|
||||
|
||||
Reference in New Issue
Block a user