summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-08-31 16:07:43 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-08-31 16:07:43 +0700
commit697bb1ffeaee2374ac39aa1c838958b6dfae40fd (patch)
tree3c2fb9138e6e108fafc4d5ee2a304054db6db312
parent403b86d1a3cc168680069b0d8fc499048583da8f (diff)
Update voucher model
- Add voucher line model - Add voucher line on voucher view - Add voucher relation to voucher line
-rw-r--r--indoteknik_custom/models/voucher.py99
-rw-r--r--indoteknik_custom/models/voucher_line.py20
-rwxr-xr-xindoteknik_custom/views/voucher.xml29
3 files changed, 129 insertions, 19 deletions
diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py
index a7151398..485fd0b9 100644
--- a/indoteknik_custom/models/voucher.py
+++ b/indoteknik_custom/models/voucher.py
@@ -13,22 +13,20 @@ class Voucher(models.Model):
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(
+ discount_type = fields.Selection(string='Discount Type',
selection=[
('percentage', 'Percentage'),
('fixed_price', 'Fixed Price'),
- ],
- string='Discount Type',
+ ],
help='Select the type of discount:\n'
- '- Percentage: Persentage dari total harga.\n'
+ '- Percentage: Persentase dari total harga.\n'
'- Fixed Price: Jumlah tetap yang dikurangi dari harga total.'
)
- visibility = fields.Selection(
+ visibility = fields.Selection(string='Visibility',
selection=[
('public', 'Public'),
('private', 'Private')
],
- string='Visibility',
help='Select the visibility:\n'
'- Public: Ditampilkan kepada seluruh pengguna.\n'
'- Private: Tidak ditampilkan kepada seluruh pengguna.'
@@ -41,6 +39,11 @@ class Voucher(models.Model):
limit = fields.Integer(string='Limit', help='Voucher limit by sale order. Masukan 0 untuk tanpa limit')
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')
+ apply_type = fields.Selection(string='Apply Type', default="all", selection=[
+ ('all', "All product"),
+ ('brand', "Selected product brand"),
+ ])
@api.constrains('description')
def _check_description_length(self):
@@ -97,6 +100,84 @@ class Voucher(models.Model):
calculate_time = self.end_time - datetime.now()
return round(calculate_time.total_seconds())
+ def filter_order_line(self, order_line):
+ if self.apply_type == 'all':
+ return order_line
+
+ voucher_manufacture_ids = self.collect_manufacture_ids()
+ results = []
+ for line in order_line:
+ manufacture_id = line['product_id'].x_manufacture.id or None
+ if manufacture_id not in voucher_manufacture_ids:
+ continue
+
+ product_flashsale = line['product_id']._get_active_flash_sale()
+ if len(product_flashsale) > 0:
+ continue
+
+ results.append(line)
+
+ return results
+
+ def calc_total_order_line(self, order_line):
+ result = { 'all': 0, 'brand': {} }
+ for line in order_line:
+ manufacture_id = line['product_id'].x_manufacture.id or None
+ manufacture_total = result['brand'].get(manufacture_id, 0)
+ result['brand'][manufacture_id] = manufacture_total + line['subtotal']
+ result['all'] += line['subtotal']
+
+ return result
+
+ def calc_discount_amount(self, total):
+ result = { 'all': 0, 'brand': {} }
+
+ if self.apply_type == 'all':
+ if total['all'] < self.min_purchase_amount:
+ return result
+
+ if self.discount_type == 'percentage':
+ decimal_discount = self.discount_amount / 100
+ discount_all = total['all'] * decimal_discount
+ result['all'] = min(discount_all, self.max_discount_amount) if self.max_discount_amount > 0 else discount_all
+ else:
+ result['all'] = self.discount_amount
+
+ return result
+
+ for line in self.voucher_line:
+ manufacture_id = line.manufacture_id.id
+ total_brand = total['brand'].get(manufacture_id, 0)
+
+ discount_brand = 0
+ if total_brand < line.min_purchase_amount:
+ discount_brand = 0
+ elif line.discount_type == 'percentage':
+ decimal_discount = line.discount_amount / 100
+ discount_brand = total_brand * decimal_discount
+ discount_brand = min(discount_brand, line.max_discount_amount) if line.max_discount_amount > 0 else discount_brand
+ else:
+ discount_brand = line.discount_amount
+
+ result['brand'][manufacture_id] = discount_brand
+ result['all'] += discount_brand
+
+ return result
+
+ def apply(self, order_line):
+ order_line = self.filter_order_line(order_line)
+ amount_total = self.calc_total_order_line(order_line)
+ discount = self.calc_discount_amount(amount_total)
+ return {
+ 'discount': discount,
+ 'total': amount_total,
+ 'type': self.apply_type,
+ 'valid_order': order_line
+ }
+
+ def collect_manufacture_ids(self):
+ return [x.manufacture_id.id for x in self.voucher_line]
+
def calculate_discount(self, price):
if price < self.min_purchase_amount:
return 0
@@ -111,11 +192,11 @@ class Voucher(models.Model):
return 0
- def get_active_voucher(self, parameter):
+ def get_active_voucher(self, domain):
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- parameter += [
+ domain += [
('start_time', '<=', current_time),
('end_time', '>=', current_time),
]
- vouchers = self.search(parameter, order='min_purchase_amount ASC')
+ vouchers = self.search(domain, order='min_purchase_amount ASC')
return vouchers \ No newline at end of file
diff --git a/indoteknik_custom/models/voucher_line.py b/indoteknik_custom/models/voucher_line.py
new file mode 100644
index 00000000..8b449d1f
--- /dev/null
+++ b/indoteknik_custom/models/voucher_line.py
@@ -0,0 +1,20 @@
+from odoo import models, fields
+
+
+class Voucher(models.Model):
+ _name = 'voucher.line'
+
+ voucher_id = fields.Many2one('voucher', string='Voucher')
+ manufacture_id = fields.Many2one('x_manufactures', string='Brand')
+ min_purchase_amount = fields.Integer(string='Min. Purchase Amount', help='Nominal minimum untuk dapat menggunakan voucher. Isi 0 jika tidak ada minimum purchase amount')
+ discount_amount = fields.Integer(string='Discount Amount')
+ discount_type = fields.Selection(string='Discount Type',
+ selection=[
+ ('percentage', 'Percentage'),
+ ('fixed_price', 'Fixed Price'),
+ ],
+ help='Select the type of discount:\n'
+ '- Percentage: Persentase dari total harga.\n'
+ '- Fixed Price: Jumlah tetap yang dikurangi dari harga total.'
+ )
+ max_discount_amount = fields.Integer(string='Max. Discount Amount', help='Max nominal terhadap persentase diskon') \ No newline at end of file
diff --git a/indoteknik_custom/views/voucher.xml b/indoteknik_custom/views/voucher.xml
index 7b181c62..eb74f27d 100755
--- a/indoteknik_custom/views/voucher.xml
+++ b/indoteknik_custom/views/voucher.xml
@@ -28,8 +28,15 @@
<group>
<field name="image" widget="image" width="120"/>
<field name="name" required="1" />
+ <field name="code" required="1" />
+ <field name="visibility" required="1" />
+ <field name="start_time" required="1"/>
+ <field name="end_time" required="1"/>
+ <field name="limit" required="1"/>
+ <field name="apply_type" required="1" />
+ <field name="excl_pricelist_ids" widget="many2many_tags" domain="[('id', 'in', [4, 15037, 15038, 15039])]"/>
</group>
- <group string="Discount Settings">
+ <group string="Discount Settings" attrs="{'invisible': [('apply_type', '!=', 'all')]}">
<field name="min_purchase_amount" widget="monetary" required="1" />
<field name="discount_type" required="1" />
@@ -52,17 +59,19 @@
<field name="max_discount_amount" widget="monetary" required="1" attrs="{'invisible': [('discount_type', '!=', 'percentage')]}"/>
</group>
- <group string="Rules">
- <field name="code" required="1" />
- <field name="visibility" required="1" />
- <field name="start_time" required="1"/>
- <field name="end_time" required="1"/>
- <field name="limit" required="1"/>
- <field name="manufacture_ids" widget="many2many_tags"/>
- <field name="excl_pricelist_ids" widget="many2many_tags" domain="[('id', 'in', [4, 15037, 15038, 15039])]"/>
- </group>
</group>
<notebook>
+ <page name="voucher_line" string="Voucher Line" attrs="{'invisible': [('apply_type', '!=', 'brand')]}">
+ <field name="voucher_line">
+ <tree editable="bottom">
+ <field name="manufacture_id" required="1" />
+ <field name="min_purchase_amount" required="1" />
+ <field name="discount_type" required="1" />
+ <field name="discount_amount" required="1" />
+ <field name="max_discount_amount" required="1" attrs="{'readonly': [('discount_type', '!=', 'percentage')]}" />
+ </tree>
+ </field>
+ </page>
<page name="description" string="Description">
<label for="description" string="Max 120 characters:" class="font-weight-normal mb-2 oe_edit_only"/>
<field name="description" placeholder="Insert short description..." />