summaryrefslogtreecommitdiff
path: root/indoteknik_api/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'indoteknik_api/controllers')
-rw-r--r--indoteknik_api/controllers/__init__.py3
-rw-r--r--indoteknik_api/controllers/api_v1/__init__.py5
-rw-r--r--indoteknik_api/controllers/api_v1/category.py37
-rw-r--r--indoteknik_api/controllers/api_v1/flash_sale.py57
-rw-r--r--indoteknik_api/controllers/api_v1/manufacture.py37
-rw-r--r--indoteknik_api/controllers/api_v1/product.py83
-rw-r--r--indoteknik_api/controllers/api_v1/sale_order.py (renamed from indoteknik_api/controllers/sale_order_controller.py)10
-rw-r--r--indoteknik_api/controllers/controller.py33
-rw-r--r--indoteknik_api/controllers/product_controller.py151
9 files changed, 251 insertions, 165 deletions
diff --git a/indoteknik_api/controllers/__init__.py b/indoteknik_api/controllers/__init__.py
index 4c317fdc..30664b92 100644
--- a/indoteknik_api/controllers/__init__.py
+++ b/indoteknik_api/controllers/__init__.py
@@ -1,3 +1,2 @@
from . import controller
-from . import product_controller
-from . import sale_order_controller
+from . import api_v1 \ No newline at end of file
diff --git a/indoteknik_api/controllers/api_v1/__init__.py b/indoteknik_api/controllers/api_v1/__init__.py
new file mode 100644
index 00000000..b569a012
--- /dev/null
+++ b/indoteknik_api/controllers/api_v1/__init__.py
@@ -0,0 +1,5 @@
+from . import category
+from . import flash_sale
+from . import manufacture
+from . import product
+from . import sale_order \ No newline at end of file
diff --git a/indoteknik_api/controllers/api_v1/category.py b/indoteknik_api/controllers/api_v1/category.py
new file mode 100644
index 00000000..585e3eda
--- /dev/null
+++ b/indoteknik_api/controllers/api_v1/category.py
@@ -0,0 +1,37 @@
+from .. import controller
+from odoo import http
+from odoo.http import request
+
+
+class Category(controller.Controller):
+ prefix = '/api/v1/'
+
+ @http.route(prefix + 'category/page/<page>', auth='public', methods=['GET'])
+ def get_category(self, **kw):
+ if not self.authenticate():
+ return self.response(code=401, description='Unauthorized')
+
+ category_ids = []
+ page = kw.get('page')
+ if page == 'flash-sale':
+ active_flash_sale = request.env['product.pricelist'].get_active_flash_sale()
+ if active_flash_sale:
+ category_ids = [x.id for item in active_flash_sale.item_ids for x in item.product_id.public_categ_ids]
+ elif page == 'manufacture':
+ manufacture_id = kw.get('manufacture_id')
+ if not manufacture_id:
+ return self.response(code=400, description='manufacture_id is required')
+ product_variants = request.env['product.product'].search([('x_manufacture', '=', int(manufacture_id))])
+ category_ids = [x.id for variant in product_variants for x in variant.public_categ_ids]
+ else:
+ return self.response(code=400, description='page possible value is flash-sale, manufacture')
+
+ categories = request.env['product.public.category'].search([('id', 'in', category_ids)])
+ data = []
+ for category in categories:
+ data.append({
+ 'id': category.id,
+ 'name': category.name
+ })
+ return self.response(data)
+ \ No newline at end of file
diff --git a/indoteknik_api/controllers/api_v1/flash_sale.py b/indoteknik_api/controllers/api_v1/flash_sale.py
new file mode 100644
index 00000000..7f0166ee
--- /dev/null
+++ b/indoteknik_api/controllers/api_v1/flash_sale.py
@@ -0,0 +1,57 @@
+from datetime import datetime
+import logging
+from .. import controller
+from odoo import http
+from odoo.http import request
+
+_logger = logging.getLogger(__name__)
+
+
+class FlashSale(controller.Controller):
+ prefix = '/api/v1/'
+
+ @http.route(prefix + 'flash_sale', auth='public', methods=['GET'])
+ def get_flash_sale(self, **kw):
+ try:
+ if not self.authenticate():
+ return self.response(code=401, description='Unauthorized')
+ base_url = request.env['ir.config_parameter'].get_param('web.base.url')
+ active_flash_sale = request.env['product.pricelist'].get_active_flash_sale()
+ data = {}
+ if active_flash_sale:
+ flash_sale_product_variant_ids = [x.product_id.id for x in active_flash_sale.item_ids]
+ query = [('id', 'in', flash_sale_product_variant_ids)]
+
+ product_name = kw.get('product_name')
+ if product_name:
+ product_name = '%' + product_name.replace(' ', '%') + '%'
+ query += ['|', ('name', 'ilike', product_name), ('default_code', 'ilike', product_name)]
+
+ manufactures = kw.get('manufactures')
+ if manufactures:
+ query += [('x_manufacture', 'in', [int(x) for x in manufactures.split(',')])]
+
+ categories = kw.get('categories')
+ if categories:
+ query += [('public_categ_ids', 'child_of', [int(x) for x in categories.split(',')])]
+
+ product_variants = request.env['product.product'].search(query)
+ product_variant_ids = [x.id for x in product_variants]
+
+ query = [('product_variant_ids', 'in', product_variant_ids)]
+ product_templates = self.search_filter('product.template', kw, query)
+ data = {
+ 'flash_sale': {
+ 'banner': base_url + 'api/image/product.pricelist/banner/' + str(active_flash_sale.id) if active_flash_sale.banner else '',
+ 'duration': round((active_flash_sale.end_date - datetime.now()).total_seconds()),
+ 'product_total': request.env['product.template'].search_count(query),
+ 'products': [request.env['product.template'].api_single_response(x) for x in product_templates]
+ }
+ }
+ return self.response(data)
+ else:
+ return self.response(code=404, description='Data not found')
+ except Exception as e:
+ _logger.info(self.prefix_url + '/flash_sale: ' + str(e))
+ return self.response(code=500, description='Internal server error')
+ \ No newline at end of file
diff --git a/indoteknik_api/controllers/api_v1/manufacture.py b/indoteknik_api/controllers/api_v1/manufacture.py
new file mode 100644
index 00000000..ba2e3be9
--- /dev/null
+++ b/indoteknik_api/controllers/api_v1/manufacture.py
@@ -0,0 +1,37 @@
+from .. import controller
+from odoo import http
+from odoo.http import request
+
+
+class Manufacture(controller.Controller):
+ prefix = '/api/v1/'
+
+ @http.route(prefix + 'manufacture/page/<page>', auth='public', methods=['GET'])
+ def get_manufacture(self, **kw):
+ if not self.authenticate():
+ return self.response(code=401, description='Unauthorized')
+
+ manufacture_ids = []
+ page = kw.get('page')
+ if page == 'flash-sale':
+ active_flash_sale = request.env['product.pricelist'].get_active_flash_sale()
+ if active_flash_sale:
+ manufacture_ids = [x.product_id.x_manufacture.id for x in active_flash_sale.item_ids]
+ elif page == 'category':
+ category_id = kw.get('category_id')
+ if not category_id:
+ return self.response(code=400, description='category_id is required')
+ product_variants = request.env['product.product'].search([('public_categ_ids', '=', int(category_id))])
+ manufacture_ids = [x.x_manufacture.id for x in product_variants]
+ else:
+ return self.response(code=400, description='page possible value is flash-sale, category')
+
+ manufactures = request.env['x_manufactures'].search([('id', 'in', manufacture_ids)])
+ data = []
+ for manufacture in manufactures:
+ data.append({
+ 'id': manufacture.id,
+ 'name': manufacture.x_name
+ })
+ return self.response(data)
+ \ No newline at end of file
diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py
new file mode 100644
index 00000000..493677fd
--- /dev/null
+++ b/indoteknik_api/controllers/api_v1/product.py
@@ -0,0 +1,83 @@
+from .. import controller
+from odoo import http
+from odoo.http import request
+
+
+class Product(controller.Controller):
+ prefix = '/api/v1/'
+
+ @http.route(prefix + 'product', auth='public', methods=['GET'])
+ def get_product(self, **kw):
+ if not self.authenticate():
+ return self.response(code=401, description='Unauthorized')
+
+ name = kw.get('name')
+ manufactures = kw.get('manufactures')
+ categories = kw.get('categories')
+
+ require_betweens = ['name', 'manufactures', 'categories']
+ is_fulfill = False
+ for required in require_betweens:
+ if kw.get(required):
+ is_fulfill = True
+
+ # If not fulfill in require_between
+ if not is_fulfill:
+ return self.response(code=400, description='name or manufactures or categories is required')
+
+ query = [('sale_ok', '=', True)]
+
+ if name:
+ name = '%' + name.replace(' ', '%') + '%'
+ query += [
+ '|',
+ ('default_code', 'ilike', name),
+ ('name', 'ilike', name),
+ ]
+
+ if manufactures:
+ query.append(('x_manufacture', 'in', [int(x) for x in manufactures.split(',')]))
+
+ if categories:
+ query.append(('public_categ_ids', 'child_of', [int(x) for x in categories.split(',')]))
+
+ product_variants = request.env['product.product'].search(query)
+ product_variant_ids = [x.id for x in product_variants]
+
+ query = [('product_variant_ids', 'in', product_variant_ids)]
+ limit = int(kw.get('limit', 0))
+ offset = int(kw.get('offset', 0))
+ order = kw.get('order')
+
+ orders = ['product_rating desc']
+ if order != 'price-asc':
+ orders.append('web_price_sorting desc')
+ if order == 'price-asc':
+ orders.append('web_price_sorting asc')
+ elif order == 'latest':
+ orders.append('create_date desc')
+ orders = ','.join(orders)
+ product_templates = request.env['product.template'].search(query, limit=limit, offset=offset, order=orders)
+ data = {
+ 'product_total': request.env['product.template'].search_count(query),
+ 'products': [request.env['product.template'].api_single_response(x) for x in product_templates]
+ }
+ return self.response(data)
+
+ @http.route(prefix + 'product/<id>', auth='public', methods=['GET'])
+ def get_product_by_id(self, **kw):
+ if not self.authenticate():
+ return self.response(code=401, description='Unauthorized')
+
+ id = kw.get('id')
+ if not id:
+ return self.response(code=400, description='id is required')
+
+ data = []
+ id = [int(x) for x in id.split(',')]
+ product_templates = request.env['product.template'].search([('id', 'in', id)])
+ if product_templates:
+ data = [request.env['product.template'].api_single_response(x, with_detail=True) for x in product_templates]
+
+ return self.response(data)
+ \ No newline at end of file
diff --git a/indoteknik_api/controllers/sale_order_controller.py b/indoteknik_api/controllers/api_v1/sale_order.py
index 741d4bf8..99302a66 100644
--- a/indoteknik_api/controllers/sale_order_controller.py
+++ b/indoteknik_api/controllers/api_v1/sale_order.py
@@ -1,12 +1,12 @@
-from . import controller
+from .. import controller
from odoo import http
from odoo.http import request
-class SaleOrderController(controller.Controller):
+class SaleOrder(controller.Controller):
@http.route('/api/sale_order/invoiced', auth='public', methods=['GET'])
def get_sale_order_invoiced_by_partner_id(self, **kw):
- self.authenticate(kw)
+ self.authenticate()
partner_id = kw.get('partner_id')
if not partner_id:
return self.response(code=400, description='Field partner_id is required')
@@ -25,7 +25,7 @@ class SaleOrderController(controller.Controller):
('invoice_status', '=', 'invoiced'),
('invoice_status', '=', 'to_invoice')
]
- sale_orders = self.search_with_api_params('sale.order', kw, default_domain)
+ sale_orders = self.search_filter('sale.order', kw, default_domain)
for sale_order in sale_orders:
pickings = []
for picking in sale_order.picking_ids:
@@ -71,7 +71,7 @@ class SaleOrderController(controller.Controller):
partner_child_ids = [v['id'] for v in partner_childs] + [int(partner_id)]
default_domain.append(('partner_id', 'in', partner_child_ids))
- sale_order = self.search_with_api_params('sale.order', kw, default_domain)
+ sale_order = self.search_filter('sale.order', kw, default_domain)
orders = []
for order in sale_order.order_line:
orders.append({
diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py
index fb5f1fce..c02f6b60 100644
--- a/indoteknik_api/controllers/controller.py
+++ b/indoteknik_api/controllers/controller.py
@@ -1,3 +1,4 @@
+from array import array
import datetime
import base64
import json
@@ -8,11 +9,29 @@ from pytz import timezone
class Controller(http.Controller):
- def authenticate(self, kw):
- db = kw.get('db')
- username = kw.get('username')
- password = kw.get('password')
- request.session.authenticate(db, username, password)
+ def authenticate(self):
+ try:
+ wsgienv = request.httprequest.environ
+ db = wsgienv['HTTP_DB']
+ username = wsgienv['HTTP_USERNAME']
+ password = wsgienv['HTTP_PASSWORD']
+ request.session.authenticate(db, username, password)
+ return True
+ except:
+ return False
+
+ def validate_request(self, rules: dict, kw: dict):
+ validation = {
+ 'status': True,
+ 'reason': []
+ }
+ for key in rules:
+ values = rules[key]
+ for value in values:
+ if value == 'required' and not kw.get(key):
+ validation['status'] = False
+ validation['reason'].append(key + ' is ' + value)
+ return validation
def time_to_str(self, object, format):
time = ''
@@ -33,13 +52,13 @@ class Controller(http.Controller):
response = json.dumps(response)
return request.make_response(response, [('Content-Type', 'application/json')])
- def search_with_api_params(self, model: str, kw, domain=[]):
+ def search_filter(self, model: str, kw: dict, query: array = []):
""" To search data by default API Params if exist """
limit = kw.get('limit', 0)
offset = kw.get('offset', 0)
order = kw.get('order', '')
- return request.env[model].search(domain, limit=int(limit), offset=int(offset), order=order)
+ return request.env[model].search(query, limit=int(limit), offset=int(offset), order=order)
@http.route('/api/image/<model>/<field>/<id>', auth='public', methods=['GET'])
def get_image(self, model, field, id):
diff --git a/indoteknik_api/controllers/product_controller.py b/indoteknik_api/controllers/product_controller.py
deleted file mode 100644
index 6101952f..00000000
--- a/indoteknik_api/controllers/product_controller.py
+++ /dev/null
@@ -1,151 +0,0 @@
-from datetime import datetime
-import logging
-from . import controller
-from odoo import http
-from odoo.http import request
-
-_logger = logging.getLogger(__name__)
-
-
-class ProductController(controller.Controller):
- prefix_url = '/api/product'
-
- # TODO: separate function for get manufacture and promotion by product_id
- @http.route(prefix_url + '/search', auth='public', methods=['GET'])
- def search_product(self, **kw):
- self.authenticate(kw)
- base_url = request.env['ir.config_parameter'].sudo().get_param('web.base.url')
-
- query = kw.get('query')
- if not query:
- return self.response(code=400, description='Field query is required')
-
- query = '%' + query.replace(' ', '%') + '%'
- domain = [
- ('sale_ok', '=', True),
- '|',
- ('default_code', 'ilike', query),
- ('name', 'ilike', query)
- ]
-
- manufactures = kw.get('manufactures')
- if manufactures:
- manufactures = [int(x) for x in manufactures.split(',')]
- domain.append(('x_manufacture', 'in', manufactures))
-
- categories = kw.get('categories')
- if categories:
- categories = [int(x) for x in categories.split(',')]
- domain.append(('public_categ_ids', 'child_of', categories))
-
- product_variants = request.env['product.product'].search(domain)
- product_variant_ids = [x.id for x in product_variants]
-
- domain = [('product_variant_ids', 'in', product_variant_ids)]
- product_templates = self.search_with_api_params('product.template', kw, domain)
- data = {
- 'total_records': len(request.env['product.template'].search(domain)),
- 'products': []
- }
- for product_template in product_templates:
- discount_price = 0
- price = product_template.web_price
- if price > 0:
- if product_template.web_tax_id:
- if not product_template.web_tax_id.price_include:
- price += (price * product_template.web_tax_id.amount / 100)
- else:
- price += (price * 11 / 100)
-
- promotion = self.get_promotion_by_product(product_template)
- if len(promotion) > 0:
- discount_price = price - (price * promotion['discount_percentage'] / 100)
-
- manufacture = self.get_manufacture_by_product(product_template)
- stock = self.get_stock_by_product(product_template)
-
- # TODO: remove price and discount_price if old indoteknik not use
- data['products'].append({
- 'id': product_template.id,
- 'image': base_url + 'api/image/product.template/image_128/' + str(product_template.id) if product_template.image_128 else '',
- 'name': product_template.name,
- # 'lowest_price': request.env['product.pricelist'].get_lowest_product_variant_price(product_template.id, 4),
- 'price': price,
- 'discount_price': discount_price,
- 'total_variant': len(product_template.product_variant_ids),
- 'stock': stock,
- 'manufacture': manufacture,
- 'promotion': promotion,
- })
- return self.response(data)
-
- @http.route(prefix_url + '/flash_sale', auth='public', methods=['GET'])
- def get_flash_sale_product(self, **kw):
- try:
- self.authenticate(kw)
- base_url = request.env['ir.config_parameter'].sudo().get_param('web.base.url')
- product_pricelist_default = request.env['ir.config_parameter'].sudo().get_param('product.pricelist.default')
- active_flash_sale = request.env['product.pricelist'].get_active_flash_sale()
- data = {}
- if active_flash_sale:
- flash_sale = {
- 'banner': base_url + 'api/image/product.pricelist/banner/' + str(active_flash_sale.id) if active_flash_sale.banner else '',
- 'duration': round((active_flash_sale.end_date - datetime.now()).total_seconds()),
- 'products': []
- }
- product_pricelist_item = request.env['product.pricelist.item'].search([('pricelist_id', '=', active_flash_sale.id)])
- product_variant_ids = [x.product_id.id for x in product_pricelist_item]
- product_templates = self.search_with_api_params('product.template', kw, [('product_variant_ids', 'in', product_variant_ids)])
- for product in product_templates:
- flash_sale['products'].append({
- 'id': product.id,
- 'name': product.name,
- 'image': base_url + 'api/image/product.template/image_128/' + str(product.id) if product.image_128 else '',
- 'lowest_price': request.env['product.pricelist'].get_lowest_product_variant_price(product.id, int(product_pricelist_default)),
- 'stock': self.get_stock_by_product(product),
- 'total_variant': len(product.product_variant_ids),
- 'manufacture': self.get_manufacture_by_product(product),
- 'promotion': self.get_promotion_by_product(product),
- })
- data.update({'flash_sale': flash_sale})
- else:
- return self.response(code=404, description='Data not found')
- except Exception as e:
- _logger.info(self.prefix_url + '/flash_sale: ' + str(e))
- return self.response(code=500, description='Internal server error')
- return self.response(data)
-
- def get_stock_by_product(self, product_template: object):
- stock = 0
- for product_variant in product_template.product_variant_ids:
- stock += product_variant.qty_stock_vendor
- return stock
-
- def get_manufacture_by_product(self, product_template: object):
- manufacture = {}
- if product_template.x_manufacture:
- manufacture.update({
- 'id': product_template.x_manufacture.id,
- 'name': product_template.x_manufacture.x_name,
- })
- return manufacture
-
- def get_promotion_by_product(self, product_template: object):
- base_url = request.env['ir.config_parameter'].sudo().get_param('web.base.url')
- promotion = {}
- if product_template.x_manufacture:
- domain = [
- ('rule_products_domain', 'ilike', product_template.x_manufacture.x_name),
- ('active', '=', True)
- ]
- coupon_program = request.env['coupon.program'].search(domain, limit=1)
- if coupon_program:
- icon_1 = (base_url + 'api/image/coupon.program/x_studio_field_Ifopn/' + str(coupon_program.id)) if coupon_program.x_studio_field_Ifopn else ''
- icon_2 = (base_url + 'api/image/coupon.program/x_studio_field_2Ul77/' + str(coupon_program.id)) if coupon_program.x_studio_field_2Ul77 else ''
- promotion.update({
- 'name': coupon_program.name,
- 'discount_percentage': coupon_program.discount_percentage,
- 'icon_1': icon_1,
- 'icon_2': icon_2
- })
- return promotion \ No newline at end of file