This commit is contained in:
javad committed 2024-01-22 13:01:42 +03:30
commit 89a5d70512
284 files changed
+8364

No files matched your search

View File
Whitespace-only changes.
+40
View File
@@ -0,0 +1,40 @@
from django.contrib import admin
from apps.shop.models import (
ProductCategory as ProductCategoryModel,
Product as ProductModel,
Order as OrderModel,
OrderItem as OrderItemModel,
Cart as CartModel,
ProductType as ProductTypeModel
)
# Register your models here.
@admin.register(ProductTypeModel)
class ProductTypeAdmin(admin.ModelAdmin):
pass
@admin.register(ProductCategoryModel)
class ProductCategoryAdmin(admin.ModelAdmin):
pass
@admin.register(ProductModel)
class ProductAdmin(admin.ModelAdmin):
pass
@admin.register(OrderModel)
class OrderAdmin(admin.ModelAdmin):
pass
@admin.register(OrderItemModel)
class OrderItemAdmin(admin.ModelAdmin):
pass
@admin.register(CartModel)
class CartAdmin(admin.ModelAdmin):
pass
+6
View File
@@ -0,0 +1,6 @@
from django.apps import AppConfig
class ShopConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.shop'
+30
View File
@@ -0,0 +1,30 @@
# Generated by Django 4.2.1 on 2023-08-07 12:00
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('workspace', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='ProductCategory',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=30)),
('parent', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='shop.productcategory')),
('sys_ws', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='workspace.workspace')),
],
options={
'abstract': False,
},
),
]
@@ -0,0 +1,19 @@
# Generated by Django 4.2.1 on 2023-08-07 12:03
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('shop', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='productcategory',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='shop.productcategory'),
),
]
@@ -0,0 +1,64 @@
# Generated by Django 4.2.1 on 2023-08-08 08:37
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('customer', '0001_initial'),
('workspace', '0002_city'),
('shop', '0002_alter_productcategory_parent'),
]
operations = [
migrations.CreateModel(
name='Order',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('total_amount', models.DecimalField(decimal_places=2, max_digits=12)),
('factor_type', models.PositiveSmallIntegerField(choices=[(1, 'pish_factor'), (2, 'factor')])),
('factor_status', models.PositiveSmallIntegerField(blank=True, choices=[(1, 'unknown'), (2, 'ok'), (3, 'cancel')], null=True)),
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='customer.customer')),
('responsible_group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='customer.responsiblegroup')),
('sys_ws', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='workspace.workspace')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Product',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=150)),
('price', models.DecimalField(decimal_places=2, max_digits=12)),
('acc_code', models.PositiveBigIntegerField(blank=True, null=True)),
('attr', models.JSONField(blank=True, null=True)),
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.productcategory')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='OrderItem',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('price', models.DecimalField(decimal_places=2, max_digits=12)),
('amount', models.PositiveIntegerField()),
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.order')),
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.product')),
],
options={
'abstract': False,
},
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2023-08-13 05:45
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0003_order_product_orderitem'),
]
operations = [
migrations.AlterField(
model_name='product',
name='acc_code',
field=models.CharField(blank=True, null=True),
),
]
@@ -0,0 +1,20 @@
# Generated by Django 4.2.1 on 2023-08-13 05:52
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('workspace', '0002_city'),
('shop', '0004_alter_product_acc_code'),
]
operations = [
migrations.AddField(
model_name='product',
name='sys_ws',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='workspace.workspace'),
),
]
@@ -0,0 +1,20 @@
# Generated by Django 4.2.1 on 2023-08-13 05:55
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('workspace', '0002_city'),
('shop', '0005_product_sys_ws'),
]
operations = [
migrations.AlterField(
model_name='product',
name='sys_ws',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='workspace.workspace'),
),
]
@@ -0,0 +1,23 @@
# Generated by Django 4.2.1 on 2023-08-14 05:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0006_alter_product_sys_ws'),
]
operations = [
migrations.RenameField(
model_name='order',
old_name='total_amount',
new_name='total_price',
),
migrations.AddField(
model_name='orderitem',
name='product_name',
field=models.CharField(blank=True, max_length=150, null=True),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2023-08-14 05:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0007_rename_total_amount_order_total_price_and_more'),
]
operations = [
migrations.AlterField(
model_name='orderitem',
name='product_name',
field=models.CharField(max_length=150),
),
]
+29
View File
@@ -0,0 +1,29 @@
# Generated by Django 4.2.1 on 2023-10-22 06:55
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cuser', '0005_smsopt'),
('shop', '0008_alter_orderitem_product_name'),
]
operations = [
migrations.CreateModel(
name='Cart',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('quantity', models.IntegerField()),
('cuser_role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cuser.cuserrole')),
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.product')),
],
options={
'abstract': False,
},
),
]
+21
View File
@@ -0,0 +1,21 @@
# Generated by Django 4.2.1 on 2023-10-22 07:00
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('workspace', '0003_alter_workspace_uuid'),
('shop', '0009_cart'),
]
operations = [
migrations.AddField(
model_name='cart',
name='sys_ws',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='workspace.workspace'),
preserve_default=False,
),
]
+28
View File
@@ -0,0 +1,28 @@
# Generated by Django 4.2.1 on 2024-01-01 11:05
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('workspace', '0003_alter_workspace_uuid'),
('shop', '0010_cart_sys_ws'),
]
operations = [
migrations.CreateModel(
name='ProductType',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=100)),
('sys_ws', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='workspace.workspace')),
],
options={
'abstract': False,
},
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-01-18 08:40
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0011_producttype'),
]
operations = [
migrations.AddField(
model_name='productcategory',
name='image',
field=models.ImageField(blank=True, default=None, null=True, upload_to=''),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 4.2.1 on 2024-01-20 07:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0012_productcategory_image'),
]
operations = [
migrations.AlterField(
model_name='productcategory',
name='image',
field=models.ImageField(blank=True, default=None, null=True, upload_to='product-cat/'),
),
]
View File
Whitespace-only changes.
+86
View File
@@ -0,0 +1,86 @@
from django.db import models
from utils.base_model import BaseModel
from apps.workspace.models import Workspace as WorkspaceModel
from apps.cuser.models import CuserRole as CuserRoleModel
from apps.customer.models import ResponsibleGroup as ResponsibleGroupModel, Customer as CustomerModel
# Create your models here.
class ProductType(BaseModel):
name = models.CharField(max_length=100)
sys_ws = models.ForeignKey(WorkspaceModel, on_delete=models.CASCADE, null=False, blank=False)
def __str__(self):
return f'{self.name}'
class ProductCategory(BaseModel):
name = models.CharField(max_length=30, null=False, blank=False)
parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True)
image = models.ImageField(null=True, blank=True, default=None, upload_to='product-cat/')
sys_ws = models.ForeignKey(WorkspaceModel, on_delete=models.CASCADE, null=False, blank=False)
def __str__(self):
return f'{self.name}'
class Product(BaseModel):
name = models.CharField(max_length=150, null=False, blank=False)
price = models.DecimalField(max_digits=12, decimal_places=2, null=False, blank=False)
category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE, null=False, blank=False)
acc_code = models.CharField(null=True, blank=True)
attr = models.JSONField(null=True, blank=True)
sys_ws = models.ForeignKey(WorkspaceModel, on_delete=models.CASCADE, null=False, blank=False)
def __str__(self):
return f'{self.name}'
class Cart(BaseModel):
cuser_role = models.ForeignKey(CuserRoleModel, on_delete=models.CASCADE, null=False, blank=False)
product = models.ForeignKey(Product, on_delete=models.CASCADE, null=False, blank=False)
quantity = models.IntegerField(null=False, blank=False)
sys_ws = models.ForeignKey(WorkspaceModel, on_delete=models.CASCADE, null=False, blank=False)
def __str__(self):
return f'{self.cuser_role}'
class Order(BaseModel):
FACTOR_TYPE_CHOICE = [
(1, 'pish_factor'),
(2, 'factor'),
]
FACTOR_STATUS_CHOICE = [
(1, 'unknown'),
(2, 'ok'),
(3, 'cancel'),
]
responsible_group = models.ForeignKey(ResponsibleGroupModel, on_delete=models.SET_NULL, null=True, blank=True)
customer = models.ForeignKey(CustomerModel, on_delete=models.CASCADE, null=False, blank=False)
total_price = models.DecimalField(max_digits=12, decimal_places=2, null=False, blank=False)
factor_type = models.PositiveSmallIntegerField(choices=FACTOR_TYPE_CHOICE, null=False, blank=False)
factor_status = models.PositiveSmallIntegerField(choices=FACTOR_STATUS_CHOICE, null=True, blank=True)
sys_ws = models.ForeignKey(WorkspaceModel, on_delete=models.CASCADE, null=False, blank=False)
def __str__(self):
return f'{self.customer}'
class OrderItem(BaseModel):
order = models.ForeignKey(Order, on_delete=models.CASCADE, null=False, blank=False)
product = models.ForeignKey(Product, on_delete=models.CASCADE, null=False, blank=False)
product_name = models.CharField(max_length=150, null=False, blank=False)
price = models.DecimalField(max_digits=12, decimal_places=2, null=False, blank=False)
amount = models.PositiveIntegerField(null=False, blank=False)
def __str__(self):
return f'{self.order} {self.order.id}'
+5
View File
@@ -0,0 +1,5 @@
from .product_category import *
from .product import *
from .order import *
from .cart import *
from .order_item import *
+9
View File
@@ -0,0 +1,9 @@
from apps.shop.models import Cart as CartModel
def list_cart(cuser_role_uuid: str, workspace_uuid: str) -> CartModel:
return CartModel.objects.filter(sys_ws__uuid=workspace_uuid, cuser_role__uuid=cuser_role_uuid)
def clean_cart(cuser_role_uuid: str, workspace_uuid: str) -> CartModel:
return CartModel.objects.filter(sys_ws__uuid=workspace_uuid, cuser_role__uuid=cuser_role_uuid).delete()
+46
View File
@@ -0,0 +1,46 @@
from apps.shop.models import Order as OrderModel
from apps.customer.models import CustomerResponsible as CustomerResponsibleModel
from apps.cuser.models import CuserRole as CuserRoleModel
from rest_framework import exceptions
from utils.custom_permissions import workspace_admin_up
from apps.customer.models import Customer as CustomerModel
def retrieve_order(cuser_role_uuid: str, order_id: int, workspace_uuid: str) -> OrderModel:
try:
cuser_role = CuserRoleModel.objects.select_related('role_type').get
role_type = cuser_role.role_type
if role_type.role_name_en == 'workspace_customer':
customer = CustomerModel.objects.get(cuser_role=cuser_role)
order_obj = OrderModel.objects.get(id=order_id, sys_ws__uuid=workspace_uuid, customer=customer)
return order_obj
if role_type.role_name_en in ('workspace_owner', 'workspace_operator', 'workspace_admin'):
order_obj = OrderModel.objects.get(id=order_id, sys_ws__uuid=workspace_uuid)
return order_obj
except Exception as exp:
message = f'Error Retrieve Order: {exp}'
raise exceptions.ValidationError({'error': message})
def list_order(cuser_role_uuid: str, workspace_uuid: str) -> OrderModel:
try:
cuser_role = CuserRoleModel.objects.select_related('role_type').get(uuid=cuser_role_uuid)
role_type = cuser_role.role_type
if role_type.role_name_en == 'workspace_customer':
customer = CustomerModel.objects.get(cuser_role=cuser_role)
orders_obj = OrderModel.objects.filter(sys_ws__uuid=workspace_uuid, customer=customer).order_by('-created_at')
return orders_obj
if role_type.role_name_en in ('workspace_owner', 'workspace_operator', 'workspace_admin'):
orders_obj = OrderModel.objects.filter(sys_ws__uuid=workspace_uuid).order_by('-created_at')
return orders_obj
except Exception as exp:
message = f'Error Fetching List Order: {exp}'
raise exceptions.ValidationError({'error': message})
+19
View File
@@ -0,0 +1,19 @@
from apps.shop.models import OrderItem as OrderItemModel
from apps.cuser.models import CuserRole as CuserRoleModel
from rest_framework import exceptions
def list_order_item(order_id: int, cuser_role_uuid: str) -> OrderItemModel:
try:
cuser_role_uuid_obj = CuserRoleModel.objects.get(uuid=cuser_role_uuid)
order_items_obj = OrderItemModel.objects.filter(
order_id=order_id,
order__customer__cuser_role_id=cuser_role_uuid_obj.id).order_by('-created_at')
return order_items_obj
except Exception as exp:
message = f'Error Fetching List Order items: {exp}'
raise exceptions.ValidationError({'error': message})
+38
View File
@@ -0,0 +1,38 @@
from apps.shop.models import Product as ProductModel
from rest_framework import exceptions
def retrieve_product(product_id: int, workspace_uuid: str) -> ProductModel:
try:
product_obj = ProductModel.objects.get(id=product_id, sys_ws__uuid=workspace_uuid)
return product_obj
except Exception as exp:
message = f'Error Retrieve Product: {exp}'
raise exceptions.ValidationError({'error': message})
def list_product(workspace_uuid: str) -> ProductModel:
try:
product_category_obj = ProductModel.objects.filter(sys_ws__uuid=workspace_uuid)
return product_category_obj
except Exception as exp:
message = f'Error Fetching List Product: {exp}'
raise exceptions.ValidationError({'error': message})
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)
return product_category_obj
except Exception as exp:
message = f'Error Fetching 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()
return count_product
except Exception as exp:
message = f'Error Couting Product in category: {exp}'
raise exceptions.ValidationError({'error': message})
+20
View File
@@ -0,0 +1,20 @@
from apps.shop.models import ProductCategory as ProductCategoryModel
from rest_framework import exceptions
def retrieve_product_category(category_id: int, workspace_uuid: str) -> ProductCategoryModel:
try:
product_category_obj = ProductCategoryModel.objects.get(id=category_id, sys_ws__uuid=workspace_uuid)
return product_category_obj
except Exception as exp:
message = f'Error Retrieve ProductCategory: {exp}'
raise exceptions.ValidationError({'error': message})
def list_product_category(workspace_uuid: str) -> ProductCategoryModel:
try:
product_category_obj = ProductCategoryModel.objects.filter(sys_ws__uuid=workspace_uuid)
return product_category_obj
except Exception as exp:
message = f'Error Fetching List ProductCategory: {exp}'
raise exceptions.ValidationError({'error': message})
+5
View File
@@ -0,0 +1,5 @@
from .product_category import *
from .product import *
from .order import *
from .order_item import *
from .cart import *
+36
View File
@@ -0,0 +1,36 @@
from rest_framework import exceptions
from decimal import Decimal
from django.db import transaction
from apps.shop.models import Cart as CartModel
def add_to_cart(product_id: int, quantity: int, workspace, cuser_role) -> CartModel:
try:
try:
cart_obj = CartModel.objects.get(product_id=product_id, sys_ws=workspace, cuser_role=cuser_role)
except Exception as exp:
cart_obj = CartModel()
cart_obj.product_id = product_id
cart_obj.quantity = quantity
cart_obj.sys_ws = workspace
cart_obj.cuser_role = cuser_role
cart_obj.full_clean()
cart_obj.save()
return cart_obj
except Exception as exp:
message = f'Error Add to Cart: {exp}'
exceptions.ValidationError({'error': message})
def delete_cart_iteam(cart_id: int, cuser_role_uuid, workspace_uuid: str) -> CartModel:
try:
cart_obj = CartModel.objects.get(id=cart_id, cuser_role__uuid=cuser_role_uuid, sys_ws__uuid=workspace_uuid).delete()
return cart_obj
except Exception as exp:
message = f'Error Deleting Cart iteam: {exp}'
raise exceptions.ValidationError({'error': message})
+111
View File
@@ -0,0 +1,111 @@
import json
from apps.shop.models import (
Order as OrderModel,
OrderItem as OrderItemModel,
Product as ProductModel,
)
from apps.customer.models import Customer as CustomerModel
from rest_framework import exceptions
from decimal import Decimal
from django.db import transaction
def create_order(responsible_group_id: int, customer_id: int,
total_amount: Decimal, factor_type: int, factor_status: int, workspace) -> OrderModel:
try:
order_obj = OrderModel()
order_obj.responsible_group_id = responsible_group_id
order_obj.customer_id = customer_id
order_obj.total_amount = total_amount
order_obj.factor_type = factor_type
order_obj.factor_status = factor_status
order_obj.sys_ws = workspace
order_obj.full_clean()
order_obj.save()
return order_obj
except Exception as exp:
message = f'Error Create Order: {exp}'
exceptions.ValidationError({'error': message})
def create_order_and_items(items: str, customer: CustomerModel, workspace) -> OrderModel:
with transaction.atomic():
try:
sum_price = 0
order_obj = OrderModel()
order_obj.responsible_group = customer.responsible_group
order_obj.customer = customer
order_obj.total_price = 0
order_obj.factor_type = 1
order_obj.factor_status = 1
order_obj.sys_ws = workspace
order_obj.full_clean()
order_obj.save()
json_items = json.loads(items)
for item in json_items:
product_obj = ProductModel.objects.get(id=int(item['product_id']))
product_price = product_obj.price
product_name = product_obj.name
order_item_obj = OrderItemModel()
order_item_obj.order = order_obj
order_item_obj.product_name = product_name
order_item_obj.price = product_price
order_item_obj.amount = int(item['amount'])
order_item_obj.product_id = int(item['product_id'])
order_item_obj.full_clean()
order_item_obj.save()
sum_price += product_price
order_obj.total_price = sum_price
order_obj.full_clean()
order_obj.save()
return order_obj
except Exception as exp:
transaction.set_rollback(True)
message = f'Error Create Order: {exp}'
raise exceptions.ValidationError({'error': message})
def update_order(order_id: int, responsible_group_id: int = None, customer_id: int = None,
total_amount: Decimal = None, factor_type: int = None, factor_status: int = None, workspace_uuid = None) -> OrderModel:
try:
order_obj = OrderModel.objects.get(id=order_id, sys_ws__uuid=workspace_uuid)
if responsible_group_id is not None:
order_obj.responsible_group_id = responsible_group_id
if customer_id is not None:
order_obj.customer_id = customer_id
if total_amount is not None:
order_obj.total_amount = total_amount
if factor_type is not None:
order_obj.factor_type = factor_type
if factor_status is not None:
order_obj.factor_status = factor_status
order_obj.full_clean()
order_obj.save()
return order_obj
except Exception as exp:
message = f'Error Updating Order: {exp}'
raise exceptions.ValidationError({'error': message})
def delete_order(order_id: int, workspace_uuid: str) -> OrderModel:
try:
order_obj = OrderModel.objects.get(id=order_id, sys_ws__uuid=workspace_uuid).delete()
return order_obj
except Exception as exp:
message = f'Error Deleting Order: {exp}'
raise exceptions.ValidationError({'error': message})
+18
View File
@@ -0,0 +1,18 @@
import json
from decimal import Decimal
from apps.shop.models import OrderItem as OrderItemModel
def create_order_items(items: str, order_id: int):
json_items = json.loads(items)
for item in json_items:
order_item_obj = OrderItemModel()
order_item_obj.order_id = order_id
order_item_obj.price = Decimal(item.price)
order_item_obj.amount = int(item.amount)
order_item_obj.product_id = int(item.product)
order_item_obj.full_clean()
order_item_obj.save()
+55
View File
@@ -0,0 +1,55 @@
from apps.shop.models import Product as ProductModel
from decimal import Decimal
from rest_framework import exceptions
def create_product(name: str, price: Decimal, category: int, acc_code: str = None, attr: str = None, workspace=None) -> ProductModel:
try:
product_obj = ProductModel()
product_obj.name = name
product_obj.price = price
product_obj.category_id = category
if acc_code is not None:
product_obj.acc_code = acc_code
if attr is not None:
product_obj.attr = attr
product_obj.sys_ws = workspace
product_obj.full_clean()
product_obj.save()
return product_obj
except Exception as exp:
message = f'Error Create Product: {exp}'
exceptions.ValidationError({'error': message})
def update_product(product_id: int, name: str, price: Decimal, category: int, acc_code: str = None, attr: str = None, workspace_uuid: str = None) -> ProductModel:
try:
product_obj = ProductModel.objects.get(id=product_id, sys_ws__uuid=workspace_uuid)
product_obj.name = name
product_obj.price = price
product_obj.category_id = category
if acc_code is not None:
product_obj.acc_code = acc_code
if attr is not None:
product_obj.attr = attr
product_obj.full_clean()
product_obj.save()
return product_obj
except Exception as exp:
message = f'Error Updating Product: {exp}'
raise exceptions.ValidationError({'error': message})
def delete_product(product_id: int, workspace_uuid: str) -> ProductModel:
try:
product_obj = ProductModel.objects.get(id=product_id, sys_ws__uuid=workspace_uuid).delete()
return product_obj
except Exception as exp:
message = f'Error Deleting Product: {exp}'
raise exceptions.ValidationError({'error': message})
+40
View File
@@ -0,0 +1,40 @@
from apps.shop.models import ProductCategory as ProductCategoryModel
from rest_framework import exceptions
def create_product_category(name: str, parent: int = None, workspace=None) -> ProductCategoryModel:
try:
product_category_obj = ProductCategoryModel(name=name, sys_ws=workspace)
if parent is not None:
product_category_obj.parent_id = parent
product_category_obj.full_clean()
product_category_obj.save()
return product_category_obj
except Exception as exp:
message = f'Error Create ProductCategory: {exp}'
exceptions.ValidationError({'error': message})
def update_product_category(category_id: int, name: str, workspace_uuid: str) -> ProductCategoryModel:
try:
product_category_obj = ProductCategoryModel.objects.get(id=category_id, sys_ws__uuid=workspace_uuid)
product_category_obj.name = name
product_category_obj.full_clean()
product_category_obj.save()
return product_category_obj
except Exception as exp:
message = f'Error Updating ProductCategory: {exp}'
raise exceptions.ValidationError({'error': message})
def delete_product_category(category_id: int, workspace_uuid: str) -> ProductCategoryModel:
try:
product_category_obj = ProductCategoryModel.objects.get(id=category_id, sys_ws__uuid=workspace_uuid).delete()
return product_category_obj
except Exception as exp:
message = f'Error Deleting ProductCategory: {exp}'
raise exceptions.ValidationError({'error': message})
+3
View File
@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.
+34
View File
@@ -0,0 +1,34 @@
from django.urls import path
from apps.shop.views import *
urlpatterns = [
path('product-category/create/', ProductCategoryCreateApi.as_view(), name='create_product_category'),
path('product-category/<int:category_id>/', ProductCategoryRetrieveApi.as_view(), name='retrieve_product_category'),
path('product-category/update/<int:category_id>/', ProductCategoryUpdateApi.as_view(), name='update_product_category'),
path('product-category/delete/<int:category_id>/', ProductCategoryDeleteApi.as_view(), name='delete_product_category'),
path('product-category/list/', ProductCategoryListApi.as_view(), name='list_product_category'),
path('v2/product-category/list/', ProductsCategoryApi.as_view(), name='v2_list_product_category'),
path('product/create/', ProductCreateApi.as_view(), name='create_product'),
path('product/<int:product_id>/', ProductRetrieveApi.as_view(), name='retrieve_product'),
path('product/update/<int:product_id>/', ProductUpdateApi.as_view(), name='update_product'),
path('product/delete/<int:product_id>/', ProductDeleteApi.as_view(), name='delete_product'),
path('product/list/', ProductListApi.as_view(), name='list_product'),
path('product/list/<int:category_id>/', ProductListCategoryApi.as_view(), name='list_product_by_category'),
path('order/create/', OrderCreateApi.as_view(), name='create_order'),
path('order-and-item/create/', OrderAndItemCreateApi.as_view(), name='create_order_and_items'),
path('order/<int:order_id>/', OrderRetrieveApi.as_view(), name='retrieve_order'),
path('order/update/<int:order_id>/', OrderUpdateApi.as_view(), name='update_order'),
path('order/delete/<int:order_id>/', OrderDeleteApi.as_view(), name='delete_order'),
path('order/list/', OrderListApi.as_view(), name='list_order'),
path('order/iteams/list/<int:order_id>/', OrderItemsListApi.as_view(), name='list_order_items'),
path('cart/', CartListApi.as_view(), name='list_cart'),
path('cart/add/', CartCreateApi.as_view(), name='add_cart'),
path('cart/delete/<int:cart_id>/', CartDeleteApi.as_view(), name='delete_cart'),
]
+3
View File
@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.
+16
View File
@@ -0,0 +1,16 @@
from .product_category import (
ProductCategoryCreateApi, ProductCategoryRetrieveApi, ProductCategoryDeleteApi, ProductCategoryListApi,
ProductCategoryUpdateApi, ProductsCategoryApi
)
from .product import (
ProductCreateApi, ProductRetrieveApi, ProductDeleteApi, ProductUpdateApi, ProductListApi, ProductListCategoryApi
)
from .order import (
OrderCreateApi, OrderUpdateApi, OrderDeleteApi, OrderRetrieveApi, OrderListApi, OrderAndItemCreateApi
)
from .cart import (CartListApi, CartCreateApi, CartDeleteApi)
from .order_item import (OrderItemsListApi, )
+85
View File
@@ -0,0 +1,85 @@
from rest_framework import generics, views
from apps.shop.models import Cart as CartModel, Product as ProductModel
from utils.get_user_workspace import get_user_workspace_uuid
from utils.get_cuser_role import get_cuser_role_uuid
from apps.shop.selectors import list_cart
from rest_framework import serializers
from rest_framework.permissions import IsAuthenticated
from utils import custom_permissions
from utils.get_user_workspace import get_user_workspace_uuid, get_user_workspace
from utils.get_cuser_role import get_cuser_role
from rest_framework.response import Response
from apps.shop.services import add_to_cart, delete_cart_iteam
from rest_framework import status
class CartListApi(generics.ListAPIView):
class OutputSerializer(serializers.ModelSerializer):
class ProductSerializer(serializers.ModelSerializer):
class CategorySerializer(serializers.Serializer):
name = serializers.CharField()
category = CategorySerializer()
class Meta:
model = ProductModel
exclude = ('sys_ws', 'created_at', 'updated_at', 'acc_code', 'attr')
product = ProductSerializer()
class Meta:
model = CartModel
exclude = ('sys_ws', 'created_at', 'updated_at', 'cuser_role')
serializer_class = OutputSerializer
def get_queryset(self):
user_workspace_uuid = get_user_workspace_uuid(self.request)
cuser_role_uuid = get_cuser_role_uuid(self.request)
return list_cart(workspace_uuid=user_workspace_uuid, cuser_role_uuid=cuser_role_uuid)
class CartCreateApi(views.APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceCustomerPermission)
class InputSerializer(serializers.Serializer):
product_id = serializers.IntegerField(required=True)
quantity = serializers.IntegerField(required=True)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = CartModel
exclude = ('sys_ws', )
def post(self, request):
serializer = self.InputSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user_workspace = get_user_workspace(request)
cuser_role = get_cuser_role(request)
cart_obj = add_to_cart(**serializer.validated_data, workspace=user_workspace, cuser_role=cuser_role)
output = self.OutputSerializer(cart_obj)
return Response(data=output.data, status=status.HTTP_201_CREATED)
class CartDeleteApi(views.APIView):
def delete(self, request, cart_id: int):
user_workspace_uuid = get_user_workspace_uuid(request=request)
cuser_role_uuid = get_cuser_role_uuid(request=request)
cart_obj = delete_cart_iteam(cart_id=cart_id, cuser_role_uuid=cuser_role_uuid, workspace_uuid=user_workspace_uuid)
output = {
'order_id': cart_obj,
'message': 'deleted successfully'
}
return Response(data=output, status=status.HTTP_200_OK)
+152
View File
@@ -0,0 +1,152 @@
from apps.shop.models import Order as OrderModel
from rest_framework.views import APIView
from rest_framework import serializers
from utils.get_user_workspace import get_user_workspace_uuid, get_user_workspace
from utils.get_cuser_role import get_cuser_role_uuid
from rest_framework.response import Response
from rest_framework import status
from apps.shop.services import *
from apps.shop.selectors import *
from rest_framework import generics
from apps.customer.models import Customer as CustomerModel
from rest_framework.permissions import IsAuthenticated
from utils import custom_permissions
class OrderCreateApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceAdminPermission)
class InputSerializer(serializers.Serializer):
responsible_group_id = serializers.IntegerField(required=True)
customer_id = serializers.IntegerField(required=True)
total_amount = serializers.DecimalField(max_digits=20, decimal_places=2)
factor_type = serializers.IntegerField(required=True)
factor_status = serializers.IntegerField(required=True)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = OrderModel
exclude = ('sys_ws', )
def post(self, request):
serializer = self.InputSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user_workspace = get_user_workspace(request)
order_obj = create_order(**serializer.validated_data, workspace=user_workspace)
output = self.OutputSerializer(order_obj)
return Response(data=output.data, status=status.HTTP_201_CREATED)
class OrderAndItemCreateApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceCustomerPermission)
class InputSerializer(serializers.Serializer):
items = serializers.CharField(required=True)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = OrderModel
exclude = ('sys_ws', )
def post(self, request):
serializer = self.InputSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user_workspace = get_user_workspace(request)
cuser_role_uuid = get_cuser_role_uuid(request)
try:
customer_obj = CustomerModel.objects.get(cuser_role__uuid=cuser_role_uuid)
except Exception as exp:
raise exceptions.ValidationError({'error': f'customer obj not found: {exp}'})
order_obj = create_order_and_items(**serializer.validated_data, customer=customer_obj, workspace=user_workspace)
clean_cart(cuser_role_uuid=cuser_role_uuid,workspace_uuid=user_workspace.uuid)
output = self.OutputSerializer(order_obj)
return Response(data=output.data, status=status.HTTP_201_CREATED)
class OrderRetrieveApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceCustomerPermission)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = OrderModel
exclude = ('sys_ws', )
def get(self, request, order_id):
user_workspace_uuid = get_user_workspace_uuid(request=request)
cuser_role_uuid = get_cuser_role_uuid(request=request)
request_user = request.user
order_obj = retrieve_order(cuser_role_uuid=cuser_role_uuid, order_id=order_id, workspace_uuid=user_workspace_uuid)
output = self.OutputSerializer(order_obj)
return Response(data=output.data, status=status.HTTP_200_OK)
class OrderUpdateApi(APIView):
class InputSerializer(serializers.Serializer):
responsible_group_id = serializers.IntegerField(required=False)
customer_id = serializers.IntegerField(required=False)
total_amount = serializers.DecimalField(max_digits=20, decimal_places=2, required=False)
factor_type = serializers.IntegerField(required=False)
factor_status = serializers.IntegerField(required=False)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = OrderModel
exclude = ('sys_ws', )
def patch(self, request, order_id):
serializer = self.InputSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user_workspace_uuid = get_user_workspace_uuid(request)
order_obj = update_order(order_id=order_id, **serializer.validated_data, workspace_uuid=user_workspace_uuid)
output = self.OutputSerializer(order_obj)
return Response(data=output.data, status=status.HTTP_200_OK)
class OrderDeleteApi(APIView):
def delete(self, request, order_id: int):
user_workspace_uuid = get_user_workspace_uuid(request=request)
order_obj = delete_order(order_id=order_id, workspace_uuid=user_workspace_uuid)
output = {
'order_id': order_id,
'message': 'deleted successfully'
}
return Response(data=output, status=status.HTTP_200_OK)
class OrderListApi(generics.ListAPIView):
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = OrderModel
exclude = ('sys_ws', )
serializer_class = OutputSerializer
def get_queryset(self):
cuser_role_uuid = get_cuser_role_uuid(request=self.request)
user_workspace_uuid = get_user_workspace_uuid(request=self.request)
return list_order(cuser_role_uuid=cuser_role_uuid, workspace_uuid=user_workspace_uuid)
+30
View File
@@ -0,0 +1,30 @@
from rest_framework.views import APIView
from rest_framework import generics
from rest_framework import serializers
from apps.shop.models import OrderItem as OrderItemModel
from utils.get_user_workspace import get_user_workspace_uuid, get_user_workspace
from utils.get_cuser_role import get_cuser_role_uuid
from apps.shop.selectors import list_order_item
class OrderItemsListApi(generics.ListAPIView):
class OutputSerializer(serializers.ModelSerializer):
category_name = serializers.SerializerMethodField()
class Meta:
model = OrderItemModel
fields = '__all__'
def get_category_name(self, obj):
return obj.product.category.name
serializer_class = OutputSerializer
def get_queryset(self):
cuser_role_uuid = get_cuser_role_uuid(request=self.request)
#user_workspace_uuid = get_user_workspace_uuid(request=self.request)
order_id = self.kwargs.get('order_id')
return list_order_item(order_id=order_id, cuser_role_uuid=cuser_role_uuid)
+165
View File
@@ -0,0 +1,165 @@
from apps.shop.models import Product as ProductModel
from rest_framework.views import APIView
from rest_framework import serializers
from utils.get_user_workspace import get_user_workspace_uuid, get_user_workspace
from rest_framework.response import Response
from rest_framework import status
from apps.shop.services import *
from apps.shop.selectors import *
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from utils import custom_permissions
class ProductCreateApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceAdminPermission)
class InputSerializer(serializers.Serializer):
name = serializers.CharField(required=True, max_length=20)
price = serializers.DecimalField(required=True, max_digits=20, decimal_places=2)
category = serializers.IntegerField(required=True)
acc_code = serializers.CharField(required=False)
attr = serializers.CharField(required=False)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductModel
exclude = ('sys_ws', )
def post(self, request):
serializer = self.InputSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user_workspace = get_user_workspace(request)
product_obj = create_product(**serializer.validated_data, workspace=user_workspace)
output = self.OutputSerializer(product_obj)
return Response(data=output.data, status=status.HTTP_201_CREATED)
class ProductRetrieveApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceCustomerPermission)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductModel
exclude = ('sys_ws', )
def get(self, request, product_id: int):
user_workspace_uuid = get_user_workspace_uuid(request)
product_obj = retrieve_product(product_id, workspace_uuid=user_workspace_uuid)
output = self.OutputSerializer(product_obj)
return Response(data=output.data, status=status.HTTP_200_OK)
class ProductUpdateApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceAdminPermission)
class InputSerializer(serializers.Serializer):
name = serializers.CharField(required=True, max_length=20)
price = serializers.DecimalField(required=True, max_digits=20, decimal_places=2)
category = serializers.IntegerField(required=True)
acc_code = serializers.CharField(required=False)
attr = serializers.CharField(required=False)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductModel
exclude = ('sys_ws', )
def put(self, request, product_id: int):
serializer = self.InputSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user_workspace_uuid = get_user_workspace_uuid(request)
product_obj = update_product(product_id=product_id, **serializer.validated_data, workspace_uuid=user_workspace_uuid)
output = self.OutputSerializer(product_obj)
return Response(data=output.data, status=status.HTTP_200_OK)
class ProductDeleteApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceAdminPermission)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductModel
exclude = ('sys_ws', )
def delete(self, request, product_id: int):
user_workspace_uuid = get_user_workspace_uuid(request=request)
product_obj = delete_product(product_id=product_id, workspace_uuid=user_workspace_uuid)
output = {
'id': product_id,
'status': 'deleted successfully'
}
return Response(data=output, status=status.HTTP_200_OK)
class ProductListApi(generics.ListAPIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceCustomerPermission)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductCategoryModel
exclude = ('sys_ws', )
def get_queryset(self):
user_workspace_uuid = get_user_workspace_uuid(self.request)
return list_product(workspace_uuid=user_workspace_uuid)
serializer_class = OutputSerializer
class ProductListCategoryApi(generics.ListAPIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceCustomerPermission)
class OutputSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField()
price = serializers.FloatField()
class Meta:
exclude = ('sys_ws', )
def list(self, request, category_id):
# Note the use of `get_queryset()` instead of `self.queryset`
queryset_data = self.get_queryset()
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)
if len(serializer.data) == 0:
return Response(
status=404,
)
data = {
"category_name": category.name,
"products": serializer.data
}
return Response(data)
def get_queryset(self):
user_workspace_uuid = get_user_workspace_uuid(self.request)
category_id = self.kwargs.get('category_id')
return list_product_by_category(workspace_uuid=user_workspace_uuid, category_id=category_id)
serializer_class = OutputSerializer
+162
View File
@@ -0,0 +1,162 @@
from apps.shop.models import ProductCategory as ProductCategoryModel, Product as ProductModel
from rest_framework.views import APIView
from rest_framework import serializers
from utils.get_user_workspace import get_user_workspace_uuid, get_user_workspace
from rest_framework.response import Response
from rest_framework import status
from apps.shop.services import *
from apps.shop.selectors import *
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from django.db.models import Count
from utils.tools import inline_serializer
from utils import custom_permissions
class ProductCategoryCreateApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceAdminPermission)
class InputSerializer(serializers.Serializer):
name = serializers.CharField(required=True, max_length=20)
parent = serializers.IntegerField(required=False)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductCategoryModel
exclude = ('sys_ws', )
def post(self, request):
serializer = self.InputSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user_workspace = get_user_workspace(request)
product_category_obj = create_product_category(**serializer.validated_data, workspace=user_workspace)
output = self.OutputSerializer(product_category_obj)
return Response(data=output.data, status=status.HTTP_201_CREATED)
class ProductCategoryRetrieveApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceCustomerPermission)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductCategoryModel
exclude = ('sys_ws', )
def get(self, request, category_id: int):
user_workspace_uuid = get_user_workspace_uuid(request)
product_category_obj = retrieve_product_category(category_id=category_id, workspace_uuid=user_workspace_uuid)
output = self.OutputSerializer(product_category_obj)
return Response(data=output.data, status=status.HTTP_200_OK)
class ProductCategoryUpdateApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceAdminPermission)
class InputSerializer(serializers.Serializer):
name = serializers.CharField(required=True)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductCategoryModel
exclude = ('sys_ws', )
def put(self, request, category_id: int):
serializer = self.InputSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
name = serializer.validated_data.get
user_workspace_uuid = get_user_workspace_uuid(request)
product_category_obj = update_product_category(name=name, category_id=category_id, workspace_uuid=user_workspace_uuid)
output = self.OutputSerializer(product_category_obj)
return Response(data=output.data, status=status.HTTP_200_OK)
class ProductCategoryDeleteApi(APIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceAdminPermission)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductCategoryModel
exclude = ('sys_ws', )
def delete(self, request, category_id: int):
user_workspace_uuid = get_user_workspace_uuid(request=request)
product_category_obj = delete_product_category(category_id=category_id, workspace_uuid=user_workspace_uuid)
output = {
'id': category_id,
'status': 'deleted successfully'
}
return Response(data=output, status=status.HTTP_200_OK)
class ProductCategoryListApi(generics.ListAPIView):
permission_classes = (IsAuthenticated, custom_permissions.WorkspaceCustomerPermission)
class OutputSerializer(serializers.ModelSerializer):
class Meta:
model = ProductCategoryModel
exclude = ('sys_ws', )
def list(self, request):
# Note the use of `get_queryset()` instead of `self.queryset`
queryset_data = self.get_queryset()
serializer = self.get_serializer(queryset_data, many=True)
workspace_uuid = get_user_workspace_uuid(request=request)
print(workspace_uuid)
category = list_product_category(workspace_uuid=workspace_uuid)
categorysList = []
for cate in category:
count_prd = count_product_in_category(category_id=cate.id, workspace_uuid=workspace_uuid)
if count_prd >= 1:
tmp_cat = {
"name": cate.name,
"count": count_prd,
"id": cate.id,
}
categorysList.append(tmp_cat)
return Response(categorysList)
def get_queryset(self):
user_workspace_uuid = get_user_workspace_uuid(self.request)
return list_product_category(workspace_uuid=user_workspace_uuid)
serializer_class = OutputSerializer
class ProductsCategoryApi(APIView):
class OutputSerializer(serializers.ModelSerializer):
product_count = serializers.IntegerField()
class Meta:
model = ProductCategoryModel
fields = '__all__'
def get(self, request):
p_cate = ProductCategoryModel.objects.annotate(product_count=Count('product')).filter(product_count__gte=1)
output = self.OutputSerializer(p_cate, many=True)
return Response(data=output.data, status=status.HTTP_200_OK)