free plans in set_plans
This commit is contained in:
commit
68a67caab5
@ -1306,7 +1306,7 @@ class Dealer(models.Model, LocalizedNameMixin):
|
|||||||
)
|
)
|
||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
||||||
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
||||||
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator()])
|
||||||
address = models.CharField(
|
address = models.CharField(
|
||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
)
|
)
|
||||||
@ -1432,7 +1432,7 @@ class Staff(models.Model):
|
|||||||
last_name = models.CharField(max_length=255, verbose_name=_("Last Name"))
|
last_name = models.CharField(max_length=255, verbose_name=_("Last Name"))
|
||||||
|
|
||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
||||||
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator()])
|
||||||
staff_type = models.CharField(
|
staff_type = models.CharField(
|
||||||
choices=StaffTypes.choices, max_length=255, verbose_name=_("Staff Type")
|
choices=StaffTypes.choices, max_length=255, verbose_name=_("Staff Type")
|
||||||
)
|
)
|
||||||
@ -1826,7 +1826,7 @@ class Organization(models.Model, LocalizedNameMixin):
|
|||||||
)
|
)
|
||||||
vrn = models.CharField(max_length=15, verbose_name=_("VAT Registration Number"))
|
vrn = models.CharField(max_length=15, verbose_name=_("VAT Registration Number"))
|
||||||
email = models.EmailField(verbose_name=_("Email"))
|
email = models.EmailField(verbose_name=_("Email"))
|
||||||
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator()])
|
||||||
address = models.CharField(
|
address = models.CharField(
|
||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
)
|
)
|
||||||
@ -1960,7 +1960,7 @@ class Representative(models.Model, LocalizedNameMixin):
|
|||||||
id_number = models.CharField(
|
id_number = models.CharField(
|
||||||
max_length=10, unique=True, verbose_name=_("ID Number")
|
max_length=10, unique=True, verbose_name=_("ID Number")
|
||||||
)
|
)
|
||||||
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator()])
|
||||||
email = models.EmailField(max_length=255, verbose_name=_("Email Address"))
|
email = models.EmailField(max_length=255, verbose_name=_("Email Address"))
|
||||||
address = models.CharField(
|
address = models.CharField(
|
||||||
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
max_length=200, blank=True, null=True, verbose_name=_("Address")
|
||||||
@ -2668,7 +2668,7 @@ class Vendor(models.Model, LocalizedNameMixin):
|
|||||||
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name"))
|
||||||
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
name = models.CharField(max_length=255, verbose_name=_("English Name"))
|
||||||
contact_person = models.CharField(max_length=100, verbose_name=_("Contact Person"))
|
contact_person = models.CharField(max_length=100, verbose_name=_("Contact Person"))
|
||||||
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator])
|
phone_number = models.CharField(max_length=255, verbose_name=_("Phone Number"),validators=[SaudiPhoneNumberValidator()])
|
||||||
email = models.EmailField(max_length=255, verbose_name=_("Email Address"))
|
email = models.EmailField(max_length=255, verbose_name=_("Email Address"))
|
||||||
address = models.CharField(max_length=200, verbose_name=_("Address"))
|
address = models.CharField(max_length=200, verbose_name=_("Address"))
|
||||||
logo = models.ImageField(
|
logo = models.ImageField(
|
||||||
|
|||||||
@ -1571,13 +1571,13 @@ def _post_sale_and_cogs(invoice, dealer):
|
|||||||
# calc = CarFinanceCalculator(invoice)
|
# calc = CarFinanceCalculator(invoice)
|
||||||
data = get_finance_data(invoice,dealer)
|
data = get_finance_data(invoice,dealer)
|
||||||
car = data.get("car")
|
car = data.get("car")
|
||||||
cash_acc = entity.get_all_accounts().filter(role_default=True, role=roles.ASSET_CA_CASH).first()
|
cash_acc = entity.get_default_coa_accounts().filter(role_default=True, role=roles.ASSET_CA_CASH).first()
|
||||||
ar_acc = entity.get_all_accounts().filter(role_default=True, role=roles.ASSET_CA_RECEIVABLES).first()
|
ar_acc = entity.get_default_coa_accounts().filter(role_default=True, role=roles.ASSET_CA_RECEIVABLES).first()
|
||||||
vat_acc = entity.get_all_accounts().filter(role_default=True, role=roles.LIABILITY_CL_TAXES_PAYABLE).first()
|
vat_acc = entity.get_default_coa_accounts().filter(role_default=True, role=roles.LIABILITY_CL_TAXES_PAYABLE).first()
|
||||||
car_rev = entity.get_all_accounts().filter(role_default=True, role=roles.INCOME_OPERATIONAL).first()
|
car_rev = entity.get_default_coa_accounts().filter(role_default=True, role=roles.INCOME_OPERATIONAL).first()
|
||||||
add_rev = entity.get_all_accounts().filter(role_default=True, role=roles.INCOME_OPERATIONAL).first()
|
add_rev = entity.get_default_coa_accounts().filter(code="4020").first()
|
||||||
cogs_acc = entity.get_all_accounts().filter(role_default=True, role=roles.COGS).first()
|
cogs_acc = entity.get_default_coa_accounts().filter(role_default=True, role=roles.COGS).first()
|
||||||
inv_acc = entity.get_all_accounts().filter(role_default=True, role=roles.ASSET_CA_INVENTORY).first()
|
inv_acc = entity.get_default_coa_accounts().filter(role_default=True, role=roles.ASSET_CA_INVENTORY).first()
|
||||||
|
|
||||||
# for car_data in data['cars']:
|
# for car_data in data['cars']:
|
||||||
# car = invoice.get_itemtxs_data()[0].filter(
|
# car = invoice.get_itemtxs_data()[0].filter(
|
||||||
@ -1588,7 +1588,7 @@ def _post_sale_and_cogs(invoice, dealer):
|
|||||||
net_car_price = Decimal(data['discounted_price'])
|
net_car_price = Decimal(data['discounted_price'])
|
||||||
net_additionals_price = Decimal(data['additional_services']['total'])
|
net_additionals_price = Decimal(data['additional_services']['total'])
|
||||||
vat_amount = Decimal(data['vat_amount'])
|
vat_amount = Decimal(data['vat_amount'])
|
||||||
grand_total = net_car_price + net_additionals_price + vat_amount
|
grand_total = net_car_price + car.get_additional_services_amount_ + vat_amount
|
||||||
cost_total = Decimal(car.cost_price)
|
cost_total = Decimal(car.cost_price)
|
||||||
discount_amount =Decimal(data['discount_amount'])
|
discount_amount =Decimal(data['discount_amount'])
|
||||||
|
|
||||||
@ -1608,7 +1608,8 @@ def _post_sale_and_cogs(invoice, dealer):
|
|||||||
journal_entry=je_sale,
|
journal_entry=je_sale,
|
||||||
account=cash_acc,
|
account=cash_acc,
|
||||||
amount=grand_total,
|
amount=grand_total,
|
||||||
tx_type='debit'
|
tx_type='debit',
|
||||||
|
description='Debit to Cash on Hand'
|
||||||
)
|
)
|
||||||
|
|
||||||
# # Cr A/R (clear the receivable)
|
# # Cr A/R (clear the receivable)
|
||||||
@ -1624,7 +1625,8 @@ def _post_sale_and_cogs(invoice, dealer):
|
|||||||
journal_entry=je_sale,
|
journal_entry=je_sale,
|
||||||
account=vat_acc,
|
account=vat_acc,
|
||||||
amount=vat_amount,
|
amount=vat_amount,
|
||||||
tx_type='credit'
|
tx_type='credit',
|
||||||
|
description="Credit to Tax Payable"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Cr Sales – Car
|
# Cr Sales – Car
|
||||||
@ -1632,16 +1634,26 @@ def _post_sale_and_cogs(invoice, dealer):
|
|||||||
journal_entry=je_sale,
|
journal_entry=je_sale,
|
||||||
account=car_rev,
|
account=car_rev,
|
||||||
amount=net_car_price,
|
amount=net_car_price,
|
||||||
tx_type='credit'
|
tx_type='credit',
|
||||||
|
description=" Credit to Car Sales"
|
||||||
)
|
)
|
||||||
|
|
||||||
if net_additionals_price > 0:
|
if car.get_additional_services_amount > 0:
|
||||||
# Cr Sales – Additional Services
|
# Cr Sales – Additional Services
|
||||||
TransactionModel.objects.create(
|
TransactionModel.objects.create(
|
||||||
journal_entry=je_sale,
|
journal_entry=je_sale,
|
||||||
account=add_rev,
|
account=add_rev,
|
||||||
amount=net_additionals_price,
|
amount=car.get_additional_services_amount,
|
||||||
tx_type='credit'
|
tx_type='credit',
|
||||||
|
description="Credit to After-Sales Services"
|
||||||
|
)
|
||||||
|
TransactionModel.objects.create(
|
||||||
|
journal_entry=je_sale,
|
||||||
|
|
||||||
|
account=vat_acc,
|
||||||
|
amount=car.get_additional_services_vat,
|
||||||
|
tx_type='credit',
|
||||||
|
description="Credit to Tax Payable (Additional Services)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
@ -1660,7 +1672,7 @@ def _post_sale_and_cogs(invoice, dealer):
|
|||||||
journal_entry=je_cogs,
|
journal_entry=je_cogs,
|
||||||
account=cogs_acc,
|
account=cogs_acc,
|
||||||
amount=cost_total,
|
amount=cost_total,
|
||||||
tx_type='debit'
|
tx_type='debit',
|
||||||
)
|
)
|
||||||
|
|
||||||
# Cr Inventory
|
# Cr Inventory
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
from django.core.validators import RegexValidator
|
from django.core.validators import RegexValidator
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
import re
|
||||||
|
|
||||||
class SaudiPhoneNumberValidator(RegexValidator):
|
class SaudiPhoneNumberValidator(RegexValidator):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
regex=r"^(\+9665|05)[0-9]{8}$",
|
regex=r"^(\+9665|05)[0-9]{8}$",
|
||||||
message=_("Enter a valid Saudi phone number (05XXXXXXXX or +9665XXXXXXXX)"),
|
message=_("Enter a valid Saudi phone number (05XXXXXXXX or +9665XXXXXXXX)"),
|
||||||
)
|
)
|
||||||
|
def __call__(self, value):
|
||||||
|
# Remove any whitespace, dashes, or other separators
|
||||||
|
cleaned_value = re.sub(r'[\s\-\(\)\.]', '', str(value))
|
||||||
|
super().__call__(cleaned_value)
|
||||||
@ -4,6 +4,13 @@ from decimal import Decimal
|
|||||||
|
|
||||||
def run():
|
def run():
|
||||||
# Create quotas first
|
# Create quotas first
|
||||||
|
free_quota = Quota.objects.create(
|
||||||
|
codename="free_quota",
|
||||||
|
name="Free Features",
|
||||||
|
description="Free plan features",
|
||||||
|
is_boolean=True,
|
||||||
|
url="pricing",
|
||||||
|
)
|
||||||
basic_quota = Quota.objects.create(
|
basic_quota = Quota.objects.create(
|
||||||
codename="basic_quota",
|
codename="basic_quota",
|
||||||
name="Basic Features",
|
name="Basic Features",
|
||||||
@ -27,7 +34,19 @@ def run():
|
|||||||
is_boolean=True,
|
is_boolean=True,
|
||||||
url="pricing",
|
url="pricing",
|
||||||
)
|
)
|
||||||
|
# Create the plans
|
||||||
|
free_plan = Plan.objects.create(
|
||||||
|
name="Free",
|
||||||
|
description="Free plan with limited features",
|
||||||
|
price=Decimal("0.00"), # 0
|
||||||
|
period=7, # 1 week
|
||||||
|
default=True,
|
||||||
|
available=True,
|
||||||
|
visible=True,
|
||||||
|
order=1,
|
||||||
|
)
|
||||||
|
free_plan.quotas.add(free_quota)
|
||||||
|
|
||||||
# Create the plans
|
# Create the plans
|
||||||
basic_plan = Plan.objects.create(
|
basic_plan = Plan.objects.create(
|
||||||
name="Basic",
|
name="Basic",
|
||||||
|
|||||||
@ -138,11 +138,11 @@
|
|||||||
</div> {% endcomment %}
|
</div> {% endcomment %}
|
||||||
<div class="d-flex justify-content-end gap-2">
|
<div class="d-flex justify-content-end gap-2">
|
||||||
{% if not dealer.user.userplan %}
|
{% if not dealer.user.userplan %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-success"><span class="fas fa-cart-plus me-2"></span>{{ _("Subscribe Now") }}</a>
|
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-outline-primary"><span class="fas fa-cart-plus me-2"></span>{{ _("Subscribe Now") }}</a>
|
||||||
{% elif dealer.user.userplan.is_expired %}
|
{% elif dealer.user.userplan.is_expired %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-warning"><span class="fas fa-redo-alt me-2"></span>{{ _("Renew") }}</a>
|
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-outline-warning"><span class="fas fa-redo-alt me-2"></span>{{ _("Renew") }}</a>
|
||||||
{% elif dealer.user.userplan.plan.name != "Enterprise" %}
|
{% elif dealer.user.userplan.plan.name != "Enterprise" %}
|
||||||
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-primary"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade Plan") }}</a>
|
<a href="{% url 'pricing_page' request.dealer.slug %}" class="btn btn-outline-primary"><span class="fas fa-rocket me-2"></span>{{ _("Upgrade Plan") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -39,7 +39,7 @@
|
|||||||
{% if inventory.total_cars > 0 %}
|
{% if inventory.total_cars > 0 %}
|
||||||
<div class="row justify-content-between">
|
<div class="row justify-content-between">
|
||||||
<div class="col-sm-12 ">
|
<div class="col-sm-12 ">
|
||||||
<div class="card border h-100 w-100 p-lg-10">
|
<div class="card border h-100 w-100 p-lg-10" style="">
|
||||||
|
|
||||||
<div class="road">
|
<div class="road">
|
||||||
<p class="moving-tenhal "> {% trans "Powered By Tenhal" %} </p>
|
<p class="moving-tenhal "> {% trans "Powered By Tenhal" %} </p>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user