add price_in_dollor field and update related models and serializers
This commit is contained in:
@@ -214,10 +214,10 @@ class ProductVariantInLine(ProductVariantInlineAdminPermission, StackedInline):
|
|||||||
show_change_link = True
|
show_change_link = True
|
||||||
tab = True
|
tab = True
|
||||||
min_num = 1
|
min_num = 1
|
||||||
readonly_fields = ['price', 'sell']
|
readonly_fields = ['price', 'sell', 'price_in_dollor']
|
||||||
# inlines = [DetailModelInLine]
|
# inlines = [DetailModelInLine]
|
||||||
autocomplete_fields = ['product_attributes', 'in_pack_items', 'images', 'details']
|
autocomplete_fields = ['product_attributes', 'in_pack_items', 'images', 'details']
|
||||||
fields = ['images', 'video','input_price', 'min_price', 'currency', 'price', 'discount','in_stock', 'color', 'product_attributes', 'in_pack_items', 'details', 'sell', 'slider_category', 'profit', 'special_discount_percent']
|
fields = ['input_price', 'min_price', 'currency', 'price','price_in_dollor', 'profit', 'discount', 'special_discount_percent', 'in_stock', 'images', 'video', 'color', 'product_attributes', 'in_pack_items', 'details', 'sell', 'slider_category']
|
||||||
# search_fields = ['']
|
# search_fields = ['']
|
||||||
|
|
||||||
def formfield_for_dbfield(self, db_field, request, **kwargs):
|
def formfield_for_dbfield(self, db_field, request, **kwargs):
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Generated by Django 5.1.2 on 2025-12-20 05:53
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('product', '0062_alter_productmodel_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='productvariant',
|
||||||
|
name='price_in_dollor',
|
||||||
|
field=models.FloatField(blank=True, help_text='قیمت محصول به دلار (محاسبه خودکار)', null=True, verbose_name='قیمت به دلار'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='productvariant',
|
||||||
|
name='input_price',
|
||||||
|
field=models.PositiveBigIntegerField(default=0, verbose_name='قیمت ورودی'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='productvariant',
|
||||||
|
name='min_price',
|
||||||
|
field=models.PositiveBigIntegerField(help_text='این قیمت برای کف قیمتی محصول در نظر گرفته میشود', verbose_name='قیمت کف'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='productvariant',
|
||||||
|
name='price',
|
||||||
|
field=models.PositiveBigIntegerField(blank=True, null=True, verbose_name='قیمت محاسبه شده'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='productvariant',
|
||||||
|
name='profit',
|
||||||
|
field=models.PositiveBigIntegerField(default=0, help_text='مقدار سود به ازای هر واحد به تومان', verbose_name='سود (تومان)'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Generated by Django 5.1.2 on 2025-12-20 06:13
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('product', '0063_productvariant_price_in_dollor_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='dollormodel',
|
||||||
|
name='defualt_price',
|
||||||
|
field=models.DecimalField(blank=True, decimal_places=2, default=80000.0, max_digits=10, null=True, verbose_name='قیمت دستی'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='dollormodel',
|
||||||
|
name='price',
|
||||||
|
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='قیمت دلار'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='productvariant',
|
||||||
|
name='currency',
|
||||||
|
field=models.CharField(choices=[('dollor', 'با نوسان دلاری'), ('toman', 'بدون نوسان')], max_length=20, verbose_name='نوع نوسان'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='productvariant',
|
||||||
|
name='input_price',
|
||||||
|
field=models.PositiveBigIntegerField(default=0, help_text='قیمت ورودی محصول', verbose_name='قیمت محصول'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='productvariant',
|
||||||
|
name='price_in_dollor',
|
||||||
|
field=models.DecimalField(blank=True, decimal_places=5, help_text='قیمت محصول به دلار (محاسبه خودکار)', max_digits=12, null=True, verbose_name='قیمت به دلار'),
|
||||||
|
),
|
||||||
|
]
|
||||||
+31
-14
@@ -6,6 +6,8 @@ import requests
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from home.models import ShowCaseSlider
|
from home.models import ShowCaseSlider
|
||||||
|
from decimal import Decimal
|
||||||
|
from dirtyfields import DirtyFieldsMixin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -119,9 +121,9 @@ class SubCategoryModel(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class DollorModel(models.Model):
|
class DollorModel(models.Model):
|
||||||
price = models.FloatField(null=True, blank=True, verbose_name='قیمت دلار')
|
price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True, verbose_name='قیمت دلار')
|
||||||
defualt_price = models.FloatField(
|
defualt_price = models.DecimalField(
|
||||||
null=True, blank=True, default=80000.0, verbose_name='قیمت دستی')
|
max_digits=10, decimal_places=2, null=True, blank=True, default=80000.0, verbose_name='قیمت دستی')
|
||||||
# these fields will avoid dublicate of this model
|
# these fields will avoid dublicate of this model
|
||||||
unique = (('unique', 'unique'),)
|
unique = (('unique', 'unique'),)
|
||||||
unique_filed = models.CharField(
|
unique_filed = models.CharField(
|
||||||
@@ -354,32 +356,35 @@ class DetailModel(models.Model):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ProductVariant(models.Model):
|
class ProductVariant(DirtyFieldsMixin, models.Model):
|
||||||
product = models.ForeignKey(
|
product = models.ForeignKey(
|
||||||
ProductModel, on_delete=models.CASCADE, related_name='variants', verbose_name='محصول')
|
ProductModel, on_delete=models.CASCADE, related_name='variants', verbose_name='محصول')
|
||||||
product_attributes = models.ManyToManyField(
|
product_attributes = models.ManyToManyField(
|
||||||
AttributeValue, verbose_name='ویژگیها', related_name='variant')
|
AttributeValue, verbose_name='ویژگیها', related_name='variant')
|
||||||
in_stock = models.PositiveIntegerField(
|
in_stock = models.PositiveIntegerField(
|
||||||
default=0, verbose_name='تعداد موجود')
|
default=0, verbose_name='تعداد موجود')
|
||||||
price = models.PositiveIntegerField(
|
price = models.PositiveBigIntegerField(
|
||||||
verbose_name='قیمت محاسبه شده', blank=True, null=True)
|
verbose_name='قیمت محاسبه شده', blank=True, null=True)
|
||||||
input_price = models.PositiveIntegerField(
|
input_price = models.PositiveBigIntegerField(
|
||||||
default=0, verbose_name='قیمت ورودی')
|
default=0, verbose_name='قیمت محصول', help_text='قیمت ورودی محصول')
|
||||||
min_price = models.PositiveIntegerField(
|
min_price = models.PositiveBigIntegerField(
|
||||||
verbose_name='قیمت کف', help_text='این قیمت برای کف قیمتی محصول در نظر گرفته میشود')
|
verbose_name='قیمت کف', help_text='این قیمت برای کف قیمتی محصول در نظر گرفته میشود')
|
||||||
profit = models.BigIntegerField(
|
profit = models.PositiveBigIntegerField(
|
||||||
default=0, verbose_name='سود (تومان)', help_text='مقدار سود به ازای هر واحد به تومان')
|
default=0, verbose_name='سود (تومان)', help_text='مقدار سود به ازای هر واحد به تومان')
|
||||||
special_discount_percent = models.SmallIntegerField(
|
special_discount_percent = models.SmallIntegerField(
|
||||||
default=0, verbose_name='درصد تخفیف ویژه', help_text='درصدی که از سود برای محاسبه تخفیف ویژه استفاده میشود')
|
default=0, verbose_name='درصد تخفیف ویژه', help_text='درصدی که از سود برای محاسبه تخفیف ویژه استفاده میشود')
|
||||||
currency_type = (
|
currency_type = (
|
||||||
('dollor', 'دلار'),
|
('dollor', 'با نوسان دلاری'),
|
||||||
('toman', 'تومان'),
|
('toman', 'بدون نوسان'),
|
||||||
)
|
)
|
||||||
in_pack_items = models.ManyToManyField(
|
in_pack_items = models.ManyToManyField(
|
||||||
InPackItems, blank=True, verbose_name='ایتم های داخل پک')
|
InPackItems, blank=True, verbose_name='ایتم های داخل پک')
|
||||||
sell = models.IntegerField(default=0, verbose_name='فروش')
|
sell = models.IntegerField(default=0, verbose_name='فروش')
|
||||||
currency = models.CharField(
|
currency = models.CharField(
|
||||||
verbose_name='نوع ارز', max_length=20, choices=currency_type)
|
verbose_name='نوع نوسان', max_length=20, choices=currency_type)
|
||||||
|
price_in_dollor = models.DecimalField(
|
||||||
|
max_digits=12, decimal_places=5, blank=True, null=True,
|
||||||
|
verbose_name='قیمت به دلار', help_text='قیمت محصول به دلار (محاسبه خودکار)')
|
||||||
discount = models.SmallIntegerField(default=0, verbose_name='تخفیف')
|
discount = models.SmallIntegerField(default=0, verbose_name='تخفیف')
|
||||||
color = models.CharField(
|
color = models.CharField(
|
||||||
verbose_name='رنگ', max_length=7, blank=True, null=True)
|
verbose_name='رنگ', max_length=7, blank=True, null=True)
|
||||||
@@ -451,12 +456,24 @@ class ProductVariant(models.Model):
|
|||||||
|
|
||||||
if self.currency == 'toman':
|
if self.currency == 'toman':
|
||||||
toman_price = self.input_price
|
toman_price = self.input_price
|
||||||
|
# Clear dollar price when currency is toman
|
||||||
|
self.price_in_dollor = None
|
||||||
elif self.currency == 'dollor':
|
elif self.currency == 'dollor':
|
||||||
toman_price = self.input_price * dollor_price
|
# Only recalculate dollar price if input_price has changed
|
||||||
|
if self.is_dirty(check_relationship=False) and 'input_price' in self.get_dirty_fields(check_relationship=False):
|
||||||
|
self.price_in_dollor = Decimal(str(self.input_price)) / Decimal(str(dollor_price))
|
||||||
|
|
||||||
|
# Always recalculate Toman price using stored dollar price and current rate
|
||||||
|
if self.price_in_dollor:
|
||||||
|
toman_price = self.price_in_dollor * Decimal(str(dollor_price))
|
||||||
|
else:
|
||||||
|
# Fallback if price_in_dollor is not set yet
|
||||||
|
toman_price = self.input_price
|
||||||
else:
|
else:
|
||||||
toman_price = self.input_price
|
toman_price = self.input_price
|
||||||
|
self.price_in_dollor = None
|
||||||
|
|
||||||
self.price = max(toman_price, self.min_price)
|
self.price = max(int(toman_price), self.min_price)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
self.set_or_update_price()
|
self.set_or_update_price()
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class ProductVariantSerialzier(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProductVariant
|
model = ProductVariant
|
||||||
exclude = ('min_price', 'sell', 'currency', 'product', 'input_price')
|
exclude = ('min_price', 'sell', 'currency', 'product', 'input_price', 'price_in_dollor')
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|||||||
Reference in New Issue
Block a user