Skip to content

Commit

Permalink
Merge pull request #14 from maykinmedia/feature/6-product-types-api
Browse files Browse the repository at this point in the history
Feature/6 product types api
  • Loading branch information
Floris272 authored Sep 3, 2024
2 parents 6467416 + be49dd2 commit 478a09a
Show file tree
Hide file tree
Showing 37 changed files with 4,760 additions and 55 deletions.
19 changes: 7 additions & 12 deletions .github/workflows/generate-postman-collection.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
name: generate-postman-collection

on:
# push:
# paths:
# - "src/open_producten/api/v*/openapi.yaml"
# - ".github/workflows/generate-postman-collection.yml"
# branches:
# - '**'
push:
paths:
- "src/openapi.yaml"
- ".github/workflows/generate-postman-collection.yml"
branches:
- '**'
workflow_dispatch:

jobs:
run:
runs-on: ubuntu-latest
strategy:
matrix:
version: [ 'v1' ]

name: Run with version $

steps:
- uses: actions/checkout@v4
Expand All @@ -29,4 +24,4 @@ jobs:
- name: Create tests folder
run: mkdir -p ./tests/postman
- name: Generate Postman collection
run: openapi2postmanv2 -s ./src/open_producten/api/$/openapi.yaml -o ./tests/postman/collection.json --pretty
run: openapi2postmanv2 -s ./src/openapi.yaml -o ./tests/postman/collection.json --pretty
28 changes: 11 additions & 17 deletions .github/workflows/generate-sdks.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
name: generate-sdks

on:
# push:
# paths:
# - "src/open_producten/api/v*/openapi.yaml"
# - ".github/workflows/generate-sdks.yml"
# branches:
# - '**'
push:
paths:
- "src/openapi.yaml"
- ".github/workflows/generate-sdks.yml"
branches:
- '**'
workflow_dispatch:

jobs:
run:
runs-on: ubuntu-latest
strategy:
matrix:
version: [ 'v1' ]

name: Run with version $

steps:
- uses: actions/checkout@v4
- name: Use Node.js
Expand All @@ -28,15 +22,15 @@ jobs:
run: npm install -g @openapitools/openapi-generator-cli
- name: Determing oas path
id: vars
run: echo ::set-output name=oas::./src/open_producten/api/$/openapi.yaml
run: echo ::set-output name=oas::./src/openapi.yaml
- name: Validate schema
run: openapi-generator-cli validate -i $
run: openapi-generator-cli validate -i ${{ steps.vars.outputs.oas }}
- name: Generate Java client
run: openapi-generator-cli generate -i $ --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \
run: openapi-generator-cli generate -i ${{ steps.vars.outputs.oas }} --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \
-o ./sdks/java -g java --additional-properties=dateLibrary=java8,java8=true,optionalProjectFile=false,optionalAssemblyInfo=false
- name: Generate .NET client
run: openapi-generator-cli generate -i $ --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \
run: openapi-generator-cli generate -i ${{ steps.vars.outputs.oas }} --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \
-o ./sdks/net -g csharp --additional-properties=optionalProjectFile=false,optionalAssemblyInfo=false
- name: Generate Python client
run: openapi-generator-cli generate -i $ --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \
run: openapi-generator-cli generate -i ${{ steps.vars.outputs.oas }} --global-property=modelTests=false,apiTests=false,modelDocs=false,apiDocs=false \
-o ./sdks/python -g python --additional-properties=optionalProjectFile=false,optionalAssemblyInfo=false+
20 changes: 7 additions & 13 deletions .github/workflows/lint-oas.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
name: lint-oas

on:
# push:
# paths:
# - "src/open_producten/api/v*/openapi.yaml"
# - .github/workflows/lint-oas.yml
# branches:
# - '**'
push:
paths:
- "src/openapi.yaml"
- .github/workflows/lint-oas.yml
branches:
- '**'
workflow_dispatch:

jobs:
run:
runs-on: ubuntu-latest
strategy:
matrix:
version: [ 'v1' ]

name: Run with version $

steps:
- uses: actions/checkout@v4
- name: Use Node.js
Expand All @@ -27,4 +21,4 @@ jobs:
- name: Install spectral
run: npm install -g @stoplight/spectral@5
- name: Run OAS linter
run: spectral lint ./src/open_producten/api/$/openapi.yaml
run: spectral lint ./src/openapi.yaml
29 changes: 29 additions & 0 deletions src/open_producten/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,32 @@
ADMIN_INDEX_DISPLAY_DROP_DOWN_MENU_CONDITION_FUNCTION = (
"open_producten.utils.django_two_factor_auth.should_display_dropdown_menu"
)

#
# Django rest framework
#

REST_FRAMEWORK = {
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
"DEFAULT_PARSER_CLASSES": [
"rest_framework.parsers.JSONParser",
],
}

#
# SPECTACULAR - OpenAPI schema generation
#

_DESCRIPTION = """
Open Producten is an API to manage product types and products.
"""

API_VERSION = "0.0.1"

SPECTACULAR_SETTINGS = { # TODO: may need to be expanded.
"SCHEMA_PATH_PREFIX": "/api/v1",
"TITLE": "Open Producten API",
"DESCRIPTION": _DESCRIPTION,
"TOS": None,
"VERSION": API_VERSION,
}
2 changes: 1 addition & 1 deletion src/open_producten/products/tests/test_data_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from open_producten.products.models import Product
from open_producten.producttypes.models import FieldTypes
from open_producten.producttypes.tests.factories import FieldFactory, ProductTypeFactory
from open_producten.utils.tests.test_helpers import build_formset_data
from open_producten.utils.tests.helpers import build_formset_data

