diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2023-04-28 09:03:04 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2023-04-28 09:03:04 +0700 |
| commit | 57d55f545da0fc501a9828bb3ca2988f126b241a (patch) | |
| tree | 75b98126546eea20b90ca777b2887b4813946871 | |
| parent | 3592c254ca5baf4a0a769f500f9e28a9cbc272a7 (diff) | |
| parent | 6fa5de951abc02884eb37cdc6786c0f3d141ccc5 (diff) | |
Merge branch 'staging' into release
| -rw-r--r-- | indoteknik_api/controllers/api_v1/__init__.py | 1 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v1/flash_sale.py | 2 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v1/lead.py | 26 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v1/sale_order.py | 42 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v1/user.py | 73 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v2/product.py | 6 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v2/product_variant.py | 4 | ||||
| -rw-r--r-- | indoteknik_api/controllers/controller.py | 50 | ||||
| -rw-r--r-- | indoteknik_api/models/product_product.py | 53 | ||||
| -rw-r--r-- | indoteknik_api/models/product_template.py | 4 | ||||
| -rw-r--r-- | indoteknik_api/models/res_users.py | 17 | ||||
| -rw-r--r-- | indoteknik_api/models/sale_order.py | 4 | ||||
| -rw-r--r-- | indoteknik_custom/models/apache_solr.py | 5 |
13 files changed, 220 insertions, 67 deletions
diff --git a/indoteknik_api/controllers/api_v1/__init__.py b/indoteknik_api/controllers/api_v1/__init__.py index 682cb369..5d5f723b 100644 --- a/indoteknik_api/controllers/api_v1/__init__.py +++ b/indoteknik_api/controllers/api_v1/__init__.py @@ -7,6 +7,7 @@ from . import district from . import download from . import flash_sale from . import invoice +from . import lead from . import manufacture from . import page_content from . import partner diff --git a/indoteknik_api/controllers/api_v1/flash_sale.py b/indoteknik_api/controllers/api_v1/flash_sale.py index cad2cb61..a0aaa44e 100644 --- a/indoteknik_api/controllers/api_v1/flash_sale.py +++ b/indoteknik_api/controllers/api_v1/flash_sale.py @@ -10,7 +10,7 @@ _logger = logging.getLogger(__name__) class FlashSale(controller.Controller): prefix = '/api/v1/' - @http.route(prefix + 'flashsale/header', auth='public', methods=['GET']) + @http.route(prefix + 'flashsale/header', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def _get_flash_sale_header(self, **kw): try: diff --git a/indoteknik_api/controllers/api_v1/lead.py b/indoteknik_api/controllers/api_v1/lead.py new file mode 100644 index 00000000..df4f46bd --- /dev/null +++ b/indoteknik_api/controllers/api_v1/lead.py @@ -0,0 +1,26 @@ +from .. import controller +from odoo import http +from odoo.http import request + +class Lead(controller.Controller): + @http.route('/api/v1/lead', auth='public', methods=['POST', 'OPTIONS'], csrf=False) + @controller.Controller.must_authorized() + def create_lead(self, **kw): + params = self.get_request_params(kw, { + "name": ["required"], + "contact_name": [], + "email_from": [], + "phone": [], + "file_npwp": [], + "file_nib": [], + "file_tdp": [], + "file_siup": [], + "description": [] + }) + + if not params['valid']: + return self.response(code=400, description=params) + + lead = request.env['crm.lead'].create(params['value']) + + return self.response(True)
\ No newline at end of file diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index 76fbfddb..425dd296 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -53,6 +53,7 @@ class SaleOrder(controller.Controller): 'name': [], 'limit': ['default:0', 'number'], 'offset': ['default:0', 'number'], + 'context': [] }) limit = params['value']['limit'] offset = params['value']['offset'] @@ -61,6 +62,13 @@ class SaleOrder(controller.Controller): partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) domain = [('partner_id', 'in', partner_child_ids)] + + context = params['value']['context'] + if context == 'quotation': + domain += [('approval_status', '=', False)] + if not context: + domain += [('approval_status', '!=', False)] + if params['value']['name']: name = params['value']['name'].replace(' ', '%') domain += [ @@ -213,8 +221,11 @@ class SaleOrder(controller.Controller): @http.route(PREFIX_PARTNER + 'sale_order/checkout', auth='public', method=['POST', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized(private=True, private_key='partner_id') def create_partner_sale_order(self, **kw): - product_pricelist_default_discount_id = request.env['ir.config_parameter'].get_param('product.pricelist.default_discount_id') - product_pricelist_default_discount_id = int(product_pricelist_default_discount_id) + config = request.env['ir.config_parameter'] + product_pricelist_default_discount_id = int(config.get_param('product.pricelist.default_discount_id')) + product_pricelist_tier1 = int(config.get_param('product.pricelist.tier1')) + product_pricelist_tier2 = int(config.get_param('product.pricelist.tier2')) + product_pricelist_tier3 = int(config.get_param('product.pricelist.tier3')) params = self.get_request_params(kw, { 'partner_id': ['number'], @@ -232,7 +243,7 @@ class SaleOrder(controller.Controller): parameters = { 'warehouse_id': 8, 'carrier_id': 1, - 'sales_tax_id': 23, + 'sales_tax_id': 21, 'pricelist_id': product_pricelist_default_discount_id, 'payment_term_id': 26, 'team_id': 2, @@ -252,15 +263,36 @@ class SaleOrder(controller.Controller): sale_order = request.env['sale.order'].create([parameters]) order_line = json.loads(params['value']['order_line']) parameters = [] + + partner = request.env['res.partner'].browse(params['value']['partner_id']) + partner_pricelist = partner.property_product_pricelist for line in order_line: product = request.env['product.product'].search([('id', '=', line['product_id'])], limit=1) + discount = product._get_website_disc(0) + + price_tier = False + pricelist = { + 'tier1': product._get_pricelist_tier1, + 'tier2': product._get_pricelist_tier2, + 'tier3': product._get_pricelist_tier3, + } + partner_pricelist_id = partner_pricelist.id if partner_pricelist else False + if partner_pricelist_id == product_pricelist_tier1: price_tier = 'tier1' + if partner_pricelist_id == product_pricelist_tier2: price_tier = 'tier2' + if partner_pricelist_id == product_pricelist_tier3: price_tier = 'tier3' + + if price_tier: + price = pricelist[price_tier]() + discount_key = 'discount_%s' % price_tier + if price[discount_key] > 0: discount = price[discount_key] + parameters.append({ 'company_id': 1, 'order_id': sale_order.id, 'product_id': line['product_id'], 'product_uom_qty': line['quantity'], - 'price_subtotal': product._get_website_price_exclude_tax(), - 'discount': product._get_website_disc(0) + 'price_unit': product._get_website_price_exclude_tax(), + 'discount': discount }) request.env['sale.order.line'].create(parameters) return self.response({ diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py index 1f1f2413..5edb208e 100644 --- a/indoteknik_api/controllers/api_v1/user.py +++ b/indoteknik_api/controllers/api_v1/user.py @@ -118,6 +118,60 @@ class User(controller.Controller): 'user': request.env['res.users'].api_single_response(user) }) + @http.route(prefix + 'user/activation', auth='public', methods=['POST'], csrf=False) + @controller.Controller.must_authorized() + def activation_user(self, **kw): + token = kw.get('token') + if not token: + return self.response(code=400, description='token is required') + + user = request.env['res.users'].search([('activation_token', '=', token), ('active', '=', False)], limit=1) + if not user: + return self.response({'activation': False, 'reason': 'INVALID_TOKEN'}) + + user.active = True + user.activation_token = '' + return self.response({ + 'activation': True, + 'user': self.response_with_token(user) + }) + + @http.route(prefix + 'user/forgot-password', auth='public', methods=['POST'], csrf=False) + @controller.Controller.must_authorized() + def forgot_password_user(self, **kw): + email = kw.get('email') + user = self.get_user_by_email(email) + if not user: + return self.response({'success': False, 'reason': 'NOT_FOUND'}) + + token_source = string.ascii_letters + string.digits + user.reset_password_token = ''.join(random.choice(token_source) for i in range(21)) + return self.response({ + 'success': True, + 'token': user.reset_password_token, + 'user': request.env['res.users'].api_single_response(user) + }) + + @http.route(prefix + 'user/reset-password', auth='public', methods=['POST', 'OPTIONS'], csrf=False) + @controller.Controller.must_authorized() + def reset_password_user(self, **kw): + token = kw.get('token') + if not token: + return self.response(code=400, description='token is required') + + user = request.env['res.users'].search([('reset_password_token', '=', token), ('active', 'in', [False, True])], limit=1) + + if not user: + return self.response({'success': False, 'reason': 'INVALID_TOKEN'}) + + password = kw.get('password', '') + user.password = password + user.reset_password_token = '' + return self.response({ + 'success': True, + 'user': request.env['res.users'].api_single_response(user) + }) + @http.route(prefix + 'user/<id>', auth='public', methods=['PUT', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() def update_user(self, **kw): @@ -151,21 +205,4 @@ class User(controller.Controller): address = [request.env['res.users'].api_address_response(x) for x in partners] return self.response(address) - - @http.route(prefix + 'user/activation', auth='public', methods=['POST'], csrf=False) - @controller.Controller.must_authorized() - def activation_user(self, **kw): - token = kw.get('token') - if not token: - return self.response(code=400, description='token is required') - - user = request.env['res.users'].search([('activation_token', '=', token), ('active', '=', False)], limit=1) - if not user: - return self.response({'activation': False, 'reason': 'INVALID_TOKEN'}) - - user.active = True - user.activation_token = '' - return self.response({ - 'activation': True, - 'user': self.response_with_token(user) - })
\ No newline at end of file +
\ No newline at end of file diff --git a/indoteknik_api/controllers/api_v2/product.py b/indoteknik_api/controllers/api_v2/product.py index 772906f6..d9b43bda 100644 --- a/indoteknik_api/controllers/api_v2/product.py +++ b/indoteknik_api/controllers/api_v2/product.py @@ -5,17 +5,19 @@ from odoo.http import request class V2Product(controller.Controller): prefix = '/api/v2/' - @http.route(prefix + 'product/<id>', auth='public', methods=['GET']) + @http.route(prefix + 'product/<id>', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def v2_get_product_by_id(self, **kw): id = kw.get('id') if not id: return self.response(code=400, description='id is required') + + pricelist = self.user_pricelist() 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'].v2_api_single_response(x, with_detail='DEFAULT') for x in product_templates] + data = [request.env['product.template'].v2_api_single_response(x, pricelist=pricelist, with_detail='DEFAULT') for x in product_templates] return self.response(data)
\ No newline at end of file diff --git a/indoteknik_api/controllers/api_v2/product_variant.py b/indoteknik_api/controllers/api_v2/product_variant.py index b74e4936..8a5bbeb1 100644 --- a/indoteknik_api/controllers/api_v2/product_variant.py +++ b/indoteknik_api/controllers/api_v2/product_variant.py @@ -12,11 +12,13 @@ class V2ProductVariant(controller.Controller): if not id: return self.response(code=400, description='id is required') + pricelist = self.user_pricelist() + data = [] id = [int(x) for x in id.split(',')] product_products = request.env['product.product'].search([('id', 'in', id)]) if product_products: - data = [request.env['product.product'].v2_api_single_response(x) for x in product_products] + data = [request.env['product.product'].v2_api_single_response(x, pricelist=pricelist) for x in product_products] return self.response(data) diff --git a/indoteknik_api/controllers/controller.py b/indoteknik_api/controllers/controller.py index f419f66e..5b20f7d4 100644 --- a/indoteknik_api/controllers/controller.py +++ b/indoteknik_api/controllers/controller.py @@ -54,7 +54,15 @@ class Controller(http.Controller): if user_token: result = user_token return result - + + def user_pricelist(self): + user_token = self.authenticate() + pricelist = False + if isinstance(user_token, dict): + partner = request.env['res.partner'].browse(user_token['partner_id']) + if partner: pricelist = partner.property_product_pricelist + return pricelist + def get_request_params(self, kw, queries): result = { 'valid': True, @@ -62,40 +70,30 @@ class Controller(http.Controller): 'value': {}, 'query': {} } - for key in queries: - rules = queries[key] - is_number = len([r for r in rules if r == 'number']) > 0 - - has_alias = [r for r in rules if r.startswith('alias:')] - alias = key - if len(has_alias) > 0: - alias = has_alias[0].replace('alias:', '') - - has_default = [r for r in rules if r.startswith('default:')] - default = None - if len(has_default) > 0: - default = has_default[0].replace('default:', '') - - value = kw.get(key, '') - if value in ['null', 'undefined']: + + for key, rules in queries.items(): + is_number = 'number' in rules + alias = next((r.replace('alias:', '') for r in rules if r.startswith('alias:')), key) + default = next((r.replace('default:', '') for r in rules if r.startswith('default:')), None) + + if (value := kw.get(key, '')) in ['null', 'undefined']: value = '' - for rule in rules: - if rule == 'required' and not value: - result['reason'].append(key + ' is ' + rule) - elif rule == 'number' and value and not value.isdigit(): - result['reason'].append(key + ' must be ' + rule) + if 'required' in rules and not value: + result['reason'].append(f"{key} is required") + if 'number' in rules and value and not value.isdigit(): + result['reason'].append(f"{key} must be a number") result['query'][key] = value + if not value and default: value = default if is_number and value.isdigit(): value = int(value) - if not value and not default: - value = None + result['value'][alias] = value - if len(result['reason']) > 0: - result['valid'] = False + result['valid'] = not result['reason'] + return result def time_to_str(self, object, format): diff --git a/indoteknik_api/models/product_product.py b/indoteknik_api/models/product_product.py index 32bd7c21..49ea7804 100644 --- a/indoteknik_api/models/product_product.py +++ b/indoteknik_api/models/product_product.py @@ -1,4 +1,5 @@ from odoo import models +from odoo.http import request import math @@ -26,9 +27,33 @@ class ProductProduct(models.Model): } return data - def v2_api_single_response(self, product_product): - product_pricelist_default_discount_id = self.env['ir.config_parameter'].get_param('product.pricelist.default_discount_id') - product_pricelist_default_discount_id = int(product_pricelist_default_discount_id) + def v2_api_single_response(self, product_product, pricelist=False): + config = self.env['ir.config_parameter'] + product_pricelist_tier1 = int(config.get_param('product.pricelist.tier1')) + product_pricelist_tier2 = int(config.get_param('product.pricelist.tier2')) + product_pricelist_tier3 = int(config.get_param('product.pricelist.tier3')) + + discount_percentage = product_product._get_website_disc(0) + price_discount = product_product._get_website_price_after_disc_and_tax() + + price_tier = False + pricelists = { + 'tier1': product_product._get_pricelist_tier1, + 'tier2': product_product._get_pricelist_tier2, + 'tier3': product_product._get_pricelist_tier3, + } + pricelist_id = pricelist.id if pricelist else False + if pricelist_id == product_pricelist_tier1: price_tier = 'tier1' + if pricelist_id == product_pricelist_tier2: price_tier = 'tier2' + if pricelist_id == product_pricelist_tier3: price_tier = 'tier3' + + if price_tier: + price = pricelists[price_tier]() + discount_key = 'discount_%s' % price_tier + price_key = 'price_%s' % price_tier + if price[discount_key] > 0: discount_percentage = price[discount_key] + if price[price_key] > 0: price_discount = price[price_key] + product_template = product_product.product_tmpl_id data = { 'id': product_product.id, @@ -41,8 +66,8 @@ class ProductProduct(models.Model): 'name': product_product.display_name, 'price': { 'price': product_product._get_website_price_exclude_tax(), - 'discount_percentage': product_product._get_website_disc(0), - 'price_discount': product_product._get_website_price_after_disc_and_tax() + 'discount_percentage': discount_percentage, + 'price_discount': price_discount }, 'stock': product_product.qty_stock_vendor, 'weight': product_product.weight, @@ -134,9 +159,13 @@ class ProductProduct(models.Model): return math.floor(res) def _get_pricelist_tier1(self): + product_pricelist_tier1 = int(self.env['ir.config_parameter'].get_param('product.pricelist.tier1')) default_divide_tax = float(1.11) base_price = discount = price = 0 - pricelist_item = self.env['product.pricelist.item'].search([('pricelist_id', '=', 15037), ('product_id', '=', self.id)], limit=1) + pricelist_item = self.env['product.pricelist.item'].search([ + ('pricelist_id', '=', product_pricelist_tier1), + ('product_id', '=', self.id) + ], limit=1) if pricelist_item: # base_price = self._get_website_price_exclude_tax() base_price_incl = self._get_website_price_include_tax() @@ -152,9 +181,13 @@ class ProductProduct(models.Model): return data def _get_pricelist_tier2(self): + product_pricelist_tier2 = int(self.env['ir.config_parameter'].get_param('product.pricelist.tier2')) default_divide_tax = float(1.11) base_price = discount = price = 0 - pricelist_item = self.env['product.pricelist.item'].search([('pricelist_id', '=', 15038), ('product_id', '=', self.id)], limit=1) + pricelist_item = self.env['product.pricelist.item'].search([ + ('pricelist_id', '=', product_pricelist_tier2), + ('product_id', '=', self.id) + ], limit=1) if pricelist_item: # base_price = self._get_website_price_exclude_tax() base_price_incl = self._get_website_price_include_tax() @@ -170,9 +203,13 @@ class ProductProduct(models.Model): return data def _get_pricelist_tier3(self): + product_pricelist_tier3 = int(self.env['ir.config_parameter'].get_param('product.pricelist.tier3')) default_divide_tax = float(1.11) base_price = discount = price = 0 - pricelist_item = self.env['product.pricelist.item'].search([('pricelist_id', '=', 15039), ('product_id', '=', self.id)], limit=1) + pricelist_item = self.env['product.pricelist.item'].search([ + ('pricelist_id', '=', product_pricelist_tier3), + ('product_id', '=', self.id) + ], limit=1) if pricelist_item: # base_price = self._get_website_price_exclude_tax() base_price_incl = self._get_website_price_include_tax() diff --git a/indoteknik_api/models/product_template.py b/indoteknik_api/models/product_template.py index 4d16727f..b9df0f5f 100644 --- a/indoteknik_api/models/product_template.py +++ b/indoteknik_api/models/product_template.py @@ -51,7 +51,7 @@ class ProductTemplate(models.Model): data.update(data_with_detail) return data - def v2_api_single_response(self, product_template, with_detail=''): + def v2_api_single_response(self, product_template, pricelist=False, with_detail=''): product_pricelist_default_discount_id = self.env['ir.config_parameter'].get_param('product.pricelist.default_discount_id') product_pricelist_default_discount_id = int(product_pricelist_default_discount_id) data = { @@ -71,7 +71,7 @@ class ProductTemplate(models.Model): data_with_detail = { 'image': self.env['ir.attachment'].api_image('product.template', 'image_512', product_template.id), 'display_name': product_template.display_name, - 'variants': [self.env['product.product'].v2_api_single_response(variant) for variant in product_template.product_variant_ids], + 'variants': [self.env['product.product'].v2_api_single_response(variant, pricelist=pricelist) for variant in product_template.product_variant_ids], 'description': product_template.website_description or '', } data.update(data_with_detail) diff --git a/indoteknik_api/models/res_users.py b/indoteknik_api/models/res_users.py index 84edb2b1..80de083d 100644 --- a/indoteknik_api/models/res_users.py +++ b/indoteknik_api/models/res_users.py @@ -5,6 +5,18 @@ class ResUsers(models.Model): _inherit = 'res.users' def api_single_response(self, res_user, with_detail=''): + config = self.env['ir.config_parameter'] + product_pricelist_tier1 = int(config.get_param('product.pricelist.tier1')) + product_pricelist_tier2 = int(config.get_param('product.pricelist.tier2')) + product_pricelist_tier3 = int(config.get_param('product.pricelist.tier3')) + + user_pricelist = res_user.property_product_pricelist + user_pricelist_id = user_pricelist.id if user_pricelist else False + pricelist_tier = False + if user_pricelist_id == product_pricelist_tier1: pricelist_tier = 'tier1' + if user_pricelist_id == product_pricelist_tier2: pricelist_tier = 'tier2' + if user_pricelist_id == product_pricelist_tier3: pricelist_tier = 'tier3' + data = { 'id': res_user.id, 'parent_id': res_user.parent_id.id or False, @@ -14,8 +26,11 @@ class ResUsers(models.Model): 'phone': res_user.phone or '', 'mobile': res_user.mobile or '', 'external': res_user.share, - 'company': res_user.company_type == 'company' + 'company': res_user.company_type == 'company', + 'pricelist': pricelist_tier } + + if res_user.parent_id: data.update({ 'company': res_user.parent_id.company_type == 'company' }) diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py index 76532d20..21ee9396 100644 --- a/indoteknik_api/models/sale_order.py +++ b/indoteknik_api/models/sale_order.py @@ -10,6 +10,7 @@ class SaleOrder(models.Model): 'id': sale_order.id, 'name': sale_order.name, 'sales': sale_order.user_id.name, + 'amount_untaxed': sale_order.amount_untaxed, 'amount_tax': sale_order.amount_tax, 'amount_total': sale_order.amount_total, 'purchase_order_name': sale_order.partner_purchase_order_name, @@ -60,7 +61,8 @@ class SaleOrder(models.Model): product['price'] = { 'price': line.price_unit, 'discount_percentage': line.discount, - 'price_discount': line.price_unit - (line.price_unit * (line.discount/100)) + 'price_discount': line.price_reduce_taxexcl, + 'subtotal': line.price_subtotal } product['quantity'] = line.product_uom_qty data_with_detail['products'].append(product) diff --git a/indoteknik_custom/models/apache_solr.py b/indoteknik_custom/models/apache_solr.py index ee166002..3709e88a 100644 --- a/indoteknik_custom/models/apache_solr.py +++ b/indoteknik_custom/models/apache_solr.py @@ -12,7 +12,7 @@ class ApacheSolr(models.Model): _name = 'apache.solr' _order = 'id desc' - def _sync_product_to_solr(self, limit = 500): + def _sync_product_to_solr(self, limit=500): # _solr = pysolr.Solr('http://10.148.0.5:8983/solr/product/', always_commit=True, timeout=30) _solr = pysolr.Solr('http://192.168.23.5:8983/solr/product/', always_commit=True, timeout=30) start_time = time.time() @@ -23,6 +23,7 @@ class ApacheSolr(models.Model): documents = [] counter = 0 for template in templates: + template_time = time.time() counter += 1 price_excl_after_disc = price_excl = discount = tax = 0 variants_name = variants_code = '' @@ -108,7 +109,7 @@ class ApacheSolr(models.Model): documents.append(document) template.solr_flag = 1 # add counter for monitoring - _logger.info('[SYNC_PRODUCT_TO_SOLR] %s/%i' % (counter, limit)) + _logger.info('[SYNC_PRODUCT_TO_SOLR] {}/{} {:.6f}'.format(counter, limit, time.time() - template_time)) _logger.info('[SYNC_PRODUCT_TO_SOLR] Success add to solr product %s' % template.id) _solr.add(documents) end_time = time.time() |
