summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-09-06 10:33:34 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-09-06 10:33:34 +0700
commitea48748650d1abe7b9c09f961eaa3762750e21be (patch)
tree6fabd4d2aff8d88fb76aa3fb4a10478975bd3c47
parenta8404a3ed4423dd7d86f8637ecbf35b7cc18a14c (diff)
Add voucher terms and conditions
Add voucher to sale order API
-rw-r--r--indoteknik_api/controllers/api_v1/sale_order.py22
-rw-r--r--indoteknik_api/controllers/api_v1/voucher.py33
-rw-r--r--indoteknik_custom/models/voucher.py68
-rw-r--r--indoteknik_custom/models/website_user_cart.py12
-rwxr-xr-xindoteknik_custom/views/voucher.xml3
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>