From 68c2e896a684e1dc68b4f01da38a444fe76bceac Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 10 Jul 2023 14:34:55 +0700 Subject: Add voucher model, view, and api --- indoteknik_api/controllers/api_v1/__init__.py | 1 + indoteknik_api/controllers/api_v1/voucher.py | 22 +++++++ indoteknik_custom/__manifest__.py | 1 + indoteknik_custom/models/__init__.py | 1 + indoteknik_custom/models/sale_order.py | 1 + indoteknik_custom/models/voucher.py | 66 ++++++++++++++++++++ indoteknik_custom/security/ir.model.access.csv | 3 +- indoteknik_custom/views/voucher.xml | 85 ++++++++++++++++++++++++++ 8 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 indoteknik_api/controllers/api_v1/voucher.py create mode 100644 indoteknik_custom/models/voucher.py create mode 100755 indoteknik_custom/views/voucher.xml diff --git a/indoteknik_api/controllers/api_v1/__init__.py b/indoteknik_api/controllers/api_v1/__init__.py index 2afefb34..65bcf926 100644 --- a/indoteknik_api/controllers/api_v1/__init__.py +++ b/indoteknik_api/controllers/api_v1/__init__.py @@ -25,3 +25,4 @@ from . import content from . import midtrans from . import wati from . import courier +from . import voucher \ No newline at end of file diff --git a/indoteknik_api/controllers/api_v1/voucher.py b/indoteknik_api/controllers/api_v1/voucher.py new file mode 100644 index 00000000..0990a1a0 --- /dev/null +++ b/indoteknik_api/controllers/api_v1/voucher.py @@ -0,0 +1,22 @@ +from .. import controller +from odoo import http +from odoo.http import request + +class Voucher(controller.Controller): + prefix = '/api/v1/' + + @http.route(prefix + 'voucher', auth='public', methods=['GET', 'OPTIONS']) + @controller.Controller.must_authorized() + def get_vouchers(self, **kw): + code = kw.get('code') + visibility = 'public' + + parameter = [] + if code: + visibility = 'private' + parameter += [('code', '=', code)] + + parameter += [('visibility', '=', visibility)] + vouchers = request.env['voucher'].get_active_voucher(parameter) + data = vouchers.res_format() + return self.response(data) diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 79f6e195..5b0c4e41 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -77,6 +77,7 @@ 'views/brand_vendor.xml', 'views/requisition.xml', 'views/landedcost.xml', + 'views/voucher.xml', 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 166d43ad..3a27072c 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -64,3 +64,4 @@ from . import brand_vendor from . import manufacturing from . import requisition from . import account_move_due_extension +from . import voucher \ No newline at end of file diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 5a3cada9..e54b9ae2 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -86,6 +86,7 @@ class SaleOrder(models.Model): sppkp = fields.Char(string="SPPKP") npwp = fields.Char(string="NPWP") purchase_total = fields.Monetary(string='Purchase Total', compute='_compute_purchase_total') + voucher_id = fields.Many2one(comodel_name='voucher', string='Voucher') def _compute_purchase_total(self): for order in self: diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py new file mode 100644 index 00000000..4ca13bd3 --- /dev/null +++ b/indoteknik_custom/models/voucher.py @@ -0,0 +1,66 @@ +from odoo import models, fields +from datetime import datetime + + +class Voucher(models.Model): + _name = 'voucher' + + name = fields.Char(string='Name') + image = fields.Binary(string='Image') + code = fields.Char(string='Code', help='Kode voucher yang akan berlaku untuk pengguna') + description = fields.Text(string='Description') + discount_amount = fields.Integer(string='Discount Amount') + discount_type = fields.Selection( + selection=[ + ('percentage', 'Percentage'), + ('fixed_price', 'Fixed Price'), + ], + string='Discount Type', + help='Select the type of discount:\n' + '- Percentage: Persentage dari total harga.\n' + '- Fixed Price: Jumlah tetap yang dikurangi dari harga total.' + ) + visibility = fields.Selection( + selection=[ + ('public', 'Public'), + ('private', 'Private') + ], + string='Visibility', + help='Select the visibility:\n' + '- Public: Ditampilkan kepada seluruh pengguna.\n' + '- Private: Tidak ditampilkan kepada seluruh pengguna.' + ) + start_time = fields.Datetime(string='Start Time') + end_time = fields.Datetime(string='End Time') + min_purchase_amount = fields.Integer(string='Min. Purchase Amount', help='Nominal minimum untuk dapat menggunakan voucher. Isi 0 jika tidak ada minimum purchase amount') + max_discount_amount = fields.Integer(string='Max. Discount Amount', help='Max nominal terhadap persentase diskon') + order_ids = fields.One2many('sale.order', 'voucher_id', string='Order') + + def res_format(self): + datas = [voucher.format() for voucher in self] + return datas + + def format(self): + data = { + 'name': self.name, + 'code': self.code, + 'description': self.description, + 'discount_amount': self.discount_amount, + 'discount_type': self.discount_type, + 'remaining_time': self._get_remaining_time(), + 'min_purchase_amount': self.min_purchase_amount + } + return data + + def _get_remaining_time(self): + calculate_time = self.end_time - datetime.now() + return round(calculate_time.total_seconds()) + + def get_active_voucher(self, parameter): + current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + parameter += [ + ('start_time', '<=', current_time), + ('end_time', '>=', current_time), + ] + vouchers = self.search(parameter) + return vouchers \ No newline at end of file diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index df820053..7cacf2bb 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -53,4 +53,5 @@ access_rajaongkir_kurir,access.rajaongkir.kurir,model_rajaongkir_kurir,,1,1,1,1 access_brand_vendor,access.brand.vendor,model_brand_vendor,,1,1,1,1 access_requisition,access.requisition,model_requisition,,1,1,1,1 access_requisition_line,access.requisition.line,model_requisition_line,,1,1,1,1 -access_requisition_purchase_match,access.requisition.purchase.match,model_requisition_purchase_match,,1,1,1,1 \ No newline at end of file +access_requisition_purchase_match,access.requisition.purchase.match,model_requisition_purchase_match,,1,1,1,1 +access_voucher,access.voucher,model_voucher,,1,1,1,1 \ No newline at end of file diff --git a/indoteknik_custom/views/voucher.xml b/indoteknik_custom/views/voucher.xml new file mode 100755 index 00000000..32c15588 --- /dev/null +++ b/indoteknik_custom/views/voucher.xml @@ -0,0 +1,85 @@ + + + + Voucher + voucher + tree,form + + + + Voucher + voucher + + + + + + + + + + + Voucher + voucher + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+
\ No newline at end of file -- cgit v1.2.3 From 8ae3fbf012539d286a5de3deb3d7c500920c2257 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 10 Jul 2023 15:00:17 +0700 Subject: Update voucher api response --- indoteknik_custom/models/voucher.py | 5 ++++- indoteknik_custom/views/voucher.xml | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py index 4ca13bd3..c97e54fa 100644 --- a/indoteknik_custom/models/voucher.py +++ b/indoteknik_custom/models/voucher.py @@ -41,13 +41,16 @@ class Voucher(models.Model): return datas def format(self): + ir_attachment = self.env['ir.attachment'] data = { + 'id': self.id, + 'image': ir_attachment.api_image('voucher', 'image', self.id), 'name': self.name, 'code': self.code, 'description': self.description, 'discount_amount': self.discount_amount, 'discount_type': self.discount_type, - 'remaining_time': self._get_remaining_time(), + 'remaining_time': self.end_time.strftime('%d-%m-%Y'), 'min_purchase_amount': self.min_purchase_amount } return data diff --git a/indoteknik_custom/views/voucher.xml b/indoteknik_custom/views/voucher.xml index 32c15588..cd42586e 100755 --- a/indoteknik_custom/views/voucher.xml +++ b/indoteknik_custom/views/voucher.xml @@ -36,6 +36,7 @@ + -- cgit v1.2.3 From 30ee32fcb482d325dd4a8db09983112a81fdb448 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 10 Jul 2023 15:28:00 +0700 Subject: Update format voucher api response --- indoteknik_custom/models/voucher.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py index c97e54fa..e1497d9a 100644 --- a/indoteknik_custom/models/voucher.py +++ b/indoteknik_custom/models/voucher.py @@ -42,6 +42,8 @@ class Voucher(models.Model): def format(self): ir_attachment = self.env['ir.attachment'] + discount_type = self.discount_type + max_discount_amount = self.max_discount_amount if discount_type == 'percentage' else 0 data = { 'id': self.id, 'image': ir_attachment.api_image('voucher', 'image', self.id), @@ -49,9 +51,10 @@ class Voucher(models.Model): 'code': self.code, 'description': self.description, 'discount_amount': self.discount_amount, - 'discount_type': self.discount_type, + 'discount_type': discount_type, 'remaining_time': self.end_time.strftime('%d-%m-%Y'), - 'min_purchase_amount': self.min_purchase_amount + 'min_purchase_amount': self.min_purchase_amount, + 'max_discount_amount': max_discount_amount, } return data -- cgit v1.2.3 From e1af064ea7c6be76e96719382f4de8245b89dc5f Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 10 Jul 2023 15:30:53 +0700 Subject: Add start time on voucher api --- indoteknik_custom/models/voucher.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py index e1497d9a..6a166cf3 100644 --- a/indoteknik_custom/models/voucher.py +++ b/indoteknik_custom/models/voucher.py @@ -52,7 +52,8 @@ class Voucher(models.Model): 'description': self.description, 'discount_amount': self.discount_amount, 'discount_type': discount_type, - 'remaining_time': self.end_time.strftime('%d-%m-%Y'), + 'start_time': self.start_time.strftime('%d-%m-%Y'), + 'end_time': self.end_time.strftime('%d-%m-%Y'), 'min_purchase_amount': self.min_purchase_amount, 'max_discount_amount': max_discount_amount, } -- cgit v1.2.3 From 94224e3174bf1370ae8e4ced3271d78beba83cfb Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Tue, 11 Jul 2023 10:32:54 +0700 Subject: Update get active voucher order by lowest min_purchase_amount --- indoteknik_custom/models/voucher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py index 6a166cf3..23285b3a 100644 --- a/indoteknik_custom/models/voucher.py +++ b/indoteknik_custom/models/voucher.py @@ -69,5 +69,5 @@ class Voucher(models.Model): ('start_time', '<=', current_time), ('end_time', '>=', current_time), ] - vouchers = self.search(parameter) + vouchers = self.search(parameter, order='min_purchase_amount ASC') return vouchers \ No newline at end of file -- cgit v1.2.3 From 7753f4b1ebf4514863c05d3a92d8c4496d9b344a Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Wed, 12 Jul 2023 08:56:19 +0700 Subject: Update voucher time text --- indoteknik_custom/models/voucher.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py index 23285b3a..00192cec 100644 --- a/indoteknik_custom/models/voucher.py +++ b/indoteknik_custom/models/voucher.py @@ -1,5 +1,5 @@ from odoo import models, fields -from datetime import datetime +from datetime import datetime, timedelta class Voucher(models.Model): @@ -52,13 +52,28 @@ class Voucher(models.Model): 'description': self.description, 'discount_amount': self.discount_amount, 'discount_type': discount_type, - 'start_time': self.start_time.strftime('%d-%m-%Y'), - 'end_time': self.end_time.strftime('%d-%m-%Y'), + 'remaining_time': self._res_remaining_time(), 'min_purchase_amount': self.min_purchase_amount, 'max_discount_amount': max_discount_amount, } return data + def _res_remaining_time(self): + seconds = self._get_remaining_time() + remaining_time = timedelta(seconds=seconds) + hours = remaining_time.seconds // 3600 + minutes = remaining_time.seconds // 60 + if remaining_time.days > 0: + time = remaining_time.days + unit = 'hari' + elif hours > 0: + time = hours + unit = 'jam' + else: + time = minutes + unit = 'menit' + return f'{time} {unit}' + def _get_remaining_time(self): calculate_time = self.end_time - datetime.now() return round(calculate_time.total_seconds()) -- cgit v1.2.3 From 5d101afe46c1c1bce87ec2f7e8f18d040bbbc7d3 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Wed, 12 Jul 2023 11:33:04 +0700 Subject: Add apply voucher on checkout api --- indoteknik_api/controllers/api_v1/sale_order.py | 137 ++++++++++++++++-------- indoteknik_custom/models/voucher.py | 20 ++++ indoteknik_custom/views/sale_order.xml | 1 + 3 files changed, 112 insertions(+), 46 deletions(-) diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index aa211b75..e036751e 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -58,25 +58,28 @@ class SaleOrder(controller.Controller): limit = params['value']['limit'] offset = params['value']['offset'] if not params['valid']: - return self.response(code=400, description=params) + return self.response(code=400, description=params) - partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) + 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 += ["|","|",("state","=","draft"),("state","=","sent"),("state","=","cancel")] + domain += ["|", "|", ("state", "=", "draft"), + ("state", "=", "sent"), ("state", "=", "cancel")] if not context: - domain += ["|",("state","=","sale"),("state","=","done")] + domain += ["|", ("state", "=", "sale"), ("state", "=", "done")] if params['value']['name']: name = params['value']['name'].replace(' ', '%') domain += [ '|', - ('name', 'ilike', '%'+ name +'%'), - ('partner_purchase_order_name', 'ilike', '%'+ name +'%') + ('name', 'ilike', '%' + name + '%'), + ('partner_purchase_order_name', 'ilike', '%' + name + '%') ] - sale_orders = request.env['sale.order'].search(domain, offset=offset, limit=limit) + sale_orders = request.env['sale.order'].search( + domain, offset=offset, limit=limit) data = { 'sale_order_total': request.env['sale.order'].search_count(domain), 'sale_orders': [request.env['sale.order'].api_v1_single_response(x) for x in sale_orders] @@ -91,9 +94,10 @@ class SaleOrder(controller.Controller): 'id': ['number'] }) if not params['valid']: - return self.response(code=400, description=params) - - partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) + return self.response(code=400, description=params) + + partner_child_ids = self.get_partner_child_ids( + params['value']['partner_id']) domain = [ ('id', '=', params['value']['id']), ('partner_id', 'in', partner_child_ids) @@ -101,8 +105,9 @@ class SaleOrder(controller.Controller): data = {} sale_order = request.env['sale.order'].search(domain) if sale_order: - data = request.env['sale.order'].api_v1_single_response(sale_order, context='with_detail') - + data = request.env['sale.order'].api_v1_single_response( + sale_order, context='with_detail') + return self.response(data) @http.route(PREFIX_PARTNER + 'sale_order//checkout', auth='public', method=['POST', 'OPTIONS'], csrf=False) @@ -113,9 +118,10 @@ class SaleOrder(controller.Controller): 'id': ['number'] }) if not params['valid']: - return self.response(code=400, description=params) + return self.response(code=400, description=params) - partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) + partner_child_ids = self.get_partner_child_ids( + params['value']['partner_id']) domain = [ ('id', '=', params['value']['id']), ('partner_id', 'in', partner_child_ids) @@ -124,13 +130,14 @@ class SaleOrder(controller.Controller): sale_order = request.env['sale.order'].search(domain) if sale_order: sale_order.approval_status = 'pengajuan1' - data = request.env['sale.order'].api_v1_single_response(sale_order, context='with_detail') + data = request.env['sale.order'].api_v1_single_response( + sale_order, context='with_detail') return self.response(data) @http.route(PREFIX_PARTNER + 'sale_order//upload_po', auth='public', method=['POST', 'OPTIONS'], csrf=False) def partner_upload_po_sale_order(self, **kw): - user_token = self.authenticate() + user_token = self.authenticate() if not user_token: return self.unauthorized_response() @@ -144,7 +151,8 @@ class SaleOrder(controller.Controller): return self.unauthorized_response() if not params['valid']: return self.response(code=400, description=params) - partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) + partner_child_ids = self.get_partner_child_ids( + params['value']['partner_id']) domain = [ ('id', '=', params['value']['id']), ('partner_id', 'in', partner_child_ids) @@ -166,9 +174,11 @@ class SaleOrder(controller.Controller): md5_valid = rest_api.md5_salt_valid(id, 'sale.order', token) if not md5_valid: return self.response('Unauthorized') - - sale_order = request.env['sale.order'].sudo().search_read([('id', '=', id)], ['partner_purchase_order_name']) - attachment = rest_api.get_single_attachment('sale.order', 'partner_purchase_order_file', id) + + sale_order = request.env['sale.order'].sudo().search_read( + [('id', '=', id)], ['partner_purchase_order_name']) + attachment = rest_api.get_single_attachment( + 'sale.order', 'partner_purchase_order_file', id) if attachment and len(sale_order) > 0: return rest_api.response_attachment({ 'content': attachment['datas'], @@ -186,9 +196,11 @@ class SaleOrder(controller.Controller): md5_valid = rest_api.md5_salt_valid(id, 'sale.order', token) if not md5_valid: return self.response('Unauthorized') - - sale_order = request.env['sale.order'].sudo().search_read([('id', '=', id)], ['name']) - pdf, type = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'indoteknik_custom.report_saleorder_website')])._render_qweb_pdf([id]) + + sale_order = request.env['sale.order'].sudo( + ).search_read([('id', '=', id)], ['name']) + pdf, type = request.env['ir.actions.report'].sudo().search( + [('report_name', '=', 'indoteknik_custom.report_saleorder_website')])._render_qweb_pdf([id]) if pdf and len(sale_order) > 0: return rest_api.response_attachment({ 'content': pdf, @@ -205,9 +217,10 @@ class SaleOrder(controller.Controller): 'id': ['number'] }) if not params['valid']: - return self.response(code=400, description=params) + return self.response(code=400, description=params) - partner_child_ids = self.get_partner_child_ids(params['value']['partner_id']) + partner_child_ids = self.get_partner_child_ids( + params['value']['partner_id']) domain = [ ('id', '=', params['value']['id']), ('partner_id', 'in', partner_child_ids) @@ -218,15 +231,19 @@ class SaleOrder(controller.Controller): sale_order.state = 'cancel' data = sale_order.id return self.response(data) - + @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): 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')) + 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'], @@ -238,9 +255,10 @@ class SaleOrder(controller.Controller): 'type': [], 'delivery_amount': ['number', 'default:0'], 'carrier_id': [], - 'delivery_service_type': [] + 'delivery_service_type': [], + 'voucher': [] }) - + if not params['valid']: return self.response(code=400, description=params) @@ -275,10 +293,12 @@ class SaleOrder(controller.Controller): order_line = json.loads(params['value']['order_line']) parameters = [] - partner = request.env['res.partner'].browse(params['value']['partner_id']) + 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) + product = request.env['product.product'].search( + [('id', '=', line['product_id'])], limit=1) discount = product._get_website_disc(0) price_tier = False @@ -288,15 +308,19 @@ class SaleOrder(controller.Controller): '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 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] - + if price[discount_key] > 0: + discount = price[discount_key] + flashsale = product._get_flashsale_price() flashsale_discount = flashsale['flashsale_discount'] if flashsale_discount > 0 and flashsale_discount > discount: @@ -310,13 +334,29 @@ class SaleOrder(controller.Controller): 'price_unit': product._get_website_price_exclude_tax(), 'discount': discount }) - + request.env['sale.order.line'].create(parameters) + + amount_untaxed = sale_order.amount_untaxed + voucher = request.env['voucher'].search([ + ('code', '=', params['value']['voucher']) + ]) + if voucher: + sale_order.voucher_id = voucher.id + voucher_discount = voucher.calculate_discount(amount_untaxed) + total_qty = sum(line.product_uom_qty for line in sale_order.order_line) + voucher_discount_item = voucher_discount / total_qty + for line in sale_order.order_line: + discount_decimal = line.discount / 100 + voucher_discount_line = voucher_discount_item / (1 - discount_decimal) + price = line.price_unit - voucher_discount_line + line.price_unit = price + return self.response({ 'id': sale_order.id, 'name': sale_order.name }) - + @http.route('/api/sale_order/invoiced', auth='public', methods=['GET']) def get_sale_order_invoiced_by_partner_id(self, **kw): if not self.authenticate(): @@ -328,8 +368,10 @@ class SaleOrder(controller.Controller): partner_id = int(partner_id) # Get company member by partner_id - parent_partner_id = request.env['res.partner'].search([('id', '=', partner_id)], limit=1).parent_id.id - partner_childs = request.env['res.partner'].search([('parent_id', '=', int(parent_partner_id))]) + parent_partner_id = request.env['res.partner'].search( + [('id', '=', partner_id)], limit=1).parent_id.id + partner_childs = request.env['res.partner'].search( + [('parent_id', '=', int(parent_partner_id))]) partner_child_ids = [v['id'] for v in partner_childs] + [partner_id] # Get sale order by company member and invoiced @@ -378,9 +420,12 @@ class SaleOrder(controller.Controller): ('id', '=', id), ('state', 'in', ['sale', 'done']) ] - parent_partner_id = request.env['res.partner'].search([('id', '=', int(partner_id))], limit=1).parent_id.id - partner_childs = request.env['res.partner'].search([('parent_id', '=', int(parent_partner_id))]) - partner_child_ids = [v['id'] for v in partner_childs] + [int(partner_id)] + parent_partner_id = request.env['res.partner'].search( + [('id', '=', int(partner_id))], limit=1).parent_id.id + partner_childs = request.env['res.partner'].search( + [('parent_id', '=', int(parent_partner_id))]) + 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_filter('sale.order', kw, default_domain) diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py index 00192cec..b327df6d 100644 --- a/indoteknik_custom/models/voucher.py +++ b/indoteknik_custom/models/voucher.py @@ -4,7 +4,9 @@ from datetime import datetime, timedelta class Voucher(models.Model): _name = 'voucher' + _rec_name = 'display_name' + display_name = fields.Char(string='Display Name', compute='_compute_display_name') name = fields.Char(string='Name') image = fields.Binary(string='Image') code = fields.Char(string='Code', help='Kode voucher yang akan berlaku untuk pengguna') @@ -36,6 +38,10 @@ class Voucher(models.Model): max_discount_amount = fields.Integer(string='Max. Discount Amount', help='Max nominal terhadap persentase diskon') order_ids = fields.One2many('sale.order', 'voucher_id', string='Order') + def _compute_display_name(self): + for voucher in self: + voucher.display_name = f'{voucher.name} ({voucher.code})' + def res_format(self): datas = [voucher.format() for voucher in self] return datas @@ -78,6 +84,20 @@ class Voucher(models.Model): calculate_time = self.end_time - datetime.now() return round(calculate_time.total_seconds()) + def calculate_discount(self, price): + if price < self.min_purchase_amount: + return 0 + + if self.discount_type == 'fixed_price': + return self.discount_amount + + if self.discount_type == 'percentage': + discount = price * self.discount_amount / 100 + max_disc = self.max_discount_amount + return max_disc if discount > max_disc else discount + + return 0 + def get_active_voucher(self, parameter): current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') parameter += [ diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 70e3392f..b55fefff 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -26,6 +26,7 @@ + -- cgit v1.2.3