before change Ticket Desc to TextArea
This commit is contained in:
1 parent
f7dbd02a6c
commit
ef18434b86
55 files changed
+1026
-59
No files matched your search
@@ -7,6 +7,8 @@ __pycache__/
|
|||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
|
*.xlsx
|
||||||
|
|
||||||
# Distribution / packaging
|
# Distribution / packaging
|
||||||
.Python
|
.Python
|
||||||
build/
|
build/
|
||||||
|
|||||||
Generated
+10
@@ -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
@@ -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>
|
||||||
Generated
+5
-2
@@ -13,8 +13,11 @@
|
|||||||
</facet>
|
</facet>
|
||||||
</component>
|
</component>
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$">
|
||||||
<orderEntry type="inheritedJdk" />
|
<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" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PyDocumentationSettings">
|
<component name="PyDocumentationSettings">
|
||||||
|
|||||||
Generated
+4
-1
@@ -1,4 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<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>
|
</project>
|
||||||
Generated
+174
-14
@@ -1,16 +1,36 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="AutoImportSettings">
|
||||||
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="87c5db51-3e89-4a98-9bbb-121c9c52ab3c" name="Changes" comment="">
|
<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$/.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/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/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/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/__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/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.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" />
|
<change beforePath="$PROJECT_DIR$/requirements/base.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements/base.txt" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
@@ -34,23 +54,35 @@
|
|||||||
<component name="MarkdownSettingsMigration">
|
<component name="MarkdownSettingsMigration">
|
||||||
<option name="stateVersion" value="1" />
|
<option name="stateVersion" value="1" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="ProjectColorInfo">{
|
||||||
|
"associatedIndex": 3
|
||||||
|
}</component>
|
||||||
<component name="ProjectId" id="2SvKNIPBcTXVjDKPSdS8NHW9I0w" />
|
<component name="ProjectId" id="2SvKNIPBcTXVjDKPSdS8NHW9I0w" />
|
||||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
|
||||||
<component name="ProjectViewState">
|
<component name="ProjectViewState">
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
"Django Server.crmApi.executor": "Run",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.OpenDjangoStructureViewOnStart": "true",
|
||||||
"WebServerToolWindowFactoryState": "false",
|
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||||
"last_opened_file_path": "E:/Projects/crmProject/Project/api-Project/crmApi",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"node.js.detected.package.eslint": "true",
|
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"WebServerToolWindowFactoryState": "false",
|
||||||
"settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable"
|
"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">
|
<component name="RecentsManager">
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
<recent name="E:\Projects\crmProject\Project\api-Project\crmApi\utils" />
|
<recent name="E:\Projects\crmProject\Project\api-Project\crmApi\utils" />
|
||||||
@@ -60,13 +92,14 @@
|
|||||||
<component name="RunManager">
|
<component name="RunManager">
|
||||||
<configuration name="crmApi" type="Python.DjangoServer" factoryName="Django server">
|
<configuration name="crmApi" type="Python.DjangoServer" factoryName="Django server">
|
||||||
<module name="crmApi" />
|
<module name="crmApi" />
|
||||||
|
<option name="ENV_FILES" value="" />
|
||||||
<option name="INTERPRETER_OPTIONS" value="" />
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
<option name="PARENT_ENVS" value="true" />
|
<option name="PARENT_ENVS" value="true" />
|
||||||
<envs>
|
<envs>
|
||||||
<env name="PYTHONUNBUFFERED" value="1" />
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
</envs>
|
</envs>
|
||||||
<option name="SDK_HOME" value="" />
|
<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="IS_MODULE_SDK" value="true" />
|
||||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
@@ -82,6 +115,14 @@
|
|||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</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="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||||
<component name="TaskManager">
|
<component name="TaskManager">
|
||||||
<task active="true" id="Default" summary="Default task">
|
<task active="true" id="Default" summary="Default task">
|
||||||
@@ -100,7 +141,38 @@
|
|||||||
<workItem from="1702900258020" duration="63755000" />
|
<workItem from="1702900258020" duration="63755000" />
|
||||||
<workItem from="1704088148329" duration="105568000" />
|
<workItem from="1704088148329" duration="105568000" />
|
||||||
<workItem from="1704951046597" duration="135372000" />
|
<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>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
@@ -118,4 +190,92 @@
|
|||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</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>
|
</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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -26,6 +26,7 @@ class CuserRole(BaseModel):
|
|||||||
mobile = models.PositiveBigIntegerField(null=False, blank=False)
|
mobile = models.PositiveBigIntegerField(null=False, blank=False)
|
||||||
mobile_verify = models.BooleanField(default=False)
|
mobile_verify = models.BooleanField(default=False)
|
||||||
customer_panel = models.BooleanField(default=None, blank=True, null=True)
|
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)
|
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)
|
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ def customer_form_item(request):
|
|||||||
'shahr': shahr,
|
'shahr': shahr,
|
||||||
'responsible_groups': responsible_groups
|
'responsible_groups': responsible_groups
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -5,14 +5,16 @@ from apps.jwt_auth.models import CUserRoleLoginOpt
|
|||||||
from apps.cuser.models import CuserRole as CuserRoleModel, SmsOpt as SmsOptModel
|
from apps.cuser.models import CuserRole as CuserRoleModel, SmsOpt as SmsOptModel
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from rest_framework import exceptions
|
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:
|
def login_by_username(username: str, password: str) -> CUserRoleLoginOpt:
|
||||||
try:
|
try:
|
||||||
print(username)
|
print(username)
|
||||||
user = CUser.objects.get(username=username)
|
user = CUser.objects.get(username=username)
|
||||||
print(user)
|
|
||||||
if user and user.check_password(password):
|
if user and user.check_password(password):
|
||||||
|
|
||||||
cuser_roles = CuserRoleModel.objects.filter(cuser=user)
|
cuser_roles = CuserRoleModel.objects.filter(cuser=user)
|
||||||
@@ -52,21 +54,35 @@ def login_by_mobile(mobile: int):
|
|||||||
|
|
||||||
random_number = random.randint(100000, 999999)
|
random_number = random.randint(100000, 999999)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
SmsOptModel.objects.filter(mobile=mobile).delete()
|
SmsOptModel.objects.filter(mobile=mobile).delete()
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
pass
|
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()
|
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:
|
except Exception as exp:
|
||||||
raise exceptions.ValidationError({'error': "mobile not found"})
|
raise exceptions.ValidationError({'error': "mobile not found"})
|
||||||
|
|
||||||
|
|
||||||
def verify_mobile_and_get_token(mobile: int, opt: int) -> CUserRoleLoginOpt:
|
def verify_mobile_and_get_token(mobile: int, opt: int) -> CUserRoleLoginOpt:
|
||||||
try:
|
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:
|
if opt_obj:
|
||||||
cuser_roles = CuserRoleModel.objects.filter(cuser__mobile=mobile, is_active=True)
|
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()
|
SmsOptModel.objects.filter(mobile=mobile).delete()
|
||||||
return login_opts
|
return login_opts
|
||||||
except Exception as exp:
|
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)})
|
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
@@ -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.shop.models import ProductType as ProductTypeModel
|
||||||
from apps.workspace.models import City as CityModel
|
from apps.workspace.models import City as CityModel
|
||||||
from utils.get_user_workspace import get_user_workspace_uuid
|
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
|
from rest_framework import exceptions
|
||||||
|
|
||||||
|
|
||||||
@@ -12,7 +12,16 @@ def list_leads(request) -> LeadModel:
|
|||||||
try:
|
try:
|
||||||
workspace_uuid = get_user_workspace_uuid(request)
|
workspace_uuid = get_user_workspace_uuid(request)
|
||||||
cuser_role_uuid = get_cuser_role_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
|
return leads
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
@@ -25,7 +34,16 @@ def retrieve_lead(request, id: int) -> LeadModel:
|
|||||||
try:
|
try:
|
||||||
workspace_uuid = get_user_workspace_uuid(request)
|
workspace_uuid = get_user_workspace_uuid(request)
|
||||||
cuser_role_uuid = get_cuser_role_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
|
return lead
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
message = f'Error retrieve Leads: {exp}'
|
message = f'Error retrieve Leads: {exp}'
|
||||||
|
|||||||
@@ -139,6 +139,11 @@ class LeadListApi(ListAPIView):
|
|||||||
'ostan': 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:
|
class Meta:
|
||||||
model = LeadModel
|
model = LeadModel
|
||||||
fields = '__all__'
|
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),
|
||||||
|
),
|
||||||
|
]
|
||||||
Whitespace-only changes.
@@ -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')
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -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'),
|
||||||
|
]
|
||||||
@@ -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
@@ -22,7 +22,7 @@ class ProductCategoryAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
@admin.register(ProductModel)
|
@admin.register(ProductModel)
|
||||||
class ProductAdmin(admin.ModelAdmin):
|
class ProductAdmin(admin.ModelAdmin):
|
||||||
pass
|
search_fields = ("name", "category__name", "acc_code")
|
||||||
|
|
||||||
|
|
||||||
@admin.register(OrderModel)
|
@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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -34,6 +34,7 @@ class Product(BaseModel):
|
|||||||
acc_code = models.CharField(null=True, blank=True)
|
acc_code = models.CharField(null=True, blank=True)
|
||||||
order_prd = models.PositiveIntegerField(null=True, blank=True, default=None)
|
order_prd = models.PositiveIntegerField(null=True, blank=True, default=None)
|
||||||
attr = models.JSONField(null=True, blank=True)
|
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)
|
sys_ws = models.ForeignKey(WorkspaceModel, on_delete=models.CASCADE, null=False, blank=False)
|
||||||
|
|
||||||
|
|||||||
@@ -55,11 +55,18 @@ def list_order_operators(request) -> OrderModel:
|
|||||||
try:
|
try:
|
||||||
workspace_uuid = get_user_workspace_uuid(request)
|
workspace_uuid = get_user_workspace_uuid(request)
|
||||||
cuser_role_uuid = get_cuser_role_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)
|
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)
|
responsible_group_ids = customer_responsibles.values_list('responsible_group__id', flat=True)
|
||||||
|
|
||||||
orders = OrderModel.objects.filter(sys_ws__uuid=workspace_uuid,
|
base_filter = {
|
||||||
responsible_group_id__in=responsible_group_ids).order_by('-created_at')[:10]
|
'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
|
return orders
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
message = f'Error Fetching List Order: {exp}'
|
message = f'Error Fetching List Order: {exp}'
|
||||||
@@ -70,13 +77,23 @@ def retrieve_order_operators(request, order_id) -> OrderModel:
|
|||||||
try:
|
try:
|
||||||
workspace_uuid = get_user_workspace_uuid(request)
|
workspace_uuid = get_user_workspace_uuid(request)
|
||||||
cuser_role_uuid = get_cuser_role_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)
|
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)
|
responsible_group_ids = customer_responsibles.values_list('responsible_group__id', flat=True)
|
||||||
|
|
||||||
order = OrderModel.objects.get(id=order_id, sys_ws__uuid=workspace_uuid,
|
base_filter = {
|
||||||
responsible_group_id__in=responsible_group_ids)
|
'sys_ws__uuid': workspace_uuid,
|
||||||
order.view_at = timezone.now()
|
'id': order_id,
|
||||||
order.save()
|
}
|
||||||
|
|
||||||
|
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
|
return order
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
|
|||||||
@@ -22,13 +22,24 @@ def list_product(workspace_uuid: str) -> ProductModel:
|
|||||||
|
|
||||||
def list_product_by_category(workspace_uuid: str, category_id: int) -> ProductModel:
|
def list_product_by_category(workspace_uuid: str, category_id: int) -> ProductModel:
|
||||||
try:
|
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
|
return product_category_obj
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
message = f'Error Fetching List Product by category: {exp}'
|
message = f'Error Fetching List Product by category: {exp}'
|
||||||
raise exceptions.ValidationError({'error': message})
|
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:
|
def count_product_in_category(workspace_uuid: str, category_id: int) -> int:
|
||||||
try:
|
try:
|
||||||
count_product = ProductModel.objects.filter(sys_ws__uuid=workspace_uuid, category_id=category_id).count()
|
count_product = ProductModel.objects.filter(sys_ws__uuid=workspace_uuid, category_id=category_id).count()
|
||||||
|
|||||||
+3
-1
@@ -34,5 +34,7 @@ urlpatterns = [
|
|||||||
path('cart/add/', CartCreateApi.as_view(), name='add_cart'),
|
path('cart/add/', CartCreateApi.as_view(), name='add_cart'),
|
||||||
path('cart/delete/<int:cart_id>/', CartDeleteApi.as_view(), name='delete_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'),
|
||||||
]
|
]
|
||||||
@@ -16,4 +16,4 @@ from .cart import (CartListApi, CartCreateApi, CartDeleteApi)
|
|||||||
|
|
||||||
from .order_item import (OrderItemsListApi, )
|
from .order_item import (OrderItemsListApi, )
|
||||||
|
|
||||||
from .excel_import import ImportExcelView
|
from .excel_import import ImportExcelView, ImportExcelCitysView, ImportExcelCustomersView
|
||||||
@@ -2,7 +2,9 @@ from rest_framework.views import APIView
|
|||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from apps.shop.models import Product as ProductModel, ProductCategory as ProductCategoryModel
|
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
|
import os
|
||||||
|
|
||||||
|
|
||||||
@@ -13,27 +15,100 @@ class ImportExcelView(APIView):
|
|||||||
df = pd.read_excel('pe.xlsx')
|
df = pd.read_excel('pe.xlsx')
|
||||||
for index, row in df.iterrows():
|
for index, row in df.iterrows():
|
||||||
cate_name = row['cate_name']
|
cate_name = row['cate_name']
|
||||||
order_cat = row['order_cat']
|
#order_cat = row['order_cat']
|
||||||
acc_code = row['acc_code']
|
acc_code = row['acc_code']
|
||||||
prd_name = row['prd_name']
|
prd_name = row['name']
|
||||||
order_prd = row['order_prd']
|
order_prd = row['size']
|
||||||
vahed = row['vahed']
|
vahed = row['vahed']
|
||||||
|
|
||||||
workspace = WorkspaceModel.objects.get(id=2)
|
workspace = WorkspaceModel.objects.get(id=2)
|
||||||
try:
|
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:
|
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()
|
if ProductModel.objects.filter(acc_code=acc_code).exists() == False:
|
||||||
new_product.name = prd_name
|
new_product = ProductModel()
|
||||||
new_product.price = 0
|
new_product.name = prd_name
|
||||||
new_product.category = ProductCategoryModel.objects.get(id=prd_ct.id)
|
new_product.price = 0
|
||||||
new_product.acc_code = acc_code
|
new_product.category = ProductCategoryModel.objects.get(id=prd_ct.id)
|
||||||
new_product.order_prd = order_prd
|
new_product.acc_code = acc_code
|
||||||
new_product.attr = {"acc_vahed": vahed}
|
new_product.order_prd = order_prd
|
||||||
new_product.sys_ws = workspace
|
new_product.view_only = True
|
||||||
new_product.save()
|
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'})
|
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'})
|
||||||
@@ -124,7 +124,7 @@ class OrderUpdateApi(APIView):
|
|||||||
|
|
||||||
|
|
||||||
class OrderDeleteApi(APIView):
|
class OrderDeleteApi(APIView):
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
def delete(self, request, order_id: int):
|
def delete(self, request, order_id: int):
|
||||||
|
|
||||||
user_workspace_uuid = get_user_workspace_uuid(request=request)
|
user_workspace_uuid = get_user_workspace_uuid(request=request)
|
||||||
@@ -139,7 +139,7 @@ class OrderDeleteApi(APIView):
|
|||||||
|
|
||||||
|
|
||||||
class OrderListApi(generics.ListAPIView):
|
class OrderListApi(generics.ListAPIView):
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
class OutputSerializer(serializers.ModelSerializer):
|
class OutputSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OrderModel
|
model = OrderModel
|
||||||
@@ -155,6 +155,7 @@ class OrderListApi(generics.ListAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class OrderListOperatorApi(generics.ListAPIView):
|
class OrderListOperatorApi(generics.ListAPIView):
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
class OutputSerializer(serializers.ModelSerializer):
|
class OutputSerializer(serializers.ModelSerializer):
|
||||||
customer = inline_serializer(fields={
|
customer = inline_serializer(fields={
|
||||||
'id': serializers.IntegerField(),
|
'id': serializers.IntegerField(),
|
||||||
@@ -172,6 +173,7 @@ class OrderListOperatorApi(generics.ListAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class OrderRetrieveOperatorApi(APIView):
|
class OrderRetrieveOperatorApi(APIView):
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
class OutputSerializer(serializers.ModelSerializer):
|
class OutputSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
customer = inline_serializer(fields={
|
customer = inline_serializer(fields={
|
||||||
@@ -210,6 +212,7 @@ class OrderRetrieveOperatorApi(APIView):
|
|||||||
|
|
||||||
|
|
||||||
class OrderRetrieveOperatorExcelApi(APIView):
|
class OrderRetrieveOperatorExcelApi(APIView):
|
||||||
|
permission_classes = (IsAuthenticated, )
|
||||||
def get(self, request, order_id):
|
def get(self, request, order_id):
|
||||||
|
|
||||||
order_df = retrieve_order_item_excel(request=request, order_id=order_id)
|
order_df = retrieve_order_item_excel(request=request, order_id=order_id)
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ class ProductListCategoryApi(generics.ListAPIView):
|
|||||||
id = serializers.IntegerField()
|
id = serializers.IntegerField()
|
||||||
name = serializers.CharField()
|
name = serializers.CharField()
|
||||||
price = serializers.FloatField()
|
price = serializers.FloatField()
|
||||||
|
view_only = serializers.BooleanField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
exclude = ('sys_ws', )
|
exclude = ('sys_ws', )
|
||||||
@@ -144,6 +145,8 @@ class ProductListCategoryApi(generics.ListAPIView):
|
|||||||
serializer = self.get_serializer(queryset_data, many=True)
|
serializer = self.get_serializer(queryset_data, many=True)
|
||||||
workspace_uuid = get_user_workspace_uuid(request=request)
|
workspace_uuid = get_user_workspace_uuid(request=request)
|
||||||
category = retrieve_product_category(category_id=category_id, workspace_uuid=workspace_uuid)
|
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:
|
if len(serializer.data) == 0:
|
||||||
return Response(
|
return Response(
|
||||||
@@ -152,9 +155,14 @@ class ProductListCategoryApi(generics.ListAPIView):
|
|||||||
data = {
|
data = {
|
||||||
"category_name": category.name,
|
"category_name": category.name,
|
||||||
"category_img": category.image.url,
|
"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)
|
return Response(data)
|
||||||
|
|
||||||
def get_queryset(self):
|
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',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -11,7 +11,7 @@ class Workspace(BaseModel):
|
|||||||
#cuser_role_owner = models.OneToOneField(CuserRoleModel, on_delete=models.CASCADE,
|
#cuser_role_owner = models.OneToOneField(CuserRoleModel, on_delete=models.CASCADE,
|
||||||
# related_name='workspace', null=True, blank=True)
|
# 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)
|
name = models.CharField(max_length=15, null=False, blank=False)
|
||||||
username = models.CharField(max_length=30, null=False, blank=False, unique=True)
|
username = models.CharField(max_length=30, null=False, blank=False, unique=True)
|
||||||
expire = models.DateTimeField(null=True, blank=True)
|
expire = models.DateTimeField(null=True, blank=True)
|
||||||
@@ -27,9 +27,10 @@ class Workspace(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class City(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)
|
is_ostan = models.BooleanField(default=False, null=False, blank=False)
|
||||||
ostan = models.ForeignKey('self', models.CASCADE, null=True, blank=True)
|
ostan = models.ForeignKey('self', models.CASCADE, null=True, blank=True)
|
||||||
|
pv_id = models.PositiveSmallIntegerField(null=True, blank=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.name)
|
return str(self.name)
|
||||||
|
|||||||
+1
-1
@@ -11,6 +11,6 @@ import os
|
|||||||
|
|
||||||
from django.core.asgi import get_asgi_application
|
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()
|
application = get_asgi_application()
|
||||||
+14
-2
@@ -19,8 +19,6 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||||||
MEDIA_URL = '/media/'
|
MEDIA_URL = '/media/'
|
||||||
MEDIA_ROOT = BASE_DIR.parent /'media'
|
MEDIA_ROOT = BASE_DIR.parent /'media'
|
||||||
|
|
||||||
print(MEDIA_ROOT)
|
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
|
||||||
|
|
||||||
@@ -33,8 +31,22 @@ DEBUG = True
|
|||||||
ALLOWED_HOSTS = ['*']
|
ALLOWED_HOSTS = ['*']
|
||||||
|
|
||||||
CORS_ALLOWED_ORIGINS = [
|
CORS_ALLOWED_ORIGINS = [
|
||||||
|
"http://192.168.138.94:3000",
|
||||||
|
"http://192.168.138.94:3001",
|
||||||
"http://localhost:3001",
|
"http://localhost:3001",
|
||||||
|
"http://localhost:3002",
|
||||||
"http://localhost:3000",
|
"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'
|
AUTH_USER_MODEL = 'cuser.CUser'
|
||||||
|
|||||||
@@ -1 +1,12 @@
|
|||||||
from .base import *
|
from .base import *
|
||||||
|
DEBUG = False
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.postgresql',
|
||||||
|
'NAME': 'crm-api',
|
||||||
|
'USER': 'root',
|
||||||
|
'PASSWORD': '1yI0Iw2Fpjm2BXhEnwUKVdDg',
|
||||||
|
'HOST': 'loolegostar-db',
|
||||||
|
'PORT': '5432'
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ urlpatterns = [
|
|||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('auth/', include('apps.jwt_auth.urls')),
|
path('auth/', include('apps.jwt_auth.urls')),
|
||||||
path('cuser/', include('apps.cuser.urls')),
|
path('cuser/', include('apps.cuser.urls')),
|
||||||
|
path('report/', include('apps.report.urls')),
|
||||||
path('customer/', include('apps.customer.urls')),
|
path('customer/', include('apps.customer.urls')),
|
||||||
path('shop/', include('apps.shop.urls')),
|
path('shop/', include('apps.shop.urls')),
|
||||||
path('ticket/', include('apps.ticket.urls')),
|
path('ticket/', include('apps.ticket.urls')),
|
||||||
|
|||||||
+1
-1
@@ -11,6 +11,6 @@ import os
|
|||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
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()
|
application = get_wsgi_application()
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"platform": "django",
|
||||||
|
"app": "loolegostar-api",
|
||||||
|
"disks": [
|
||||||
|
{
|
||||||
|
"name": "media",
|
||||||
|
"mountTo": "media"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
Django==4.2.1
|
Django==4.2.1
|
||||||
djangorestframework==3.14.0
|
djangorestframework==3.14.0
|
||||||
Markdown==3.4.3
|
Markdown==3.4.3
|
||||||
|
requests==2.31.0
|
||||||
django-filter==23.2
|
django-filter==23.2
|
||||||
drf-spectacular==0.26.2
|
drf-spectacular==0.26.2
|
||||||
psycopg==3.1.9
|
psycopg==3.1.9
|
||||||
|
psycopg-binary==3.1.9
|
||||||
djangorestframework-simplejwt==5.2.2
|
djangorestframework-simplejwt==5.2.2
|
||||||
django-cors-headers==4.3.1
|
django-cors-headers==4.3.1
|
||||||
openpyxl==3.1.2
|
openpyxl==3.1.2
|
||||||
|
|||||||
Reference in new issue
Block a user