before change Ticket Desc to TextArea

This commit is contained in:
mohammad javad fesahat committed 2024-07-25 09:06:30 +03:30
1 parent f7dbd02a6c
commit ef18434b86
55 files changed
+1026 -59

No files matched your search

+2
View File
@@ -7,6 +7,8 @@ __pycache__/
# C extensions
*.so
*.xlsx
# Distribution / packaging
.Python
build/
+10
View File
@@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# GitHub Copilot persisted chat sessions
/copilot/chatSessions
Generated
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="accountSettings">
<option name="activeProfile" value="profile:default" />
<option name="activeRegion" value="us-east-1" />
<option name="recentlyUsedProfiles">
<list>
<option value="profile:default" />
</list>
</option>
<option name="recentlyUsedRegions">
<list>
<option value="us-east-1" />
</list>
</option>
</component>
<component name="connectionManager">
<option name="activeConnectionId" value="sso;us-east-1;https://view.awsapps.com/start" />
</component>
</project>
+5 -2
View File
@@ -13,8 +13,11 @@
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.10" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
+4 -1
View File
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="crmApiEnv" project-jdk-type="Python SDK" />
<component name="Black">
<option name="sdkName" value="Python 3.12 (venv)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
</project>
+174 -14
View File
@@ -1,16 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="87c5db51-3e89-4a98-9bbb-121c9c52ab3c" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/.idea/.gitignore" afterDir="false" />
<change afterPath="$PROJECT_DIR$/.idea/aws.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/crmApi.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/crmApi.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/cuser/models.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/cuser/models.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/customer/selectors.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/customer/selectors.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/jwt_auth/services.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/jwt_auth/services.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/lead/selectors.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/lead/selectors.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/lead/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/lead/views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/admin.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/admin.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/models.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/models.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/selectors/cart.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/selectors/cart.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/selectors/order.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/selectors/order.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/selectors/product.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/selectors/product.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/views/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/views/__init__.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/views/excel_import.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/views/excel_import.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/views/order.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/views/order.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/views/product.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/views/product.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/shop/views/product_category.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/shop/views/product_category.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/apps/workspace/models.py" beforeDir="false" afterPath="$PROJECT_DIR$/apps/workspace/models.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/asgi.py" beforeDir="false" afterPath="$PROJECT_DIR$/config/asgi.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/settings/base.py" beforeDir="false" afterPath="$PROJECT_DIR$/config/settings/base.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/settings/production.py" beforeDir="false" afterPath="$PROJECT_DIR$/config/settings/production.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/config/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/wsgi.py" beforeDir="false" afterPath="$PROJECT_DIR$/config/wsgi.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/requirements/base.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements/base.txt" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
@@ -34,23 +54,35 @@
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 3
}</component>
<component name="ProjectId" id="2SvKNIPBcTXVjDKPSdS8NHW9I0w" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
&quot;last_opened_file_path&quot;: &quot;E:/Projects/crmProject/Project/api-Project/crmApi&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable&quot;
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"Django Server.crmApi.executor": "Run",
"RunOnceActivity.OpenDjangoStructureViewOnStart": "true",
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"WebServerToolWindowFactoryState": "false",
"git-widget-placeholder": "main",
"ignore.virus.scanning.warn.message": "true",
"last_opened_file_path": "C:/Users/mjavad/Projects/crmProject/Project/api-Project/crmApi",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "http.proxy",
"vue.rearranger.settings.migration": "true"
}
}</component>
}]]></component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="E:\Projects\crmProject\Project\api-Project\crmApi\utils" />
@@ -60,13 +92,14 @@
<component name="RunManager">
<configuration name="crmApi" type="Python.DjangoServer" factoryName="Django server">
<module name="crmApi" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="WORKING_DIRECTORY" value="C:\Users\mjavad\Projects\crmProject\Project\api-Project\crmApi" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
@@ -82,6 +115,14 @@
<method v="2" />
</configuration>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-js-predefined-1d06a55b98c1-74d2a5396914-JavaScript-PY-241.14494.241" />
<option value="bundled-python-sdk-0509580d9d50-28c9f5db9ffe-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-241.14494.241" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
@@ -100,7 +141,38 @@
<workItem from="1702900258020" duration="63755000" />
<workItem from="1704088148329" duration="105568000" />
<workItem from="1704951046597" duration="135372000" />
<workItem from="1706950546279" duration="9716000" />
<workItem from="1706950546279" duration="21524000" />
<workItem from="1707974605580" duration="43207000" />
<workItem from="1710141658112" duration="240000" />
<workItem from="1710142130443" duration="1078000" />
<workItem from="1710150399673" duration="961000" />
<workItem from="1710419485683" duration="68525000" />
<workItem from="1710488609275" duration="177000" />
<workItem from="1710488798818" duration="2376000" />
<workItem from="1710491283739" duration="274000" />
<workItem from="1710491571470" duration="2407000" />
<workItem from="1710859420770" duration="5021000" />
<workItem from="1711518197148" duration="371000" />
<workItem from="1711518633367" duration="2351000" />
<workItem from="1711525074800" duration="90000" />
<workItem from="1711525175741" duration="553000" />
<workItem from="1711525746440" duration="138000" />
<workItem from="1711525904502" duration="187000" />
<workItem from="1711526396806" duration="5937000" />
<workItem from="1711602888442" duration="717000" />
<workItem from="1711606336704" duration="5357000" />
<workItem from="1711869672173" duration="628000" />
<workItem from="1711878111438" duration="700000" />
<workItem from="1711880635851" duration="981000" />
<workItem from="1712055178474" duration="84000" />
<workItem from="1713166182071" duration="22113000" />
<workItem from="1714581267648" duration="6000" />
<workItem from="1714884894390" duration="1477000" />
<workItem from="1715065792878" duration="1238000" />
<workItem from="1715426896536" duration="10640000" />
<workItem from="1719038043515" duration="2436000" />
<workItem from="1720441183640" duration="1046000" />
<workItem from="1720442591368" duration="302000" />
</task>
<servers />
</component>
@@ -118,4 +190,92 @@
</map>
</option>
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/shop/views/excel_import.py</url>
<line>16</line>
<option name="timeStamp" value="2" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/shop/views/excel_import.py</url>
<line>19</line>
<option name="timeStamp" value="3" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/shop/views/excel_import.py</url>
<line>21</line>
<option name="timeStamp" value="4" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/shop/views/excel_import.py</url>
<line>23</line>
<option name="timeStamp" value="5" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/shop/views/excel_import.py</url>
<line>29</line>
<option name="timeStamp" value="6" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/shop/views/excel_import.py</url>
<line>30</line>
<option name="timeStamp" value="7" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/shop/views/excel_import.py</url>
<line>39</line>
<option name="timeStamp" value="8" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/jwt_auth/services.py</url>
<line>14</line>
<option name="timeStamp" value="13" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/jwt_auth/services.py</url>
<line>17</line>
<option name="timeStamp" value="14" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/jwt_auth/services.py</url>
<line>19</line>
<option name="timeStamp" value="15" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/jwt_auth/services.py</url>
<line>20</line>
<option name="timeStamp" value="16" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/jwt_auth/services.py</url>
<line>37</line>
<option name="timeStamp" value="17" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/jwt_auth/services.py</url>
<line>38</line>
<option name="timeStamp" value="18" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/jwt_auth/views.py</url>
<line>116</line>
<option name="timeStamp" value="19" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/apps/jwt_auth/views.py</url>
<line>118</line>
<option name="timeStamp" value="20" />
</line-breakpoint>
</breakpoints>
<default-breakpoints>
<breakpoint type="python-exception">
<properties notifyOnTerminate="true" exception="BaseException">
<option name="notifyOnTerminate" value="true" />
</properties>
</breakpoint>
</default-breakpoints>
</breakpoint-manager>
</component>
</project>
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-04-16 06:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cuser', '0011_cuserrole_customer_panel'),
]
operations = [
migrations.AddField(
model_name='cuserrole',
name='is_admin',
field=models.BooleanField(blank=True, default=None, null=True),
),
]
+1
View File
@@ -26,6 +26,7 @@ class CuserRole(BaseModel):
mobile = models.PositiveBigIntegerField(null=False, blank=False)
mobile_verify = models.BooleanField(default=False)
customer_panel = models.BooleanField(default=None, blank=True, null=True)
is_admin = models.BooleanField(default=None, blank=True, null=True)
sys_ws = models.ForeignKey(WorkspaceModel, on_delete=models.CASCADE, null=True, blank=True, default=None)
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
-1
View File
@@ -101,7 +101,6 @@ def customer_form_item(request):
'shahr': shahr,
'responsible_groups': responsible_groups
}
return data
@@ -0,0 +1,19 @@
# Generated by Django 4.2.1 on 2024-02-10 09:59
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('jwt_auth', '0081_alter_cuserroleloginopt_uuid'),
]
operations = [
migrations.AlterField(
model_name='cuserroleloginopt',
name='uuid',
field=models.UUIDField(default=uuid.UUID('6537ef3d-8ef9-486d-a1b6-7892e021dc19'), unique=True),
),
]
@@ -0,0 +1,19 @@
# Generated by Django 4.2.1 on 2024-02-10 11:06
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('jwt_auth', '0082_alter_cuserroleloginopt_uuid'),
]
operations = [
migrations.AlterField(
model_name='cuserroleloginopt',
name='uuid',
field=models.UUIDField(default=uuid.UUID('745db968-c736-42cd-ad3d-4de41e8e5b98'), unique=True),
),
]
@@ -0,0 +1,19 @@
# Generated by Django 4.2.1 on 2024-02-18 09:44
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('jwt_auth', '0083_alter_cuserroleloginopt_uuid'),
]
operations = [
migrations.AlterField(
model_name='cuserroleloginopt',
name='uuid',
field=models.UUIDField(default=uuid.UUID('96211808-5203-451b-a6ce-eee394e02afc'), unique=True),
),
]
@@ -0,0 +1,19 @@
# Generated by Django 4.2.1 on 2024-02-27 09:59
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('jwt_auth', '0084_alter_cuserroleloginopt_uuid'),
]
operations = [
migrations.AlterField(
model_name='cuserroleloginopt',
name='uuid',
field=models.UUIDField(default=uuid.UUID('561d07a5-fff4-436f-bab3-4e3b16e05fba'), unique=True),
),
]
@@ -0,0 +1,19 @@
# Generated by Django 4.2.1 on 2024-04-16 06:28
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('jwt_auth', '0085_alter_cuserroleloginopt_uuid'),
]
operations = [
migrations.AlterField(
model_name='cuserroleloginopt',
name='uuid',
field=models.UUIDField(default=uuid.UUID('b5346fad-8d28-482d-8ed9-2807850b6a4d'), unique=True),
),
]
+24 -4
View File
@@ -5,14 +5,16 @@ from apps.jwt_auth.models import CUserRoleLoginOpt
from apps.cuser.models import CuserRole as CuserRoleModel, SmsOpt as SmsOptModel
from django.utils import timezone
from rest_framework import exceptions
CUser = get_user_model()
import requests
from datetime import timedelta
CUser = get_user_model()
def login_by_username(username: str, password: str) -> CUserRoleLoginOpt:
try:
print(username)
user = CUser.objects.get(username=username)
print(user)
if user and user.check_password(password):
cuser_roles = CuserRoleModel.objects.filter(cuser=user)
@@ -52,21 +54,35 @@ def login_by_mobile(mobile: int):
random_number = random.randint(100000, 999999)
try:
SmsOptModel.objects.filter(mobile=mobile).delete()
except Exception as exp:
pass
opt_code = SmsOptModel(mobile=mobile, opt=123456)
expire_time = timezone.now() + timedelta(minutes=3)
opt_code = SmsOptModel(mobile=mobile, opt=random_number, expire=expire_time)
opt_code.save()
sms_text = f' کد ورود شما: {random_number}'
payload = {
'USERNAME': 'vsms7937',
'PASSWORD': '335577775533',
'FROM': '30005367',
'TO': int(mobile),
'TEXT': f'{sms_text}'
}
r = requests.get('http://www.0098sms.com/sendsmslink.aspx', params=payload)
except Exception as exp:
raise exceptions.ValidationError({'error': "mobile not found"})
def verify_mobile_and_get_token(mobile: int, opt: int) -> CUserRoleLoginOpt:
try:
opt_obj = SmsOptModel.objects.filter(mobile=mobile, opt=opt)[0]
time_now = timezone.now()
opt_obj = SmsOptModel.objects.filter(mobile=mobile, opt=opt, expire__gte=time_now)[0]
if opt_obj:
cuser_roles = CuserRoleModel.objects.filter(cuser__mobile=mobile, is_active=True)
@@ -87,4 +103,8 @@ def verify_mobile_and_get_token(mobile: int, opt: int) -> CUserRoleLoginOpt:
SmsOptModel.objects.filter(mobile=mobile).delete()
return login_opts
except Exception as exp:
try:
SmsOptModel.objects.filter(mobile=mobile).delete()
except Exception as exp:
pass
raise exceptions.ValidationError({'error': "cannot verify this mobile and opt code:"+str(exp)})
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-10 09:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lead', '0035_alter_lead_status'),
]
operations = [
migrations.AlterField(
model_name='lead',
name='status',
field=models.CharField(blank=True, choices=[('SU', 'OK'), ('UN', 'unknown'), ('FA', 'FAIL')], default='UN', max_length=2, null=True),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-10 11:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lead', '0036_alter_lead_status'),
]
operations = [
migrations.AlterField(
model_name='lead',
name='status',
field=models.CharField(blank=True, choices=[('UN', 'unknown'), ('SU', 'OK'), ('FA', 'FAIL')], default='UN', max_length=2, null=True),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-18 09:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lead', '0037_alter_lead_status'),
]
operations = [
migrations.AlterField(
model_name='lead',
name='status',
field=models.CharField(blank=True, choices=[('FA', 'FAIL'), ('SU', 'OK'), ('UN', 'unknown')], default='UN', max_length=2, null=True),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-27 09:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lead', '0038_alter_lead_status'),
]
operations = [
migrations.AlterField(
model_name='lead',
name='status',
field=models.CharField(blank=True, choices=[('SU', 'OK'), ('UN', 'unknown'), ('FA', 'FAIL')], default='UN', max_length=2, null=True),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-04-16 06:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lead', '0039_alter_lead_status'),
]
operations = [
migrations.AlterField(
model_name='lead',
name='status',
field=models.CharField(blank=True, choices=[('FA', 'FAIL'), ('SU', 'OK'), ('UN', 'unknown')], default='UN', max_length=2, null=True),
),
]
+21 -3
View File
@@ -3,7 +3,7 @@ from apps.lead.models import Lead as LeadModel, LeadType as LeadTypeModel,\
from apps.shop.models import ProductType as ProductTypeModel
from apps.workspace.models import City as CityModel
from utils.get_user_workspace import get_user_workspace_uuid
from utils.get_cuser_role import get_cuser_role_uuid
from utils.get_cuser_role import get_cuser_role_uuid, get_cuser_role
from rest_framework import exceptions
@@ -12,7 +12,16 @@ def list_leads(request) -> LeadModel:
try:
workspace_uuid = get_user_workspace_uuid(request)
cuser_role_uuid = get_cuser_role_uuid(request)
leads = LeadModel.objects.filter(sys_ws__uuid=workspace_uuid, cuser_role__uuid=cuser_role_uuid).order_by('-created_at')
cuser_role = get_cuser_role(request)
base_filter = {
'sys_ws__uuid': workspace_uuid,
}
if not cuser_role.is_admin:
base_filter['cuser_role__uuid'] = cuser_role_uuid
leads = LeadModel.objects.filter(**base_filter).order_by('-created_at')
return leads
except Exception as exp:
@@ -25,7 +34,16 @@ def retrieve_lead(request, id: int) -> LeadModel:
try:
workspace_uuid = get_user_workspace_uuid(request)
cuser_role_uuid = get_cuser_role_uuid(request)
lead = LeadModel.objects.get(id=id, sys_ws__uuid=workspace_uuid, cuser_role__uuid=cuser_role_uuid)
cuser_role = get_cuser_role(request)
base_filter = {
'sys_ws__uuid': workspace_uuid,
}
if not cuser_role.is_admin:
base_filter['cuser_role__uuid'] = cuser_role_uuid
lead = LeadModel.objects.get(id=id, **base_filter)
return lead
except Exception as exp:
message = f'Error retrieve Leads: {exp}'
+5
View File
@@ -139,6 +139,11 @@ class LeadListApi(ListAPIView):
'ostan': inline_serializer(many=False, fields={'name': serializers.CharField() })
})
cuser_role = inline_serializer(many=False, fields={
'id': serializers.IntegerField(),
'name_family': serializers.CharField()
})
class Meta:
model = LeadModel
fields = '__all__'
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-10 09:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('reminder', '0029_alter_reminder_type'),
]
operations = [
migrations.AlterField(
model_name='reminder',
name='type',
field=models.CharField(choices=[('LE', 'LEAD'), ('NO', 'NOTE'), ('UN', 'UNKNOWN'), ('CU', 'CUSTOMER')], default='UN', max_length=2),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-10 11:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('reminder', '0030_alter_reminder_type'),
]
operations = [
migrations.AlterField(
model_name='reminder',
name='type',
field=models.CharField(choices=[('CU', 'CUSTOMER'), ('NO', 'NOTE'), ('LE', 'LEAD'), ('UN', 'UNKNOWN')], default='UN', max_length=2),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-18 09:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('reminder', '0031_alter_reminder_type'),
]
operations = [
migrations.AlterField(
model_name='reminder',
name='type',
field=models.CharField(choices=[('UN', 'UNKNOWN'), ('CU', 'CUSTOMER'), ('LE', 'LEAD'), ('NO', 'NOTE')], default='UN', max_length=2),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-27 09:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('reminder', '0032_alter_reminder_type'),
]
operations = [
migrations.AlterField(
model_name='reminder',
name='type',
field=models.CharField(choices=[('LE', 'LEAD'), ('UN', 'UNKNOWN'), ('CU', 'CUSTOMER'), ('NO', 'NOTE')], default='UN', max_length=2),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-04-16 06:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('reminder', '0033_alter_reminder_type'),
]
operations = [
migrations.AlterField(
model_name='reminder',
name='type',
field=models.CharField(choices=[('CU', 'CUSTOMER'), ('NO', 'NOTE'), ('UN', 'UNKNOWN'), ('LE', 'LEAD')], default='UN', max_length=2),
),
]
View File
Whitespace-only changes.
+41
View File
@@ -0,0 +1,41 @@
from apps.lead.models import Lead as LeadModel
from apps.cuser.models import CuserRole as CuserRoleModel, RoleType as RoleTypeModel
from rest_framework import serializers
from django.db.models import Count
from django.db.models import Count
from rest_framework import exceptions
def list_leads_api() -> LeadModel:
try:
base_filter = {
'sys_ws__uuid': 'ca918836-ddf2-4d88-8d76-033d285062e4',
}
leads = LeadModel.objects.filter(**base_filter).order_by('-created_at')
return leads
except Exception as exp:
message = f'Error Fetching List Leads: {exp}'
raise exceptions.ValidationError({'error': message})
def user_lead_report_count_by_date(start_datetime, end_datetime, status: str | None = None,):
base_filer = {
'cuser_role__role_type__role_name_en': 'workspace_operator',
'created_at__range': [start_datetime, end_datetime],
}
if status:
base_filer['status'] = status
return LeadModel.objects.filter(**base_filer).values('cuser_role__name_family').annotate(
count=Count('cuser_role__name_family')).order_by('-count')
def operators_cuser_role():
return CuserRoleModel.objects.filter(sys_ws_id=2, role_type__role_name_en='workspace_operator')
+1
View File
@@ -0,0 +1 @@
+8
View File
@@ -0,0 +1,8 @@
from django.urls import path
from apps.report.views import ReportApiView, LeadListApi
urlpatterns = [
path('lead/', ReportApiView.as_view(), name='report-lead'),
path('lead/list/loolegostar-x89i20/', LeadListApi.as_view(), name='report-lead'),
]
+115
View File
@@ -0,0 +1,115 @@
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import serializers
from rest_framework.generics import ListAPIView
from rest_framework.views import APIView
from apps.lead.models import Lead as LeadModel
from rest_framework.response import Response
from rest_framework import status
from apps.report.selector import user_lead_report_count_by_date
from apps.cuser.models import CuserRole as CuserRoleModel
from datetime import datetime
from apps.report.selector import list_leads_api
from utils.pagination import CustomPagination
from utils.tools import inline_serializer
class ReportApiView(APIView):
class ResultSerializer(serializers.Serializer):
class OperatorSerializer(serializers.Serializer):
cuser_role__name_family = serializers.CharField()
count = serializers.IntegerField()
su = OperatorSerializer(many=True)
un = OperatorSerializer(many=True)
fa = OperatorSerializer(many=True)
all = OperatorSerializer(many=True)
def get(self, request):
date_format = "%Y-%m-%d"
start_datetime = request.query_params.get('start_datetime', None)
if start_datetime:
start_datetime = start_datetime.replace(" ", "")
end_datetime = request.query_params.get('end_datetime', None)
if end_datetime:
end_datetime = end_datetime.replace(" ", "")
#example start_datetime : 2024-03-20T14:31:16 03:30
if start_datetime and end_datetime:
start_dt = datetime.strptime(start_datetime, date_format)
end_dt = datetime.strptime(end_datetime, date_format)
else:
start_dt = datetime.now()
end_dt = datetime.now()
# status = request.query_params.get('status')
#همه
users_all_lead_count = user_lead_report_count_by_date(start_datetime=start_dt, end_datetime=end_dt)
#موفق
users_su_lead_count = user_lead_report_count_by_date(status='SU', start_datetime=start_dt, end_datetime=end_dt)
#شکست
users_fa_lead_count = user_lead_report_count_by_date(status='FA', start_datetime=start_dt, end_datetime=end_dt)
#نا معلوم
users_un_lead_count = user_lead_report_count_by_date(status='UN', start_datetime=start_dt, end_datetime=end_dt)
result = {
'su': users_su_lead_count,
'fa': users_fa_lead_count,
'un': users_un_lead_count,
'all': users_all_lead_count,
}
output_serializer = self.ResultSerializer(result)
return Response(output_serializer.data)
class LeadListApi(ListAPIView):
#permission_classes = (IsAuthenticated, custom_permissions.WorkspaceOperatorPermission)
class Pagination(CustomPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 20
class OutputSerializer(serializers.ModelSerializer):
customer = inline_serializer(many=False, fields={'name_family': serializers.CharField(), })
product_type = inline_serializer(many=False, fields={'name': serializers.CharField(), })
type = inline_serializer(many=False, fields={'title': serializers.CharField(), })
source = inline_serializer(many=False, fields={'title': serializers.CharField(), })
step = inline_serializer(many=False, fields={
'id': serializers.IntegerField(),
'name': serializers.CharField(),
})
city = inline_serializer(many=False, fields={
'name': serializers.CharField(),
'ostan': inline_serializer(many=False, fields={'name': serializers.CharField() })
})
cuser_role = inline_serializer(many=False, fields={
'id': serializers.IntegerField(),
'name_family': serializers.CharField()
})
class Meta:
model = LeadModel
fields = '__all__'
serializer_class = OutputSerializer
pagination_class = Pagination
filter_backends = [DjangoFilterBackend]
filterset_fields = ['step', 'status', ]
def get_queryset(self):
return list_leads_api()
+1 -1
View File
@@ -22,7 +22,7 @@ class ProductCategoryAdmin(admin.ModelAdmin):
@admin.register(ProductModel)
class ProductAdmin(admin.ModelAdmin):
pass
search_fields = ("name", "category__name", "acc_code")
@admin.register(OrderModel)
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-27 09:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0019_alter_product_price'),
]
operations = [
migrations.AddField(
model_name='product',
name='view_only',
field=models.BooleanField(blank=True, default=False, null=True),
),
]
+1
View File
@@ -34,6 +34,7 @@ class Product(BaseModel):
acc_code = models.CharField(null=True, blank=True)
order_prd = models.PositiveIntegerField(null=True, blank=True, default=None)
attr = models.JSONField(null=True, blank=True)
view_only = models.BooleanField(null=True, blank=True, default=False)
sys_ws = models.ForeignKey(WorkspaceModel, on_delete=models.CASCADE, null=False, blank=False)
+23 -6
View File
@@ -55,11 +55,18 @@ def list_order_operators(request) -> OrderModel:
try:
workspace_uuid = get_user_workspace_uuid(request)
cuser_role_uuid = get_cuser_role_uuid(request)
cuser_role = get_cuser_role(request)
customer_responsibles = CustomerResponsibleModel.objects.filter(cuser_role__uuid=cuser_role_uuid, sys_ws__uuid=workspace_uuid)
responsible_group_ids = customer_responsibles.values_list('responsible_group__id', flat=True)
orders = OrderModel.objects.filter(sys_ws__uuid=workspace_uuid,
responsible_group_id__in=responsible_group_ids).order_by('-created_at')[:10]
base_filter = {
'sys_ws__uuid': workspace_uuid,
}
if not cuser_role.is_admin:
base_filter['responsible_group_id__in'] = responsible_group_ids
orders = OrderModel.objects.filter(**base_filter).order_by('-created_at')[:50]
return orders
except Exception as exp:
message = f'Error Fetching List Order: {exp}'
@@ -70,13 +77,23 @@ def retrieve_order_operators(request, order_id) -> OrderModel:
try:
workspace_uuid = get_user_workspace_uuid(request)
cuser_role_uuid = get_cuser_role_uuid(request)
cuser_role = get_cuser_role(request)
customer_responsibles = CustomerResponsibleModel.objects.filter(cuser_role__uuid=cuser_role_uuid, sys_ws__uuid=workspace_uuid)
responsible_group_ids = customer_responsibles.values_list('responsible_group__id', flat=True)
order = OrderModel.objects.get(id=order_id, sys_ws__uuid=workspace_uuid,
responsible_group_id__in=responsible_group_ids)
order.view_at = timezone.now()
order.save()
base_filter = {
'sys_ws__uuid': workspace_uuid,
'id': order_id,
}
if not cuser_role.is_admin:
base_filter['responsible_group_id__in'] = responsible_group_ids
order = OrderModel.objects.get(**base_filter)
if not cuser_role.is_admin:
order.view_at = timezone.now()
order.save()
return order
except Exception as exp:
+12 -1
View File
@@ -22,13 +22,24 @@ def list_product(workspace_uuid: str) -> ProductModel:
def list_product_by_category(workspace_uuid: str, category_id: int) -> ProductModel:
try:
product_category_obj = ProductModel.objects.filter(sys_ws__uuid=workspace_uuid, category_id=category_id)
product_category_obj = ProductModel.objects.filter(sys_ws__uuid=workspace_uuid, category_id=category_id,
view_only=False)
return product_category_obj
except Exception as exp:
message = f'Error Fetching List Product by category: {exp}'
raise exceptions.ValidationError({'error': message})
def list_view_only_product_by_category(workspace_uuid: str, category_id: int) -> ProductModel:
try:
view_only_product_category_obj = ProductModel.objects.filter(sys_ws__uuid=workspace_uuid, category_id=category_id,
view_only=True)
return view_only_product_category_obj
except Exception as exp:
message = f'Error Fetching View Only List Product by category: {exp}'
raise exceptions.ValidationError({'error': message})
def count_product_in_category(workspace_uuid: str, category_id: int) -> int:
try:
count_product = ProductModel.objects.filter(sys_ws__uuid=workspace_uuid, category_id=category_id).count()
+3 -1
View File
@@ -34,5 +34,7 @@ urlpatterns = [
path('cart/add/', CartCreateApi.as_view(), name='add_cart'),
path('cart/delete/<int:cart_id>/', CartDeleteApi.as_view(), name='delete_cart'),
#path('import/', ImportExcelView.as_view(), name='import_excel'),
path('import/', ImportExcelView.as_view(), name='import_excel'),
path('import/customer/', ImportExcelCustomersView.as_view(), name='import_excel_customer'),
#path('import/city/', ImportExcelCitysView.as_view(), name='import_excel_city'),
]
+1 -1
View File
@@ -16,4 +16,4 @@ from .cart import (CartListApi, CartCreateApi, CartDeleteApi)
from .order_item import (OrderItemsListApi, )
from .excel_import import ImportExcelView
from .excel_import import ImportExcelView, ImportExcelCitysView, ImportExcelCustomersView
+90 -15
View File
@@ -2,7 +2,9 @@ from rest_framework.views import APIView
from rest_framework.response import Response
import pandas as pd
from apps.shop.models import Product as ProductModel, ProductCategory as ProductCategoryModel
from apps.workspace.models import Workspace as WorkspaceModel
from apps.workspace.models import Workspace as WorkspaceModel, City as CityModel
from apps.customer.models import Customer as CustomerModel
from apps.customer.models import ResponsibleGroup as ResponsibleGroupModel
import os
@@ -13,27 +15,100 @@ class ImportExcelView(APIView):
df = pd.read_excel('pe.xlsx')
for index, row in df.iterrows():
cate_name = row['cate_name']
order_cat = row['order_cat']
#order_cat = row['order_cat']
acc_code = row['acc_code']
prd_name = row['prd_name']
order_prd = row['order_prd']
prd_name = row['name']
order_prd = row['size']
vahed = row['vahed']
workspace = WorkspaceModel.objects.get(id=2)
try:
prd_ct = ProductCategoryModel.objects.get(name=cate_name, sys_ws=workspace, order_cat=order_cat)
prd_ct = ProductCategoryModel.objects.get(name=cate_name, sys_ws=workspace)
except ProductCategoryModel.DoesNotExist as exp:
prd_ct = ProductCategoryModel.objects.create(name=cate_name, sys_ws=workspace, order_cat=order_cat)
prd_ct = ProductCategoryModel.objects.create(name=cate_name, sys_ws=workspace)
new_product = ProductModel()
new_product.name = prd_name
new_product.price = 0
new_product.category = ProductCategoryModel.objects.get(id=prd_ct.id)
new_product.acc_code = acc_code
new_product.order_prd = order_prd
new_product.attr = {"acc_vahed": vahed}
new_product.sys_ws = workspace
new_product.save()
if ProductModel.objects.filter(acc_code=acc_code).exists() == False:
new_product = ProductModel()
new_product.name = prd_name
new_product.price = 0
new_product.category = ProductCategoryModel.objects.get(id=prd_ct.id)
new_product.acc_code = acc_code
new_product.order_prd = order_prd
new_product.view_only = True
new_product.attr = {"acc_vahed": vahed}
new_product.sys_ws = workspace
new_product.save()
else:
up_product = ProductModel.objects.get(acc_code=acc_code)
up_product.name = prd_name
up_product.save()
return Response(data={"result": 'ok'})
class ImportExcelCitysView(APIView):
def get(self, request):
df = pd.read_excel('cities.xlsx')
for index, row in df.iterrows():
city_name = row['name']
pv_id = row['province_id']
try:
ostan = CityModel.objects.get(pv_id=pv_id, is_ostan=True)
except Exception as exp:
print(city_name)
print(pv_id)
city_obj = CityModel()
city_obj.name = city_name
city_obj.is_ostan = False
city_obj.ostan = ostan
city_obj.save()
return Response(data={"result": 'ok'})
class ImportExcelCustomersView(APIView):
def get(self, request):
df = pd.read_excel('customersData.xlsx')
for index, row in df.iterrows():
name = row['name']
mobile = row['mobile']
if name and mobile:
phone = row['phone']
address = row['address']
ostan = row['ostan']
shahr = row['shar']
mantaghe = row['id_mantaghe']
try:
ostan_obj = CityModel.objects.get(name=ostan, is_ostan=True)
shahr_obj = CityModel.objects.get(name=shahr, ostan=ostan_obj)
except Exception as exp:
shahr_obj = CityModel.objects.get(id=1229)
try:
cs = CustomerModel()
cs.name_family = name
cs.mobile = mobile
if phone:
cs.phone = phone
cs.city = shahr_obj
if address:
cs.address = address
cs.responsible_group = ResponsibleGroupModel.objects.get(id=mantaghe)
cs.sys_ws = WorkspaceModel.objects.get(id=2)
cs.save()
except Exception as exp:
print(name)
return Response(data={"result": 'ok'})
+5 -2
View File
@@ -124,7 +124,7 @@ class OrderUpdateApi(APIView):
class OrderDeleteApi(APIView):
permission_classes = (IsAuthenticated,)
def delete(self, request, order_id: int):
user_workspace_uuid = get_user_workspace_uuid(request=request)
@@ -139,7 +139,7 @@ class OrderDeleteApi(APIView):
class OrderListApi(generics.ListAPIView):
permission_classes = (IsAuthenticated,)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = OrderModel
@@ -155,6 +155,7 @@ class OrderListApi(generics.ListAPIView):
class OrderListOperatorApi(generics.ListAPIView):
permission_classes = (IsAuthenticated,)
class OutputSerializer(serializers.ModelSerializer):
customer = inline_serializer(fields={
'id': serializers.IntegerField(),
@@ -172,6 +173,7 @@ class OrderListOperatorApi(generics.ListAPIView):
class OrderRetrieveOperatorApi(APIView):
permission_classes = (IsAuthenticated,)
class OutputSerializer(serializers.ModelSerializer):
customer = inline_serializer(fields={
@@ -210,6 +212,7 @@ class OrderRetrieveOperatorApi(APIView):
class OrderRetrieveOperatorExcelApi(APIView):
permission_classes = (IsAuthenticated, )
def get(self, request, order_id):
order_df = retrieve_order_item_excel(request=request, order_id=order_id)
+9 -1
View File
@@ -134,6 +134,7 @@ class ProductListCategoryApi(generics.ListAPIView):
id = serializers.IntegerField()
name = serializers.CharField()
price = serializers.FloatField()
view_only = serializers.BooleanField()
class Meta:
exclude = ('sys_ws', )
@@ -144,6 +145,8 @@ class ProductListCategoryApi(generics.ListAPIView):
serializer = self.get_serializer(queryset_data, many=True)
workspace_uuid = get_user_workspace_uuid(request=request)
category = retrieve_product_category(category_id=category_id, workspace_uuid=workspace_uuid)
view_only_products = list_view_only_product_by_category(category_id=category_id, workspace_uuid=workspace_uuid)
view_only_products_serializer = self.get_serializer(view_only_products, many=True)
if len(serializer.data) == 0:
return Response(
@@ -152,9 +155,14 @@ class ProductListCategoryApi(generics.ListAPIView):
data = {
"category_name": category.name,
"category_img": category.image.url,
"products": serializer.data
"products": serializer.data,
}
if len(view_only_products_serializer.data) >=1:
data['view_only_products'] = view_only_products_serializer.data
else:
data['view_only_products'] = None
return Response(data)
def get_queryset(self):
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-10 09:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('workspace', '0013_alter_workspace_cuser_owner'),
]
operations = [
migrations.AddField(
model_name='city',
name='pv_id',
field=models.PositiveSmallIntegerField(blank=True, null=True),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-02-10 11:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('workspace', '0014_city_pv_id'),
]
operations = [
migrations.AlterField(
model_name='city',
name='name',
field=models.CharField(blank=True, max_length=30, null=True),
),
]
@@ -0,0 +1,17 @@
# Generated by Django 4.2.1 on 2024-02-18 09:44
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('workspace', '0015_alter_city_name'),
]
operations = [
migrations.RemoveField(
model_name='workspace',
name='cuser_owner',
),
]
+3 -2
View File
@@ -11,7 +11,7 @@ class Workspace(BaseModel):
#cuser_role_owner = models.OneToOneField(CuserRoleModel, on_delete=models.CASCADE,
# related_name='workspace', null=True, blank=True)
cuser_owner = models.ForeignKey(CUser, on_delete=models.SET_NULL, null=True, blank=True, default=None)
#cuser_owner = models.ForeignKey(CUser, on_delete=models.SET_NULL, null=True, blank=True, default=None)
name = models.CharField(max_length=15, null=False, blank=False)
username = models.CharField(max_length=30, null=False, blank=False, unique=True)
expire = models.DateTimeField(null=True, blank=True)
@@ -27,9 +27,10 @@ class Workspace(BaseModel):
class City(BaseModel):
name = models.CharField(max_length=15, null=True, blank=True)
name = models.CharField(max_length=30, null=True, blank=True)
is_ostan = models.BooleanField(default=False, null=False, blank=False)
ostan = models.ForeignKey('self', models.CASCADE, null=True, blank=True)
pv_id = models.PositiveSmallIntegerField(null=True, blank=True)
def __str__(self):
return str(self.name)
+1 -1
View File
@@ -11,6 +11,6 @@ import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'crmApi.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
application = get_asgi_application()
+14 -2
View File
@@ -19,8 +19,6 @@ BASE_DIR = Path(__file__).resolve().parent.parent
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR.parent /'media'
print(MEDIA_ROOT)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
@@ -33,8 +31,22 @@ DEBUG = True
ALLOWED_HOSTS = ['*']
CORS_ALLOWED_ORIGINS = [
"http://192.168.138.94:3000",
"http://192.168.138.94:3001",
"http://localhost:3001",
"http://localhost:3002",
"http://localhost:3000",
"https://loolegostar.liara.run",
"https://loolegostar-crm.liara.run",
]
CORS_ALLOW_METHODS = [
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
"PUT",
]
AUTH_USER_MODEL = 'cuser.CUser'
+11
View File
@@ -1 +1,12 @@
from .base import *
DEBUG = False
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'crm-api',
'USER': 'root',
'PASSWORD': '1yI0Iw2Fpjm2BXhEnwUKVdDg',
'HOST': 'loolegostar-db',
'PORT': '5432'
}
}
+1
View File
@@ -23,6 +23,7 @@ urlpatterns = [
path('admin/', admin.site.urls),
path('auth/', include('apps.jwt_auth.urls')),
path('cuser/', include('apps.cuser.urls')),
path('report/', include('apps.report.urls')),
path('customer/', include('apps.customer.urls')),
path('shop/', include('apps.shop.urls')),
path('ticket/', include('apps.ticket.urls')),
+1 -1
View File
@@ -11,6 +11,6 @@ import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'crmApi.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
application = get_wsgi_application()
+10
View File
@@ -0,0 +1,10 @@
{
"platform": "django",
"app": "loolegostar-api",
"disks": [
{
"name": "media",
"mountTo": "media"
}
]
}
+29
View File
@@ -0,0 +1,29 @@
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
client_max_body_size 250M;
location /media {
alias /usr/src/app/media;
}
location /static {
alias /usr/src/app/config/staticfiles;
}
location / {
try_files /dev/null @django_app;
}
location ~\.sqlite3$ {
deny all;
error_page 403 =404 /;
}
location ~ /\.well-known {
allow all;
}
+14
View File
@@ -0,0 +1,14 @@
Django==4.2.1
djangorestframework==3.14.0
Markdown==3.4.3
requests==2.31.0
django-filter==23.2
drf-spectacular==0.26.2
psycopg==3.1.9
psycopg-binary==3.1.9
djangorestframework-simplejwt==5.2.2
django-cors-headers==4.3.1
openpyxl==3.1.2
XlsxWriter==3.1.9
pandas==2.2.0
pillow==10.2.0
+2
View File
@@ -1,9 +1,11 @@
Django==4.2.1
djangorestframework==3.14.0
Markdown==3.4.3
requests==2.31.0
django-filter==23.2
drf-spectacular==0.26.2
psycopg==3.1.9
psycopg-binary==3.1.9
djangorestframework-simplejwt==5.2.2
django-cors-headers==4.3.1
openpyxl==3.1.2