from ..admin.data import DataInlineFormSet
from ..models import Data
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
# Generated by Django 4.2.13 on 2024-08-16 13:54
# Generated by Django 4.2.13 on 2024-08-20 12:13

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("producttypes", "0002_remove_condition_rule_alter_field_description_and_more"),
]

operations = [
migrations.AlterField(
model_name="question",
name="category",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="questions",
to="producttypes.category",
verbose_name="Category",
),
),
migrations.AlterField(
model_name="question",
name="product_type",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="questions",
to="producttypes.producttype",
verbose_name="Product type",
),
),
migrations.AlterField(
model_name="tag",
name="type",
field=models.ForeignKey(
help_text="The related tag type",
on_delete=django.db.models.deletion.RESTRICT,
related_name="tags",
to="producttypes.tagtype",
verbose_name="Type",
),
),
migrations.AlterField(
model_name="field",
name="type",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.13 on 2024-08-30 13:33

from decimal import Decimal
import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
(
"producttypes",
"0003_alter_question_category_alter_question_product_type_and_more",
),
]

operations = [
migrations.AlterField(
model_name="priceoption",
name="amount",
field=models.DecimalField(
decimal_places=2,
help_text="The amount of the price option",
max_digits=8,
validators=[django.core.validators.MinValueValidator(Decimal("0.01"))],
verbose_name="Price",
),
),
]
4 changes: 2 additions & 2 deletions src/open_producten/producttypes/models/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ class Meta:

def clean(self):
if self.type in self.choice_fields and not self.choices:
raise ValidationError(f"Choices are required for {self.type}")
raise ValidationError({"choices": f"Choices are required for {self.type}"})

if self.choices and self.type not in self.choice_fields:
raise ValidationError(f"{self.type} cannot have choices")
raise ValidationError({"choices": f"{self.type} cannot have choices"})

def __str__(self):
return self.name
1 change: 0 additions & 1 deletion src/open_producten/producttypes/models/price.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class PriceOption(BaseModel):
verbose_name=_("Price"),
decimal_places=2,
max_digits=8,
default=0,
validators=[MinValueValidator(Decimal("0.01"))],
help_text=_("The amount of the price option"),
)
Expand Down
2 changes: 2 additions & 0 deletions src/open_producten/producttypes/models/question.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ class Question(BaseModel):
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="questions",
)
product_type = models.ForeignKey(
ProductType,
verbose_name=_("Product type"),
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="questions",
)
question = models.CharField(verbose_name=_("Question"), max_length=250)
answer = models.TextField(verbose_name=_("Answer"))
Expand Down
4 changes: 1 addition & 3 deletions src/open_producten/producttypes/models/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ class Tag(BaseModel):
)
type = models.ForeignKey(
TagType,
null=True,
blank=True,
verbose_name=_("Type"),
on_delete=models.SET_NULL,
on_delete=models.RESTRICT,
related_name="tags",
help_text=_("The related tag type"),
)
Expand Down
69 changes: 69 additions & 0 deletions src/open_producten/producttypes/router.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from django.urls import include, path

from rest_framework_nested.routers import DefaultRouter, NestedSimpleRouter

from open_producten.producttypes.views import (
CategoryQuestionViewSet,
CategoryViewSet,
ConditionViewSet,
ProductTypeFieldViewSet,
ProductTypeLinkViewSet,
ProductTypePriceViewSet,
ProductTypeQuestionViewSet,
ProductTypeViewSet,
TagTypeViewSet,
TagViewSet,
)

ProductTypesRouter = DefaultRouter()
ProductTypesRouter.register("producttypes", ProductTypeViewSet, basename="producttype")

ProductTypesLinkRouter = NestedSimpleRouter(
ProductTypesRouter, "producttypes", lookup="product_type"
)
ProductTypesLinkRouter.register(
r"links", ProductTypeLinkViewSet, basename="producttype-link"
)

ProductTypesPriceRouter = NestedSimpleRouter(
ProductTypesRouter, "producttypes", lookup="product_type"
)
ProductTypesPriceRouter.register(
r"prices", ProductTypePriceViewSet, basename="producttype-price"
)

ProductTypesQuestionRouter = NestedSimpleRouter(
ProductTypesRouter, "producttypes", lookup="product_type"
)
ProductTypesQuestionRouter.register(
r"questions", ProductTypeQuestionViewSet, basename="producttype-question"
)

ProductTypesFieldRouter = NestedSimpleRouter(
ProductTypesRouter, "producttypes", lookup="product_type"
)
ProductTypesFieldRouter.register(
r"fields", ProductTypeFieldViewSet, basename="producttype-field"
)

ProductTypesRouter.register("categories", CategoryViewSet, basename="category")

CategoriesQuestionRouter = NestedSimpleRouter(
ProductTypesRouter, "categories", lookup="category"
)
CategoriesQuestionRouter.register(
r"questions", CategoryQuestionViewSet, basename="category-question"
)

ProductTypesRouter.register("conditions", ConditionViewSet, basename="condition")
ProductTypesRouter.register("tags", TagViewSet, basename="tag")
ProductTypesRouter.register("tagtypes", TagTypeViewSet, basename="tagtype")

product_type_urlpatterns = [
path("", include(ProductTypesRouter.urls)),
path("", include(ProductTypesLinkRouter.urls)),
path("", include(ProductTypesPriceRouter.urls)),
path("", include(ProductTypesQuestionRouter.urls)),
path("", include(ProductTypesFieldRouter.urls)),
path("", include(CategoriesQuestionRouter.urls)),
]
Loading

0 comments on commit 478a09a

Please sign in to comment.