Fakultas Ilmu Komputer UI
Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ppl-fasilkom-ui
PPL Sosial
pilar
pilar-backend
Commits
8ea1766e
Commit
8ea1766e
authored
Apr 07, 2021
by
Azhar Difa Arnanda
💬
Browse files
Dev
parent
8e814adf
Changes
13
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
8ea1766e
...
...
@@ -2,4 +2,6 @@ __pycache__/
.python-version
.coverage
.env_var
static
\ No newline at end of file
static
env
.env
\ No newline at end of file
Dockerfile
0 → 100644
View file @
8ea1766e
FROM
python:3.8-slim-buster
ENV
PYTHONUNBUFFERED=1
WORKDIR
/code
COPY
requirements.txt /code/
RUN
pip3
install
-r
requirements.txt
COPY
. /code/
COPY
wait-for-it.sh /wait-for-it.sh
RUN
chmod
+x /wait-for-it.sh
\ No newline at end of file
README.md
100644 → 100755
View file @
8ea1766e
# Home Industry API
[

](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2020/ppl-c/diskominfo-depok-tpu-online/post-rpl-backend/commits/master)
[

](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2020/ppl-c/diskominfo-depok-tpu-online/post-rpl-backend/commits/master)
## Table of Contents
-
[
Environment Variables
](
#environment-variables
)
-
[
Local
](
#local
)
-
[
CI
](
#ci
)
-
[
Staging
](
#staging
)
-
[
Production
](
#production
)
-
[
Local Configuration
](
#local-configuration
)
-
[
Deployed API URLs
](
#deployed-api-urls
)
-
[
API Documentation
](
#api-documentation
)
## Environment Variables
### Local
Key | Required | Example
--- | --- | ---
`DATABASE_HOST`
| yes |
`127.0.0.1`
`DATABASE_NAME`
| yes |
`home_industry`
`DATABASE_PASSWORD`
| yes |
`postgres`
`DATABASE_PORT`
| yes |
`5432`
`DATABASE_USER`
| yes |
`postgres`
`DEBUG`
| no |
`True`
`DJANGO_SETTINGS_MODULE`
| yes |
`home_industry.settings.local`
`SECRET_KEY`
| yes |
`7&s33ax$lxxzti1)0y=8#tu!$7bdy)p$1@kn06tp&8x8i9#h2u`
### CI
Key | Required | Example
--- | --- | ---
`DJANGO_SETTINGS_MODULE`
| yes |
`home_industry.settings.ci`
`SECRET_KEY`
| yes |
`7&s33ax$lxxzti1)0y=8#tu!$7bdy)p$1@kn06tp&8x8i9#h2u`
### Staging
Key | Required | Example
--- | --- | ---
`AWS_ACCESS_KEY_ID`
| yes |
`AKIAIOSFODNN7EXAMPLE`
`AWS_REGION_NAME`
| yes |
`ap-southeast-1`
`AWS_SECRET_ACCESS_KEY`
| yes |
`wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`
`AWS_STORAGE_BUCKET_NAME`
| yes |
`homeindustry-api`
`DATABASE_URL`
| yes |
`postgres://postgres:postgres@ec2-117-21-174-214.compute-1.amazonaws.com:5432/home_industry`
`DEBUG`
| no |
`True`
`DJANGO_SETTINGS_MODULE`
| yes |
`home_industry.settings.staging`
`HOME_INDUSTRY_ADMIN_SITE_URL`
| no |
`https://homeindustry.com/admin/`
`HOME_INDUSTRY_ADMIN_SITE_USER_PATH`
| no |
`users/`
`HOME_INDUSTRY_ADMIN_SITE_PRODUCT_PATH`
| no |
`products/`
`HOME_INDUSTRY_ADMIN_SITE_TRANSACTION_PATH`
| no |
`transactions/`
`HOME_INDUSTRY_ADMIN_SITE_PROGRAM_PATH`
| no |
`programs/`
`HOME_INDUSTRY_ADMIN_SITE_PROGRAM_DONATION_PATH`
| no |
`program-donations/`
`SECRET_KEY`
| yes |
`7&s33ax$lxxzti1)0y=8#tu!$7bdy)p$1@kn06tp&8x8i9#h2u`
### Production
Key | Required | Example
--- | --- | ---
`AWS_ACCESS_KEY_ID`
| yes |
`AKIAIOSFODNN7EXAMPLE`
`AWS_REGION_NAME`
| yes |
`ap-southeast-1`
`AWS_SECRET_ACCESS_KEY`
| yes |
`wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`
`AWS_STORAGE_BUCKET_NAME`
| yes |
`homeindustry-api`
`DATABASE_HOST`
| yes |
`127.0.0.1`
`DATABASE_NAME`
| yes |
`home_industry`
`DATABASE_PASSWORD`
| yes |
`postgres`
`DATABASE_PORT`
| yes |
`5432`
`DATABASE_USER`
| yes |
`postgres`
`DJANGO_SETTINGS_MODULE`
| yes |
`home_industry.settings.production`
`HOME_INDUSTRY_ADMIN_SITE_URL`
| no |
`https://homeindustry.com/admin/`
`HOME_INDUSTRY_ADMIN_SITE_USER_PATH`
| no |
`users/`
`HOME_INDUSTRY_ADMIN_SITE_PRODUCT_PATH`
| no |
`products/`
`HOME_INDUSTRY_ADMIN_SITE_TRANSACTION_PATH`
| no |
`transactions/`
`HOME_INDUSTRY_ADMIN_SITE_PROGRAM_PATH`
| no |
`programs/`
`HOME_INDUSTRY_ADMIN_SITE_PROGRAM_DONATION_PATH`
| no |
`program-donations/`
`SECRET_KEY`
| yes |
`7&s33ax$lxxzti1)0y=8#tu!$7bdy)p$1@kn06tp&8x8i9#h2u`
## Local Configuration
-
Install Python 3.6 or higher and PostgreSQL
-
Create Python virtual environment
```
bash
$
cd
/path/to/project/directory
$
python3
-m
venv
env
$
source env
/bin/activate
$
pip3
install
-r
requirements.txt
```
-
Create PostgreSQL database
-
Set up environment variables (change as needed)
```
bash
$
export
DATABASE_HOST
=
'127.0.0.1'
$
export
DATABASE_NAME
=
'home_industry'
$
export
DATABASE_PASSWORD
=
'postgres'
$
export
DATABASE_PORT
=
'5432'
$
export
DATABASE_USER
=
'postgres'
$
export
DJANGO_SETTINGS_MODULE
=
'home_industry.settings.local'
$
export
SECRET_KEY
=
'7&s33ax$lxxzti1)0y=8#tu!$7bdy)p$1@kn06tp&8x8i9#h2u'
```
-
Migrate the database
```
bash
$
python3 manage.py migrate
```
-
Set up API configuration by modifying
`api_config.yaml`
-
Create or update the API configuration in database
```
bash
$
python3 manage.py createorupdateapiconfig
```
-
Create Superuser
```
bash
$
python3 manage.py createsuperuser
```
-
Run server
```
bash
$
python3 manage.py runserver
```
## Deployed API URLs
-
Staging:
[
https://industripilar-staging.herokuapp.com
](
https://industripilar-staging.herokuapp.com
)
-
Production:
[
https://api.industripilar.com
](
https://api.industripilar.com
)
## API Documentation
[
https://industripilar-staging.herokuapp.com/docs/
](
https://industripilar-staging.herokuapp.com/docs/
)
# Home Industry API
[

](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/sosial/pilar/pilar-backend/-/commits/dev)
[

](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/sosial/pilar/pilar-backend/-/commits/dev)
## Table of Contents
-
[
Environment Variables
](
#environment-variables
)
-
[
Local
](
#local
)
-
[
CI
](
#ci
)
-
[
Staging
](
#staging
)
-
[
Production
](
#production
)
-
[
Local Configuration
](
#local-configuration
)
-
[
Deployed API URLs
](
#deployed-api-urls
)
-
[
API Documentation
](
#api-documentation
)
## Environment Variables
### Local
Key | Required | Example
--- | --- | ---
`DATABASE_HOST`
| yes |
`127.0.0.1`
`DATABASE_NAME`
| yes |
`home_industry`
`DATABASE_PASSWORD`
| yes |
`postgres`
`DATABASE_PORT`
| yes |
`5432`
`DATABASE_USER`
| yes |
`postgres`
`DEBUG`
| no |
`True`
`DJANGO_SETTINGS_MODULE`
| yes |
`home_industry.settings.local`
`SECRET_KEY`
| yes |
`7&s33ax$lxxzti1)0y=8#tu!$7bdy)p$1@kn06tp&8x8i9#h2u`
### CI
Key | Required | Example
--- | --- | ---
`DJANGO_SETTINGS_MODULE`
| yes |
`home_industry.settings.ci`
`SECRET_KEY`
| yes |
`7&s33ax$lxxzti1)0y=8#tu!$7bdy)p$1@kn06tp&8x8i9#h2u`
### Staging
Key | Required | Example
--- | --- | ---
`AWS_ACCESS_KEY_ID`
| yes |
`AKIAIOSFODNN7EXAMPLE`
`AWS_REGION_NAME`
| yes |
`ap-southeast-1`
`AWS_SECRET_ACCESS_KEY`
| yes |
`wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`
`AWS_STORAGE_BUCKET_NAME`
| yes |
`homeindustry-api`
`DATABASE_URL`
| yes |
`postgres://postgres:postgres@ec2-117-21-174-214.compute-1.amazonaws.com:5432/home_industry`
`DEBUG`
| no |
`True`
`DJANGO_SETTINGS_MODULE`
| yes |
`home_industry.settings.staging`
`HOME_INDUSTRY_ADMIN_SITE_URL`
| no |
`https://homeindustry.com/admin/`
`HOME_INDUSTRY_ADMIN_SITE_USER_PATH`
| no |
`users/`
`HOME_INDUSTRY_ADMIN_SITE_PRODUCT_PATH`
| no |
`products/`
`HOME_INDUSTRY_ADMIN_SITE_TRANSACTION_PATH`
| no |
`transactions/`
`HOME_INDUSTRY_ADMIN_SITE_PROGRAM_PATH`
| no |
`programs/`
`HOME_INDUSTRY_ADMIN_SITE_PROGRAM_DONATION_PATH`
| no |
`program-donations/`
`SECRET_KEY`
| yes |
`7&s33ax$lxxzti1)0y=8#tu!$7bdy)p$1@kn06tp&8x8i9#h2u`
### Production
Key | Required | Example
--- | --- | ---
`AWS_ACCESS_KEY_ID`
| yes |
`AKIAIOSFODNN7EXAMPLE`
`AWS_REGION_NAME`
| yes |
`ap-southeast-1`
`AWS_SECRET_ACCESS_KEY`
| yes |
`wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`
`AWS_STORAGE_BUCKET_NAME`
| yes |
`homeindustry-api`
`DATABASE_HOST`
| yes |
`127.0.0.1`
`DATABASE_NAME`
| yes |
`home_industry`
`DATABASE_PASSWORD`
| yes |
`postgres`
`DATABASE_PORT`
| yes |
`5432`
`DATABASE_USER`
| yes |
`postgres`
`DJANGO_SETTINGS_MODULE`
| yes |
`home_industry.settings.production`
`HOME_INDUSTRY_ADMIN_SITE_URL`
| no |
`https://homeindustry.com/admin/`
`HOME_INDUSTRY_ADMIN_SITE_USER_PATH`
| no |
`users/`
`HOME_INDUSTRY_ADMIN_SITE_PRODUCT_PATH`
| no |
`products/`
`HOME_INDUSTRY_ADMIN_SITE_TRANSACTION_PATH`
| no |
`transactions/`
`HOME_INDUSTRY_ADMIN_SITE_PROGRAM_PATH`
| no |
`programs/`
`HOME_INDUSTRY_ADMIN_SITE_PROGRAM_DONATION_PATH`
| no |
`program-donations/`
`SECRET_KEY`
| yes |
`7&s33ax$lxxzti1)0y=8#tu!$7bdy)p$1@kn06tp&8x8i9#h2u`
## Local Configuration
-
Create environment variables in root folder (change as needed)
Filename:
`.env`
```
bash
DATABASE_HOST
=
db
DATABASE_NAME
=
home_industry
DATABASE_PASSWORD
=
postgres
DATABASE_PORT
=
5432
DATABASE_USER
=
postgres
DJANGO_SETTINGS_MODULE
=
home_industry.settings.local
SECRET_KEY
=
7&s33ax
$lxxzti1
)
0y
=
8#tu!
$7bdy
)
p
$1
@kn06tp&8x8i9#h2u
ALLOWED_HOST
=
0.0.0.0
```
-
Change
`wait-for-it.sh`
permission
```
bash
$
chmod
+x wait-for-it.sh
```
-
Run docker-compose
```
bash
$
sudo
docker-compose up
```
-
In another terminal, check running container
```
bash
$
docker ps
```
-
Run collectstatic
```
bash
$
docker
exec
-it
<web-container-id> python manage.py collectstatic
--noinput
```
-
Create superuser
```
bash
$
docker
exec
-it
<web-container-id> python manage.py createsuperuser
```
-
Create or update API configuration in database
```
bash
$
docker
exec
-it
<web-container-id> python manage.py createorupdateapiconfig
```
-
Generate dummy data from seeders for database
```
bash
$
docker
exec
-it
<web-container-id> python manage.py createdummydata
```
-
Access database
```
bash
$
docker
exec
-it
<postgres-container-id> psql
-U
postgres
-d
home_industry
-h
db
```
## Deployed API URLs
-
Development:
[
https://pilar-be-dev.cs.ui.ac.id
](
https://pilar-be-dev.cs.ui.ac.id
)
-
Staging:
[
https://pilar-be-staging.cs.ui.ac.id
](
https://pilar-be-staging.cs.ui.ac.id
)
-
Production:
[
https://pilar-be.cs.ui.ac.id
](
https://pilar-be.cs.ui.ac.id
)
## API Documentation
[
https://pilar-be-dev.cs.ui.ac.id/docs/
](
https://pilar-be-dev.cs.ui.ac.id/docs/
)
api/management/commands/createdummydata.py
0 → 100644
View file @
8ea1766e
from
django.core.management
import
base
from
api
import
models
from
api
import
seeds
class
Command
(
base
.
BaseCommand
):
def
handle
(
self
,
*
args
,
**
kwargs
):
user
,
status
=
models
.
User
.
objects
.
get_or_create
(
**
seeds
.
USER_DATA
)
bank_account_transfer_destination
,
status
=
models
.
BankAccountTransferDestination
.
objects
.
get_or_create
(
**
seeds
.
BANK_ACCOUNT_TRANSFER_DESTINATION
)
category
,
status
=
models
.
Category
.
objects
.
get_or_create
(
**
seeds
.
CATEGORY_DATA
)
subcategory
,
status
=
models
.
Subcategory
.
objects
.
get_or_create
(
**
dict
(
seeds
.
SUBCATEGORY_DATA
,
category
=
category
))
product
,
status
=
models
.
Product
.
objects
.
get_or_create
(
**
dict
(
seeds
.
PRODUCT_DATA
,
subcategory
=
subcategory
))
transaction
,
status
=
models
.
Transaction
.
objects
.
get_or_create
(
**
dict
(
seeds
.
TRANSACTION_DATA
,
user
=
user
))
transaction_item
,
status
=
models
.
TransactionItem
.
objects
.
get_or_create
(
**
dict
(
seeds
.
TRANSACTION_ITEM_DATA
,
transaction
=
transaction
,
product
=
product
))
program
,
status
=
models
.
Program
.
objects
.
get_or_create
(
**
seeds
.
PROGRAM_DATA
)
program_donation_pck
,
status
=
models
.
ProgramDonation
.
objects
.
get_or_create
(
**
dict
(
seeds
.
PROGRAM_DONATION_CASH_DATA
,
user
=
user
,
program
=
program
))
program_donation_dlv
,
status
=
models
.
ProgramDonation
.
objects
.
get_or_create
(
**
dict
(
seeds
.
PROGRAM_DONATION_CASH_DATA
,
user
=
user
,
program
=
program
))
batch
,
status
=
models
.
Batch
.
objects
.
get_or_create
(
**
seeds
.
BATCH_DATA
)
api/migrations/0003_product_unit.py
0 → 100644
View file @
8ea1766e
# Generated by Django 3.0.7 on 2021-03-27 05:42
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'api'
,
'0002_auto_20201229_1028'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'product'
,
name
=
'unit'
,
field
=
models
.
CharField
(
default
=
'buah'
,
max_length
=
200
,
verbose_name
=
'unit'
),
),
]
api/models.py
View file @
8ea1766e
...
...
@@ -164,6 +164,7 @@ class Product(db_models.Model):
validators
=
[
validators
.
MinValueValidator
(
decimal
.
Decimal
(
'0.01'
))],
verbose_name
=
_
(
'total profit'
)
)
unit
=
db_models
.
CharField
(
default
=
'buah'
,
max_length
=
200
,
verbose_name
=
_
(
'unit'
))
class
Meta
:
ordering
=
[
'subcategory'
,
'name'
,
'code'
,
'id'
]
verbose_name
=
_
(
'product'
)
...
...
api/seeds.py
View file @
8ea1766e
...
...
@@ -35,7 +35,8 @@ PRODUCT_DATA = {
'description'
:
'Dummy description.'
,
'price'
:
'2000'
,
'stock'
:
10
,
'modal'
:
'1000'
,
'modal'
:
'1000'
,
'unit'
:
'kg'
,
}
TRANSACTION_DATA
=
{
...
...
api/serializers.py
View file @
8ea1766e
...
...
@@ -264,7 +264,8 @@ class ProductSerializer(serializers.ModelSerializer):
'modal'
,
'profit'
,
'image'
,
'total_profit'
'total_profit'
,
'unit'
]
model
=
models
.
Product
read_only_fields
=
[
'id'
,
'code'
]
...
...
api/tests.py
View file @
8ea1766e
import
decimal
from
os
import
name
import
tempfile
from
unittest
import
mock
import
datetime
...
...
@@ -1169,6 +1170,7 @@ class ProductTest(rest_framework_test.APITestCase):
def
test_create_product_success
(
self
):
data
=
seeds
.
PRODUCT_DATA
data
[
'subcategory'
]
=
self
.
subcategory
.
id
data
[
'unit'
]
=
'kg'
response
=
request
(
'POST'
,
...
...
@@ -1180,10 +1182,12 @@ class ProductTest(rest_framework_test.APITestCase):
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
self
.
assertEqual
(
models
.
Product
.
objects
.
count
(),
1
)
self
.
assertEqual
(
models
.
Product
.
objects
.
get
(
id
=
response
.
data
[
'id'
]).
name
,
data
[
'name'
])
self
.
assertEqual
(
models
.
Product
.
objects
.
get
(
id
=
response
.
data
[
'id'
]).
unit
,
data
[
'unit'
])
def
test_create_product_fail
(
self
):
data
=
dict
(
seeds
.
PRODUCT_DATA
,
subcategory
=
self
.
subcategory
.
id
)
data
[
'name'
]
=
None
data
[
'unit'
]
=
None
response
=
request
(
'POST'
,
'product-list'
,
...
...
@@ -1200,7 +1204,8 @@ class ProductTest(rest_framework_test.APITestCase):
data
=
{
'name'
:
'Dummy'
,
'price'
:
'4000'
,
'modal'
:
'2000'
'modal'
:
'2000'
,
'unit'
:
'gram'
}
response
=
request
(
'PATCH'
,
...
...
@@ -1212,6 +1217,7 @@ class ProductTest(rest_framework_test.APITestCase):
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
models
.
Product
.
objects
.
get
(
id
=
product
.
id
).
profit
,
2000
)
self
.
assertEqual
(
models
.
Product
.
objects
.
get
(
id
=
product
.
id
).
name
,
data
[
'name'
])
self
.
assertEqual
(
models
.
Product
.
objects
.
get
(
id
=
product
.
id
).
unit
,
data
[
'unit'
])
data
=
dict
(
seeds
.
PRODUCT_DATA
,
subcategory
=
self
.
subcategory
.
id
)
response
=
request
(
'PUT'
,
...
...
@@ -1229,6 +1235,7 @@ class ProductTest(rest_framework_test.APITestCase):
))
data
=
{
'name'
:
''
,
'unit'
:
''
}
response
=
request
(
'PATCH'
,
...
...
@@ -1239,7 +1246,6 @@ class ProductTest(rest_framework_test.APITestCase):
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_400_BAD_REQUEST
)
class
ShoppingCartTest
(
rest_framework_test
.
APITestCase
):
def
setUp
(
self
):
self
.
superuser
=
models
.
User
.
objects
.
create_superuser
(
**
seeds
.
SUPERUSER_DATA
)
...
...
@@ -1629,6 +1635,21 @@ class ProgramDonationTest(rest_framework_test.APITestCase):
url_args
=
[
program_donation
.
id
]
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
def
test_delete_by_program
(
self
):
program
=
models
.
Program
.
objects
.
create
(
**
seeds
.
PROGRAM_DATA
)
donation
=
models
.
ProgramDonation
.
objects
.
create
(
**
dict
(
seeds
.
PROGRAM_DONATION_CASH_DATA
,
user
=
self
.
user
,
program
=
program
))
response
=
request
(
'DELETE'
,
'donation-by-program'
,
http_authorization
=
self
.
superuser_http_authorization
,
url_args
=
[
program
.
id
]
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_204_NO_CONTENT
)
self
.
assertEqual
(
models
.
ProgramDonation
.
objects
.
count
(),
0
)
class
ChoicesViewsTest
(
rest_framework_test
.
APITestCase
):
...
...
api/urls.py
View file @
8ea1766e
...
...
@@ -30,6 +30,7 @@ urlpatterns = [
name
=
'cart-cancel-transaction'
),
urls
.
path
(
'donation/create/'
,
api_views
.
DonationCreate
.
as_view
(),
name
=
'donation-create'
),
urls
.
path
(
'donation/delete-by-p/<str:pid>'
,
api_views
.
delete_donation_by_program
,
name
=
'donation-by-program'
),
urls
.
path
(
'donation/reupload-proof-of-bank-transfer/'
,
api_views
.
DonationReuploadProofOfBankTransfer
.
as_view
(),
...
...
api/views.py
View file @
8ea1766e
from
django
import
http
,
shortcuts
from
django.contrib
import
auth
from
django.db
import
transaction
as
db_transaction
,
utils
as
db_utils
...
...
@@ -12,7 +11,8 @@ from rest_framework import (
permissions
as
rest_framework_permissions
,
response
,
status
,
views
as
rest_framework_views
)
from
rest_framework.authtoken
import
serializers
as
authtoken_serializers
from
rest_framework.decorators
import
api_view
from
django.views.decorators.csrf
import
csrf_exempt
from
api
import
(
constants
,
exceptions
as
api_exceptions
,
filters
as
api_filters
,
models
,
paginations
,
permissions
as
api_permissions
,
reports_writer
,
schemas
,
serializers
as
api_serializers
,
...
...
@@ -626,6 +626,11 @@ class ProductList(generics.ListCreateAPIView):
def
post
(
self
,
request
,
_format
=
None
):
serializer
=
self
.
get_serializer
(
data
=
request
.
data
)
serializer
.
is_valid
(
raise_exception
=
True
)
validated_image
=
None
try
:
validated_image
=
serializer
.
validated_data
[
'image'
]
except
KeyError
:
pass
product
=
models
.
Product
.
objects
.
create
(
name
=
serializer
.
validated_data
[
'name'
],
description
=
serializer
.
validated_data
[
'description'
],
...
...
@@ -633,7 +638,9 @@ class ProductList(generics.ListCreateAPIView):
stock
=
serializer
.
validated_data
[
'stock'
],
modal
=
serializer
.
validated_data
[
'modal'
],
subcategory
=
models
.
Subcategory
.
objects
.
get
(
name
=
serializer
.
validated_data
[
'subcategory'
]),
total_profit
=
0
total_profit
=
0
,
unit
=
serializer
.
validated_data
[
'unit'
],
image
=
validated_image
)
product
.
profit
=
(
product
.
price
-
product
.
modal
)
product
.
save
()
...
...
@@ -643,6 +650,7 @@ class ProductList(generics.ListCreateAPIView):
)
class
ProductDetail
(
generics
.
RetrieveUpdateDestroyAPIView
):
permission_classes
=
[
api_permissions
.
IsAdminUserOrReadOnly
,
...
...
@@ -836,6 +844,14 @@ class ProgramDonationList(generics.ListAPIView):
return
queryset
.
filter
(
user
=
self
.
request
.
user
)
return
queryset
@
api_view
([
'DELETE'
])
@
csrf_exempt
def
delete_donation_by_program
(
request
,
pid
):
if
((
request
.
user
)
and
(
request
.
user
.
is_staff
)):
program
=
models
.
Program
.
objects
.
get
(
id
=
pid
)
donation
=
models
.
ProgramDonation
.
objects
.
filter
(
program
=
program
)
donation
.
delete
()
return
response
.
Response
(
status
=
status
.
HTTP_204_NO_CONTENT
)
class
ProgramDonationListCSH
(
generics
.
ListAPIView
):
filter_backends
=
[
...
...
docker-compose.yml
0 → 100644
View file @
8ea1766e
version
:
"
3.9"
services
:
db
:
image
:
postgres:13
environment
:
-
POSTGRES_DB=home_industry
-
POSTGRES_USER=postgres
-
POSTGRES_PASSWORD=postgres
-
POSTGRES_HOST=127.0.0.1
web
:
build
:
.
command
:
bash -c "
python manage.py makemigrations &&
python manage.py migrate &&
/wait-for-it.sh db:5432 -- python manage.py runserver 0.0.0.0:8000"
volumes
:
-
./wait-for-it.sh:/wait-for-it.sh
-
.:/code
ports
:
-
"
8000:8000"
depends_on
:
-
db
env_file
:
.env
\ No newline at end of file
wait-for-it.sh
0 → 100755
View file @
8ea1766e
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are available
WAITFORIT_cmdname
=
${
0
##*/
}
echoerr
()
{
if
[[
$WAITFORIT_QUIET
-ne
1
]]
;
then
echo
"
$@
"
1>&2
;
fi
}
usage
()
{
cat
<<
USAGE
>&2
Usage:
$WAITFORIT_cmdname
host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit
1
}
wait_for
()
{
if
[[
$WAITFORIT_TIMEOUT
-gt
0
]]
;
then
echoerr
"
$WAITFORIT_cmdname
: waiting
$WAITFORIT_TIMEOUT
seconds for
$WAITFORIT_HOST
:
$WAITFORIT_PORT
"
else
echoerr
"
$WAITFORIT_cmdname
: waiting for
$WAITFORIT_HOST
:
$WAITFORIT_PORT
without a timeout"
fi
WAITFORIT_start_ts
=
$(
date
+%s
)
while
:
do
if
[[
$WAITFORIT_ISBUSY
-eq
1
]]
;
then
nc
-z
$WAITFORIT_HOST
$WAITFORIT_PORT
WAITFORIT_result
=
$?
else
(
echo
-n
>
/dev/tcp/
$WAITFORIT_HOST
/
$WAITFORIT_PORT
)
>
/dev/null 2>&1
WAITFORIT_result
=
$?
fi
if
[[
$WAITFORIT_result
-eq
0
]]
;
then
WAITFORIT_end_ts
=
$(
date
+%s
)
echoerr
"
$WAITFORIT_cmdname
:
$WAITFORIT_HOST
:
$WAITFORIT_PORT
is available after
$((
WAITFORIT_end_ts
-
WAITFORIT_start_ts
))
seconds"
break
fi
sleep
1
done
return
$WAITFORIT_result
}
wait_for_wrapper
()
{
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
if
[[
$WAITFORIT_QUIET
-eq
1
]]
;
then
timeout
$WAITFORIT_BUSYTIMEFLAG
$WAITFORIT_TIMEOUT
$0
--quiet
--child
--host
=
$WAITFORIT_HOST
--port
=
$WAITFORIT_PORT
--timeout
=
$WAITFORIT_TIMEOUT
&
else
timeout
$WAITFORIT_BUSYTIMEFLAG
$WAITFORIT_TIMEOUT
$0
--child
--host
=
$WAITFORIT_HOST
--port
=
$WAITFORIT_PORT
--timeout
=
$WAITFORIT_TIMEOUT
&
fi
WAITFORIT_PID
=
$!
trap
"kill -INT -
$WAITFORIT_PID
"
INT
wait
$WAITFORIT_PID
WAITFORIT_RESULT
=
$?
if
[[
$WAITFORIT_RESULT
-ne
0
]]
;
then
echoerr
"
$WAITFORIT_cmdname
: timeout occurred after waiting
$WAITFORIT_TIMEOUT
seconds for
$WAITFORIT_HOST
:
$WAITFORIT_PORT
"
fi
return
$WAITFORIT_RESULT
}
# process arguments
while
[[
$#
-gt
0
]]
do
case
"
$1
"
in
*
:
*
)
WAITFORIT_hostport
=(
${
1
//
:/
}
)
WAITFORIT_HOST
=
${
WAITFORIT_hostport
[0]
}
WAITFORIT_PORT
=
${
WAITFORIT_hostport
[1]
}
shift
1
;;
--child
)