diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-09-06 10:33:34 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-09-06 10:33:34 +0700 |
| commit | ea48748650d1abe7b9c09f961eaa3762750e21be (patch) | |
| tree | 6fabd4d2aff8d88fb76aa3fb4a10478975bd3c47 | |
| parent | a8404a3ed4423dd7d86f8637ecbf35b7cc18a14c (diff) | |
Add voucher terms and conditions
Add voucher to sale order API
| -rw-r--r-- | indoteknik_api/controllers/api_v1/sale_order.py | 22 | ||||
| -rw-r--r-- | indoteknik_api/controllers/api_v1/voucher.py | 33 | ||||
| -rw-r--r-- | indoteknik_custom/models/voucher.py | 68 | ||||
| -rw-r--r-- | indoteknik_custom/models/website_user_cart.py | 12 | ||||
| -rwxr-xr-x | indoteknik_custom/views/voucher.xml | 3 |
5 files changed, 89 insertions, 49 deletions
diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py index ecc6c771..ccecb55f 100644 --- a/indoteknik_api/controllers/api_v1/sale_order.py +++ b/indoteknik_api/controllers/api_v1/sale_order.py @@ -345,28 +345,8 @@ class SaleOrder(controller.Controller): voucher_code = params['value']['voucher'] voucher = request.env['voucher'].search([('code', '=', voucher_code)]) if voucher: - amount_untaxed = 0 - manufacture_ids = [x.id for x in voucher.manufacture_ids] - for line in sale_order.order_line: - manufacture_id = line.product_id.x_manufacture.id or False - if len(manufacture_ids) == 0 or manufacture_id in manufacture_ids: - amount_untaxed += line.price_subtotal - - voucher_discount = voucher.calculate_discount(amount_untaxed) sale_order.voucher_id = voucher.id - sale_order.amount_voucher_disc = voucher_discount - - for line in sale_order.order_line: - manufacture_id = line.product_id.x_manufacture.id or False - if len(manufacture_ids) > 0 and manufacture_id not in manufacture_ids: - continue - voucher_disc_line = line.price_subtotal / amount_untaxed * voucher_discount - line.amount_voucher_disc = voucher_disc_line - - voucher_disc_item = voucher_disc_line / line.product_uom_qty - voucher_disc_unit = line.price_unit - voucher_disc_item - - line.discount += (line.price_unit - voucher_disc_unit) / line.price_unit * 100 + sale_order.apply_voucher() cart_ids = [x['cart_id'] for x in products] user_cart.browse(cart_ids).unlink() diff --git a/indoteknik_api/controllers/api_v1/voucher.py b/indoteknik_api/controllers/api_v1/voucher.py index e19ae583..2ad61feb 100644 --- a/indoteknik_api/controllers/api_v1/voucher.py +++ b/indoteknik_api/controllers/api_v1/voucher.py @@ -26,34 +26,35 @@ class Voucher(controller.Controller): parameter += [('visibility', 'in', visibility)] vouchers = request.env['voucher'].get_active_voucher(parameter) checkout = cart.get_user_checkout(user_id, source=source) - + products = checkout['products'] + + order_line = [] + for product in products: + order_line.append({ + 'product_id': request.env['product.product'].browse(product['id']), + 'price': product['price']['price'], + 'discount': product['price']['discount_percentage'], + 'qty': product['quantity'], + 'subtotal': product['subtotal'] + }) + results = [] for voucher in vouchers: - products = checkout['products'] - - order_line = [] - for product in products: - order_line.append({ - 'product_id': request.env['product.product'].browse(product['id']), - 'price': product['price']['price'], - 'discount': product['price']['discount_percentage'], - 'qty': product['quantity'], - 'subtotal': product['subtotal'] - }) + if not voucher.can_used: + continue + voucher_info = voucher.apply(order_line) + voucher_tnc = voucher.terms_conditions or voucher.generate_tnc() voucher_discount = voucher_info['discount']['all'] valid_order = voucher_info['valid_order'] - has_flashsale_products = any(product['has_flashsale'] for product in products) can_apply = True if valid_order and voucher_discount > 0 else False voucher_res = voucher.format() voucher_res['can_apply'] = can_apply - voucher_res['apply_status'] = '' - voucher_res['has_flashsale_products'] = has_flashsale_products - voucher_res['difference_to_apply'] = 0 voucher_res['discount_voucher'] = voucher_discount + voucher_res['terms_conditions'] = voucher_tnc results.append(voucher_res) sorted_results = sorted(results, key=lambda x: x['can_apply'], reverse=True) diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py index 485fd0b9..b8d0dc2e 100644 --- a/indoteknik_custom/models/voucher.py +++ b/indoteknik_custom/models/voucher.py @@ -1,6 +1,7 @@ from odoo import models, fields, api from datetime import datetime, timedelta from odoo.exceptions import ValidationError +import locale class Voucher(models.Model): @@ -40,10 +41,12 @@ class Voucher(models.Model): manufacture_ids = fields.Many2many('x_manufactures', string='Brands', help='Voucher appplied only for brand') excl_pricelist_ids = fields.Many2many('product.pricelist', string='Excluded Pricelists', help='Hide voucher from selected exclude pricelist') voucher_line = fields.One2many('voucher.line', 'voucher_id', 'Voucher Line') + terms_conditions = fields.Html('Terms and Conditions') apply_type = fields.Selection(string='Apply Type', default="all", selection=[ ('all', "All product"), ('brand', "Selected product brand"), ]) + can_used = fields.Boolean(string='Can Used?', compute='_compute_can_used') @api.constrains('description') def _check_description_length(self): @@ -55,28 +58,24 @@ class Voucher(models.Model): for voucher in self: voucher.display_name = f'{voucher.name} ({voucher.code})' + def _compute_can_used(self): + for rec in self: + valid_order = [x for x in rec.order_ids if x.state != 'cancel'] + rec.can_used = rec.limit <= 0 or len(valid_order) < rec.limit + def res_format(self): datas = [voucher.format() for voucher in self] return datas 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), 'name': self.name, 'code': self.code, 'description': self.description, - 'discount_amount': self.discount_amount, - 'discount_type': discount_type, 'remaining_time': self._res_remaining_time(), - 'min_purchase_amount': self.min_purchase_amount, - 'max_discount_amount': max_discount_amount, - 'manufacture_names': ", ".join([x.x_name for x in self.manufacture_ids]), - 'manufacture_ids': [x.id for x in self.manufacture_ids], - 'excl_pricelist_ids': [x.id for x in self.excl_pricelist_ids], } return data @@ -159,9 +158,10 @@ class Voucher(models.Model): else: discount_brand = line.discount_amount - result['brand'][manufacture_id] = discount_brand + result['brand'][manufacture_id] = round(discount_brand, 2) result['all'] += discount_brand + result['all'] = round(result['all'], 2) return result def apply(self, order_line): @@ -199,4 +199,50 @@ class Voucher(models.Model): ('end_time', '>=', current_time), ] vouchers = self.search(domain, order='min_purchase_amount ASC') - return vouchers
\ No newline at end of file + return vouchers + + def generate_tnc(self): + tnc = [] + + tnc.append('<ol>') + tnc.append('<li>Voucher hanya berlaku apabila pembelian Pengguna sudah memenuhi syarat dan ketentuan yang tertera pada voucher</li>') + tnc.append(f'<li>Voucher berlaku {self._res_remaining_time()} lagi</li>') + if len(self.voucher_line) > 0: + brand_names = ', '.join([x.manufacture_id.x_name for x in self.voucher_line]) + tnc.append(f'<li>Voucher berlaku untuk produk dari brand {brand_names}</li>') + tnc.append(self.generate_detail_tnc()) + tnc.append('</ol>') + + return ' '.join(tnc) + + def generate_detail_tnc(self): + def format_currency(amount): + locale.setlocale(locale.LC_ALL, 'id_ID') + formatted_amount = locale.format("%d", amount, grouping=True) + return f'Rp{formatted_amount}' + + tnc = [] + if self.apply_type == 'all': + tnc.append('<li>') + tnc.append('Nominal potongan yang bisa didapatkan sebesar') + tnc.append(f'{self.discount_amount}%' if self.discount_type == 'percentage' else format_currency(self.discount_amount)) + + if self.discount_type == 'percentage' and self.max_discount_amount > 0: + tnc.append(f'hingga {format_currency(self.max_discount_amount)}') + + tnc.append(f'dengan minimum pembelian {format_currency(self.min_purchase_amount)}' if self.min_purchase_amount > 0 else 'tanpa minimum pembelian') + tnc.append('</li>') + else: + for line in self.voucher_line: + line_tnc = [] + line_tnc.append(f'Nominal potongan produk {line.manufacture_id.x_name} yang bisa didapatkan sebesar') + line_tnc.append(f'{line.discount_amount}%' if line.discount_type == 'percentage' else format_currency(line.discount_amount)) + + if line.discount_type == 'percentage' and line.max_discount_amount > 0: + line_tnc.append(f'hingga {format_currency(line.max_discount_amount)}') + + line_tnc.append(f'dengan minimum pembelian {format_currency(line.min_purchase_amount)}' if line.min_purchase_amount > 0 else 'tanpa minimum pembelian') + line_tnc = ' '.join(line_tnc) + tnc.append(f'<li>{line_tnc}</li>') + return ' '.join(tnc) + diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index bf7016f8..b3695ba1 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -71,7 +71,17 @@ class WebsiteUserCart(models.Model): subtotal = total_purchase - total_discount discount_voucher = 0 if voucher: - discount_voucher = voucher.calculate_discount(subtotal) + order_line = [] + for product in products: + order_line.append({ + 'product_id': self.env['product.product'].browse(product['id']), + 'price': product['price']['price'], + 'discount': product['price']['discount_percentage'], + 'qty': product['quantity'], + 'subtotal': product['subtotal'] + }) + voucher_info = voucher.apply(order_line) + discount_voucher = voucher_info['discount']['all'] subtotal -= discount_voucher tax = round(subtotal * 0.11) grand_total = subtotal + tax diff --git a/indoteknik_custom/views/voucher.xml b/indoteknik_custom/views/voucher.xml index eb74f27d..8da30d2e 100755 --- a/indoteknik_custom/views/voucher.xml +++ b/indoteknik_custom/views/voucher.xml @@ -76,6 +76,9 @@ <label for="description" string="Max 120 characters:" class="font-weight-normal mb-2 oe_edit_only"/> <field name="description" placeholder="Insert short description..." /> </page> + <page name="terms_conditions" string="Terms and Conditions"> + <field name="terms_conditions" /> + </page> <page name="order_page" string="Orders"> <field name="order_ids" readonly="1" /> </page> |
