summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2025-05-09 15:27:52 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2025-05-09 15:27:52 +0700
commitd952f5288b360c4013064b8b6848a54b3c0a20ad (patch)
treecd2a1d8eed7b76f32f2e4063fd98bd91ee42601e
parent81a60ec161deb7eba3072172744276d6e5457f64 (diff)
parenteaa804b51a5b3829bb62148ff198327230e06f7e (diff)
Merge branch 'odoo-backup' of bitbucket.org:altafixco/indoteknik-addons into odoo-backup
-rw-r--r--indoteknik_custom/models/commision.py47
-rw-r--r--indoteknik_custom/models/voucher.py258
-rw-r--r--indoteknik_custom/models/website_user_cart.py121
-rw-r--r--indoteknik_custom/views/customer_commision.xml234
-rwxr-xr-xindoteknik_custom/views/voucher.xml74
5 files changed, 445 insertions, 289 deletions
diff --git a/indoteknik_custom/models/commision.py b/indoteknik_custom/models/commision.py
index 788fc0f9..eeaa8efc 100644
--- a/indoteknik_custom/models/commision.py
+++ b/indoteknik_custom/models/commision.py
@@ -201,7 +201,8 @@ class CustomerCommision(models.Model):
grouped_invoice_number = fields.Char(string='Group Invoice Number', compute='_compute_grouped_numbers')
sales_id = fields.Many2one('res.users', string="Sales", tracking=True, default=lambda self: self.env.user,
- domain=lambda self: [('groups_id', 'in', self.env.ref('sales_team.group_sale_salesman').id)])
+ domain=lambda self: [
+ ('groups_id', 'in', self.env.ref('sales_team.group_sale_salesman').id)])
date_approved_sales = fields.Datetime(string="Date Approved Sales", tracking=True)
date_approved_marketing = fields.Datetime(string="Date Approved Marketing", tracking=True)
@@ -213,6 +214,46 @@ class CustomerCommision(models.Model):
position_pimpinan = fields.Char(string="Position Pimpinan", tracking=True)
position_accounting = fields.Char(string="Position Accounting", tracking=True)
+ # get partner ids so it can be grouped by
+ @api.model
+ def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
+ if 'partner_ids' in groupby:
+ # Get all records matching the domain
+ records = self.search(domain)
+
+ # Create groups for each partner
+ groups = {}
+ for record in records:
+ for partner in record.partner_ids:
+ if partner.id not in groups:
+ groups[partner.id] = {
+ 'partner_ids': partner,
+ 'records': self.env['customer.commision']
+ }
+ groups[partner.id]['records'] |= record
+
+ # Format the result
+ result = []
+ for partner_id, group_data in groups.items():
+ partner = group_data['partner_ids']
+ record_ids = group_data['records'].ids
+
+ # Create the domain
+ group_domain = [('id', 'in', record_ids)]
+ if domain:
+ group_domain = ['&'] + domain + group_domain
+
+ result.append({
+ 'partner_ids': (partner.id, partner.display_name),
+ 'partner_ids_count': len(record_ids),
+ '__domain': group_domain,
+ '__count': len(record_ids),
+ })
+
+ return result
+
+ return super(CustomerCommision, self).read_group(domain, fields, groupby, offset, limit, orderby, lazy)
+
def compute_delivery_amt_text(self):
tb = Terbilang()
@@ -308,9 +349,9 @@ class CustomerCommision(models.Model):
def action_confirm_customer_commision(self):
jakarta_tz = pytz.timezone('Asia/Jakarta')
now = datetime.now(jakarta_tz)
-
+
now_naive = now.replace(tzinfo=None)
-
+
if not self.status or self.status == 'draft':
self.status = 'pengajuan1'
elif self.status == 'pengajuan1' and self.env.user.is_sales_manager:
diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py
index 7b458d01..b213a039 100644
--- a/indoteknik_custom/models/voucher.py
+++ b/indoteknik_custom/models/voucher.py
@@ -11,43 +11,47 @@ class Voucher(models.Model):
name = fields.Char(string='Name')
image = fields.Binary(string='Image')
code = fields.Char(string='Code', help='Kode voucher yang akan berlaku untuk pengguna')
+ voucher_category = fields.Many2many('product.public.category', string='Category Voucher',
+ help='Kategori Produk yang dapat menggunakan voucher ini')
description = fields.Text(string='Description')
discount_amount = fields.Float(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.'
- )
- visibility = fields.Selection(string='Visibility',
- selection=[
- ('public', 'Public'),
- ('private', 'Private')
- ],
- help='Select the visibility:\n'
- '- Public: Ditampilkan kepada seluruh pengguna.\n'
- '- Private: Tidak ditampilkan kepada seluruh pengguna.'
- )
+ 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.'
+ )
+ visibility = fields.Selection(string='Visibility',
+ selection=[
+ ('public', 'Public'),
+ ('private', 'Private')
+ ],
+ 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')
+ 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', 'applied_voucher_id', string='Order')
limit = fields.Integer(
- string='Limit',
+ string='Limit',
default=0,
help='Batas penggunaan voucher keseluruhan. Isi dengan angka 0 untuk penggunaan tanpa batas'
)
limit_user = fields.Integer(
- string='Limit User',
+ string='Limit User',
default=0,
help='Batas penggunaan voucher per pengguna. Misalnya, jika diisi dengan angka 1, maka setiap pengguna hanya dapat menggunakan voucher ini satu kali. Isi dengan angka 0 untuk penggunaan tanpa batas'
)
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')
+ 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=[
@@ -64,12 +68,40 @@ class Voucher(models.Model):
('person', "Account Individu"),
('company', "Account Company"),
])
+
+ def is_voucher_applicable(self, product_id):
+ if not self.voucher_category:
+ return True
+
+ public_categories = product_id.public_categ_ids
+
+ return bool(set(public_categories.ids) & set(self.voucher_category.ids))
+
+ def is_voucher_applicable_for_category(self, category):
+ if not self.voucher_category:
+ return True
+
+ if category.id in self.voucher_category.ids:
+ return True
+
+ category_path = []
+ current_cat = category
+ while current_cat:
+ category_path.append(current_cat.id)
+ current_cat = current_cat.parent_id
+
+ for voucher_cat in self.voucher_category:
+ if voucher_cat.id in category_path:
+ return True
+
+ return False
+
@api.constrains('description')
def _check_description_length(self):
for record in self:
if record.description and len(record.description) > 120:
raise ValidationError('Deskripsi tidak boleh lebih dari 120 karakter')
-
+
@api.constrains('limit', 'limit_user')
def _check_limit(self):
for rec in self:
@@ -87,7 +119,7 @@ class Voucher(models.Model):
def res_format(self):
datas = [voucher.format() for voucher in self]
return datas
-
+
def format(self):
ir_attachment = self.env['ir.attachment']
data = {
@@ -100,7 +132,7 @@ class Voucher(models.Model):
'remaining_time': self._res_remaining_time(),
}
return data
-
+
def _res_remaining_time(self):
seconds = self._get_remaining_time()
remaining_time = timedelta(seconds=seconds)
@@ -116,14 +148,31 @@ class Voucher(models.Model):
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())
-
+
def filter_order_line(self, order_line):
+ # import logging
+ # _logger = logging.getLogger(__name__)
+
voucher_manufacture_ids = self.collect_manufacture_ids()
results = []
+
+ if self.voucher_category and len(order_line) > 0:
+ for line in order_line:
+ category_applicable = False
+ for category in line['product_id'].public_categ_ids:
+ if self.is_voucher_applicable_for_category(category):
+ category_applicable = True
+ break
+
+ if not category_applicable:
+ # _logger.info("Cart contains product %s with non-applicable category - voucher %s cannot be used",
+ # line['product_id'].name, self.code)
+ return []
+
for line in order_line:
manufacture_id = line['product_id'].x_manufacture.id or None
if self.apply_type == 'brand' and manufacture_id not in voucher_manufacture_ids:
@@ -132,35 +181,36 @@ class Voucher(models.Model):
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': {} }
+ 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': {} }
+ result = {'all': 0, 'brand': {}}
if self.apply_type in ['all', 'shipping']:
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
+ result['all'] = min(discount_all,
+ self.max_discount_amount) if self.max_discount_amount > 0 else discount_all
else:
result['all'] = min(self.discount_amount, total['all'])
-
+
return result
for line in self.voucher_line:
@@ -173,99 +223,129 @@ class Voucher(models.Model):
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
+ discount_brand = min(discount_brand,
+ line.max_discount_amount) if line.max_discount_amount > 0 else discount_brand
else:
discount_brand = min(line.discount_amount, total_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):
- order_line = self.filter_order_line(order_line)
- amount_total = self.calc_total_order_line(order_line)
+
+ filtered_order_line = self.filter_order_line(order_line)
+
+ amount_total = self.calc_total_order_line(filtered_order_line)
+
discount = self.calc_discount_amount(amount_total)
+
return {
'discount': discount,
'total': amount_total,
'type': self.apply_type,
- 'valid_order': order_line
+ 'valid_order': filtered_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
-
+
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 discount if max_disc == 0 else min(discount, max_disc)
-
+
return 0
-
+
def get_active_voucher(self, domain):
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
domain += [
('start_time', '<=', current_time),
('end_time', '>=', current_time),
]
- vouchers = self.search(domain, order='min_purchase_amount ASC')
+ vouchers = self.search(domain, order='min_purchase_amount ASC')
return vouchers
-
+
def generate_tnc(self):
+ def format_currency(amount):
+ formatted_number = '{:,.0f}'.format(amount).replace(',', '.')
+ return f'Rp{formatted_number}'
+
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(
+ '<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>')
tnc.append(f'<li>Voucher tidak bisa digunakan apabila terdapat produk flash sale</li>')
- if len(self.voucher_line) > 0:
- brand_names = ', '.join([x.manufacture_id.x_name or '' 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())
+
+ if self.apply_type == 'brand':
+ tnc.append(f'<li>Voucher berlaku untuk produk dari brand terpilih</li>')
+ tnc.append(
+ f'<li>Nominal potongan produk yang bisa didapatkan hingga 10 Juta dengan minimum pembelian 10 Ribu.</li>')
+ elif self.apply_type == 'all' or self.apply_type == 'shipping':
+ if self.voucher_category:
+ category_names = ', '.join([cat.name for cat in self.voucher_category])
+ tnc.append(
+ f'<li>Voucher hanya berlaku untuk produk dalam kategori {category_names} dan sub-kategorinya</li>')
+ tnc.append(
+ f'<li>Voucher tidak dapat digunakan jika ada produk di keranjang yang tidak termasuk dalam kategori tersebut</li>')
+
+ if self.discount_type == 'percentage' and self.apply_type != 'brand':
+ tnc.append(
+ f'<li>Nominal potongan produk yang bisa didapatkan sebesar {self.max_discount_amount}% dengan minimum pembelian {self.min_purchase_amount}</li>')
+ elif self.discount_type == 'percentage' and self.apply_type != 'brand':
+ tnc.append(
+ f'<li>Nominal potongan produk yang bisa didapatkan sebesar {format_currency(self.discount_amount)} dengan minimum pembelian {format_currency(self.min_purchase_amount)}</li>')
+
tnc.append('</ol>')
-
- return ' '.join(tnc)
-
- def generate_detail_tnc(self):
- def format_currency(amount):
- formatted_number = '{:,.0f}'.format(amount).replace(',', '.')
- return f'Rp{formatted_number}'
-
- 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>')
+ # tnc.append(self.generate_detail_tnc())
return ' '.join(tnc)
- # copy semua data kalau diduplicate
+ # def generate_detail_tnc(self):
+ # def format_currency(amount):
+ # formatted_number = '{:,.0f}'.format(amount).replace(',', '.')
+ # return f'Rp{formatted_number}'
+ #
+ # 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)
+
+ # copy semua data kalau diduplicate
def copy(self, default=None):
default = dict(default or {})
voucher_lines = []
@@ -280,4 +360,4 @@ class Voucher(models.Model):
}))
default['voucher_line'] = voucher_lines
- return super(Voucher, self).copy(default) \ No newline at end of file
+ return super(Voucher, self).copy(default)
diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py
index 44393cf1..a6d08949 100644
--- a/indoteknik_custom/models/website_user_cart.py
+++ b/indoteknik_custom/models/website_user_cart.py
@@ -1,10 +1,11 @@
from odoo import fields, models, api
from datetime import datetime, timedelta
+
class WebsiteUserCart(models.Model):
_name = 'website.user.cart'
_rec_name = 'user_id'
-
+
user_id = fields.Many2one('res.users', string='User')
product_id = fields.Many2one('product.product', string='Product')
program_line_id = fields.Many2one('promotion.program.line', string='Program', help="Apply program")
@@ -18,7 +19,8 @@ class WebsiteUserCart(models.Model):
is_reminder = fields.Boolean(string='Reminder?')
phone_user = fields.Char(string='Phone', related='user_id.mobile')
price = fields.Float(string='Price', compute='_compute_price')
- program_product_id = fields.Many2one('product.product', string='Program Products', compute='_compute_program_product_ids')
+ program_product_id = fields.Many2one('product.product', string='Program Products',
+ compute='_compute_program_product_ids')
@api.depends('program_line_id')
def _compute_program_product_ids(self):
@@ -55,6 +57,12 @@ class WebsiteUserCart(models.Model):
product = self.product_id.v2_api_single_response(self.product_id)
res.update(product)
+ # Add category information
+ res['categories'] = [{
+ 'id': cat.id,
+ 'name': cat.name
+ } for cat in self.product_id.public_categ_ids]
+
# Check if the product's inventory location is in ID 57 or 83
target_locations = [57, 83]
stock_quant = self.env['stock.quant'].search([
@@ -90,7 +98,14 @@ class WebsiteUserCart(models.Model):
def get_products(self):
products = [x.get_product() for x in self]
-
+
+ for i, cart_item in enumerate(self):
+ if cart_item.product_id and i < len(products):
+ products[i]['categories'] = [{
+ 'id': cat.id,
+ 'name': cat.name
+ } for cat in cart_item.product_id.public_categ_ids]
+
return products
def get_product_by_user(self, user_id, selected=False, source=False):
@@ -121,10 +136,10 @@ class WebsiteUserCart(models.Model):
products = products_active.get_products()
return products
-
+
def get_user_checkout(self, user_id, voucher=False, voucher_shipping=False, source=False):
products = self.get_product_by_user(user_id=user_id, selected=True, source=source)
-
+
total_purchase = 0
total_discount = 0
for product in products:
@@ -132,9 +147,9 @@ class WebsiteUserCart(models.Model):
price = product['package_price'] * product['quantity']
else:
price = product['price']['price'] * product['quantity']
-
+
discount_price = price - product['price']['price_discount'] * product['quantity']
-
+
total_purchase += price
total_discount += discount_price
@@ -142,7 +157,7 @@ class WebsiteUserCart(models.Model):
discount_voucher = 0
discount_voucher_shipping = 0
order_line = []
-
+
if voucher or voucher_shipping:
for product in products:
if product['cart_type'] == 'promotion': continue
@@ -153,16 +168,16 @@ class WebsiteUserCart(models.Model):
'qty': product['quantity'],
'subtotal': product['subtotal']
})
-
+
if voucher:
voucher_info = voucher.apply(order_line)
discount_voucher = voucher_info['discount']['all']
subtotal -= discount_voucher
-
+
if voucher_shipping:
voucher_shipping_info = voucher_shipping.apply(order_line)
- discount_voucher_shipping = voucher_shipping_info['discount']['all']
-
+ discount_voucher_shipping = voucher_shipping_info['discount']['all']
+
tax = round(subtotal * 0.11)
grand_total = subtotal + tax
total_weight = sum(x['weight'] * x['quantity'] for x in products)
@@ -179,28 +194,31 @@ class WebsiteUserCart(models.Model):
'kg': total_weight,
'g': total_weight * 1000
},
- 'has_product_without_weight': any(not product.get('weight') or product.get('weight') == 0 for product in products),
+ 'has_product_without_weight': any(
+ not product.get('weight') or product.get('weight') == 0 for product in products),
'products': products
}
return result
-
+
def action_mail_reminder_to_checkout(self, limit=200):
user_ids = self.search([('is_reminder', '=', False)]).mapped('user_id')[:limit]
-
+
for user in user_ids:
latest_cart = self.search([('user_id', '=', user.id)], order='create_date desc', limit=1)
-
+
carts_to_remind = self.search([('user_id', '=', user.id)])
-
+
if latest_cart and not latest_cart.is_reminder:
for cart in carts_to_remind:
check = cart.check_product_flashsale(cart.product_id.id)
- if not cart.program_line_id and cart.product_id.default_code and not 'BOM' in cart.product_id.default_code and check['is_flashsale'] == False:
+ if not cart.program_line_id and cart.product_id.default_code and not 'BOM' in cart.product_id.default_code and \
+ check['is_flashsale'] == False:
cart.is_selected = True
- if cart.program_line_id or check['is_flashsale'] or cart.product_id.default_code and 'BOM' in cart.product_id.default_code:
+ if cart.program_line_id or check[
+ 'is_flashsale'] or cart.product_id.default_code and 'BOM' in cart.product_id.default_code:
cart.is_selected = False
cart.is_reminder = True
-
+
template = self.env.ref('indoteknik_custom.mail_template_user_cart_reminder_to_checkout')
template.send_mail(latest_cart.id, force_send=True)
@@ -234,8 +252,9 @@ class WebsiteUserCart(models.Model):
break
product_discount = subtotal_promo if cart.program_line_id or check['is_flashsale'] else subtotal
- total_discount += product_discount
- if check['is_flashsale'] == False and cart.product_id.default_code and not 'BOM' in cart.product_id.default_code:
+ total_discount += product_discount
+ if check[
+ 'is_flashsale'] == False and cart.product_id.default_code and not 'BOM' in cart.product_id.default_code:
voucher_product = subtotal * (discount_amount / 100.0)
total_voucher += voucher_product
@@ -253,14 +272,15 @@ class WebsiteUserCart(models.Model):
def check_product_flashsale(self, product_id):
product = product_id
current_time = datetime.utcnow()
- found_product = self.env['product.pricelist.item'].search([('product_id', '=', product_id), ('pricelist_id.is_flash_sale', '=', True)])
+ found_product = self.env['product.pricelist.item'].search(
+ [('product_id', '=', product_id), ('pricelist_id.is_flash_sale', '=', True)])
if found_product:
for found in found_product:
pricelist_flashsale = found.pricelist_id
if pricelist_flashsale.start_date <= current_time <= pricelist_flashsale.end_date:
- return {
+ return {
'is_flashsale': True,
'price': found.fixed_price
}
@@ -269,10 +289,9 @@ class WebsiteUserCart(models.Model):
'is_flashsale': False
}
- return {
+ return {
'is_flashsale': False
}
-
# if found_product:
# start_date = found_product.pricelist_id.start_date
@@ -291,26 +310,26 @@ class WebsiteUserCart(models.Model):
# return {
# 'is_flashsale': False
# }
-
+
def get_data_promo(self, program_line_id):
program_line_product = self.env['promotion.product'].search([
('program_line_id', '=', program_line_id)
- ])
-
+ ])
+
program_free_product = self.env['promotion.free_product'].search([
('program_line_id', '=', program_line_id)
- ])
+ ])
return program_line_product, program_free_product
-
+
def get_weight_product(self, program_line_id):
program_line_product = self.env['promotion.product'].search([
('program_line_id', '=', program_line_id)
- ])
-
+ ])
+
program_free_product = self.env['promotion.free_product'].search([
('program_line_id', '=', program_line_id)
- ])
-
+ ])
+
real_weight = 0.0
if program_line_product:
for product in program_line_product:
@@ -321,16 +340,16 @@ class WebsiteUserCart(models.Model):
real_weight += product.product_id.weight
return real_weight
-
+
def get_price_coret(self, program_line_id):
program_line_product = self.env['promotion.product'].search([
('program_line_id', '=', program_line_id)
- ])
-
+ ])
+
program_free_product = self.env['promotion.free_product'].search([
('program_line_id', '=', program_line_id)
- ])
-
+ ])
+
price_coret = 0.0
for product in program_line_product:
price = self.get_price_website(product.product_id.id)
@@ -340,20 +359,22 @@ class WebsiteUserCart(models.Model):
price = self.get_price_website(product.product_id.id)
price_coret += price['price'] * product.qty
- return price_coret
-
+ return price_coret
+
def get_price_website(self, product_id):
- price_website = self.env['product.pricelist.item'].search([('product_id', '=', product_id), ('pricelist_id', '=', 17022)], limit=1)
-
- price_tier = self.env['product.pricelist.item'].search([('product_id', '=', product_id), ('pricelist_id', '=', 17023)], limit=1)
-
+ price_website = self.env['product.pricelist.item'].search(
+ [('product_id', '=', product_id), ('pricelist_id', '=', 17022)], limit=1)
+
+ price_tier = self.env['product.pricelist.item'].search(
+ [('product_id', '=', product_id), ('pricelist_id', '=', 17023)], limit=1)
+
fixed_price = price_website.fixed_price if price_website else 0.0
discount = price_tier.price_discount if price_tier else 0.0
-
+
discounted_price = fixed_price - (fixed_price * discount / 100)
-
+
final_price = discounted_price / 1.11
-
+
return {
'price': final_price,
'web_price': discounted_price
@@ -365,4 +386,4 @@ class WebsiteUserCart(models.Model):
def format_currency(self, number):
number = int(number)
- return "{:,}".format(number).replace(',', '.') \ No newline at end of file
+ return "{:,}".format(number).replace(',', '.')
diff --git a/indoteknik_custom/views/customer_commision.xml b/indoteknik_custom/views/customer_commision.xml
index 9f0e1e8a..37df16ff 100644
--- a/indoteknik_custom/views/customer_commision.xml
+++ b/indoteknik_custom/views/customer_commision.xml
@@ -11,11 +11,12 @@
<field name="partner_ids" widget="many2many_tags"/>
<field name="commision_percent"/>
<field name="commision_amt" readonly="1"/>
- <field name="status" readonly="1" decoration-success="status == 'approved'" widget="badge" optional="show"/>
+ <field name="status" readonly="1" decoration-success="status == 'approved'" widget="badge"
+ optional="show"/>
<field name="payment_status" readonly="1"
- decoration-success="payment_status == 'payment'"
- decoration-danger="payment_status == 'pending'"
- widget="badge"/>
+ decoration-success="payment_status == 'payment'"
+ decoration-danger="payment_status == 'pending'"
+ widget="badge"/>
<field name="brand_ids" widget="many2many_tags"/>
<field name="grouped_so_number" readonly="1" optional="hide"/>
<field name="grouped_invoice_number" readonly="1" optional="hide"/>
@@ -47,89 +48,89 @@
<field name="model">customer.commision</field>
<field name="arch" type="xml">
<form>
-<!-- attrs="{'invisible': [('status', 'in', ['draft','pengajuan1','pengajuan2','pengajuan3','pengajuan4'])]}"-->
+ <!-- attrs="{'invisible': [('status', 'in', ['draft','pengajuan1','pengajuan2','pengajuan3','pengajuan4'])]}"-->
<header>
<button name="action_confirm_customer_commision"
- string="Confirm" type="object"
- attrs="{'invisible': [('status', 'in', ['approved','reject'])]}"
- options="{}"/>
+ string="Confirm" type="object"
+ attrs="{'invisible': [('status', 'in', ['approved','reject'])]}"
+ options="{}"/>
<button name="action_reject"
- string="Reject"
- attrs="{'invisible': [('status', 'in', ['approved','reject'])]}"
- type="object"/>
- <button name="button_draft"
- string="Reset to Draft"
- attrs="{'invisible': [('status', '!=', 'reject')]}"
- type="object"/>
+ string="Reject"
+ attrs="{'invisible': [('status', 'in', ['approved','reject'])]}"
+ type="object"/>
+ <button name="button_draft"
+ string="Reset to Draft"
+ attrs="{'invisible': [('status', '!=', 'reject')]}"
+ type="object"/>
<button name="action_confirm_customer_payment"
- string="Konfirmasi Pembayaran" type="object"
- options="{}"
- attrs="{'invisible': [('payment_status', '==', 'payment')], 'readonly': [('payment_status', '=', 'payment')]}"/>
+ string="Konfirmasi Pembayaran" type="object"
+ options="{}"
+ attrs="{'invisible': [('payment_status', '==', 'payment')], 'readonly': [('payment_status', '=', 'payment')]}"/>
<field name="status" widget="statusbar"
- statusbar_visible="draft,pengajuan1,pengajuan2,pengajuan3,pengajuan4,approved"
- statusbar_colors='{"reject":"red"}'/>
+ statusbar_visible="draft,pengajuan1,pengajuan2,pengajuan3,pengajuan4,approved"
+ statusbar_colors='{"reject":"red"}'/>
</header>
<sheet string="Customer Commision">
- <div class="oe_button_box" name="button_box"/>
+ <div class="oe_button_box" name="button_box"/>
+ <group>
<group>
+ <field name="number"/>
+ <field name="date_from"/>
+ <field name="partner_ids" widget="many2many_tags"/>
+ <field name="description"/>
+ <field name="commision_percent"/>
+ <field name="commision_amt"/>
+ <field name="commision_amt_text"/>
+ <field name="grouped_so_number" readonly="1"/>
+ <field name="grouped_invoice_number" readonly="1"/>
+ <field name="approved_by" readonly="1"/>
+ </group>
+ <group>
+ <div>
+ <button name="generate_customer_commision"
+ string="Generate Line"
+ type="object"
+ class="mr-2 oe_highlight"
+ />
+ </div>
+ <field name="date_to"/>
+ <field name="sales_id"/>
+ <field name="commision_type"/>
+ <field name="brand_ids" widget="many2many_tags"/>
+ <field name="notification" readonly="1"/>
+ <!-- <field name="status" readonly="1"/>-->
+ <field name="payment_status" readonly="1"/>
+ <field name="total_dpp"/>
+ </group>
+ </group>
+ <notebook>
+ <page string="Lines">
+ <field name="commision_lines"/>
+ </page>
+ <page string="Other Info" name="customer_commision_info">
<group>
- <field name="number"/>
- <field name="date_from"/>
- <field name="partner_ids" widget="many2many_tags"/>
- <field name="description"/>
- <field name="commision_percent"/>
- <field name="commision_amt"/>
- <field name="commision_amt_text"/>
- <field name="grouped_so_number" readonly="1"/>
- <field name="grouped_invoice_number" readonly="1"/>
- <field name="approved_by" readonly="1"/>
+ <field name="bank_name"/>
+ <field name="account_name"/>
+ <field name="bank_account"/>
+ <field name="note_transfer"/>
</group>
+ </page>
+ <page string="Finance Notes">
<group>
- <div>
- <button name="generate_customer_commision"
- string="Generate Line"
- type="object"
- class="mr-2 oe_highlight"
- />
- </div>
- <field name="date_to"/>
- <field name="sales_id"/>
- <field name="commision_type"/>
- <field name="brand_ids" widget="many2many_tags"/>
- <field name="notification" readonly="1"/>
-<!-- <field name="status" readonly="1"/>-->
- <field name="payment_status" readonly="1" />
- <field name="total_dpp"/>
+ <field name="note_finnance"/>
</group>
- </group>
- <notebook>
- <page string="Lines">
- <field name="commision_lines"/>
- </page>
- <page string="Other Info" name="customer_commision_info">
- <group>
- <field name="bank_name"/>
- <field name="account_name"/>
- <field name="bank_account"/>
- <field name="note_transfer"/>
- </group>
- </page>
- <page string="Finance Notes">
- <group>
- <field name="note_finnance"/>
- </group>
- </page>
- </notebook>
- </sheet>
- <div class="oe_chatter">
- <field name="message_follower_ids" widget="mail_followers"/>
- <field name="message_ids" widget="mail_thread"/>
- </div>
+ </page>
+ </notebook>
+ </sheet>
+ <div class="oe_chatter">
+ <field name="message_follower_ids" widget="mail_followers"/>
+ <field name="message_ids" widget="mail_thread"/>
+ </div>
</form>
</field>
</record>
- <!-- Wizard for Reject Reason -->
+ <!-- Wizard for Reject Reason -->
<record id="view_reject_reason_wizard_form" model="ir.ui.view">
<field name="name">reject.reason.commision.form</field>
<field name="model">reject.reason.commision</field>
@@ -160,7 +161,12 @@
<field name="arch" type="xml">
<search string="Search Customer Commision">
<field name="partner_ids"/>
- </search>
+ <group expand="0" string="Group By">
+ <filter string="Partner" name="group_partner"
+ domain="[]"
+ context="{'group_by':'partner_ids'}"/>
+ </group>
+ </search>
</field>
</record>
@@ -173,17 +179,17 @@
</record>
<menuitem id="menu_customer_commision_acct"
- name="Customer Commision"
- action="customer_commision_action"
- parent="account.menu_finance_entries"
- sequence="113"
+ name="Customer Commision"
+ action="customer_commision_action"
+ parent="account.menu_finance_entries"
+ sequence="113"
/>
<menuitem id="menu_customer_commision_sales"
- name="Customer Commision"
- action="customer_commision_action"
- parent="sale.product_menu_catalog"
- sequence="101"
+ name="Customer Commision"
+ action="customer_commision_action"
+ parent="sale.product_menu_catalog"
+ sequence="101"
/>
<record id="customer_rebate_tree" model="ir.ui.view">
@@ -217,34 +223,34 @@
<field name="arch" type="xml">
<form>
<sheet string="Customer Rebate">
- <div class="oe_button_box" name="button_box"/>
+ <div class="oe_button_box" name="button_box"/>
+ <group>
<group>
- <group>
- <field name="date_from"/>
- <field name="partner_id"/>
- <field name="target_1st"/>
- <field name="target_2nd"/>
- <field name="dpp_q1"/>
- <field name="dpp_q2"/>
- <field name="dpp_q3"/>
- <field name="dpp_q4"/>
- </group>
- <group>
- <field name="date_to"/>
- <field name="description"/>
- <field name="achieve_1"/>
- <field name="achieve_2"/>
- <field name="status_q1"/>
- <field name="status_q2"/>
- <field name="status_q3"/>
- <field name="status_q4"/>
- </group>
+ <field name="date_from"/>
+ <field name="partner_id"/>
+ <field name="target_1st"/>
+ <field name="target_2nd"/>
+ <field name="dpp_q1"/>
+ <field name="dpp_q2"/>
+ <field name="dpp_q3"/>
+ <field name="dpp_q4"/>
+ </group>
+ <group>
+ <field name="date_to"/>
+ <field name="description"/>
+ <field name="achieve_1"/>
+ <field name="achieve_2"/>
+ <field name="status_q1"/>
+ <field name="status_q2"/>
+ <field name="status_q3"/>
+ <field name="status_q4"/>
</group>
- </sheet>
- <div class="oe_chatter">
- <field name="message_follower_ids" widget="mail_followers"/>
- <field name="message_ids" widget="mail_thread"/>
- </div>
+ </group>
+ </sheet>
+ <div class="oe_chatter">
+ <field name="message_follower_ids" widget="mail_followers"/>
+ <field name="message_ids" widget="mail_thread"/>
+ </div>
</form>
</field>
</record>
@@ -257,16 +263,16 @@
</record>
<menuitem id="menu_customer_rebate_acct"
- name="Customer Rebate"
- action="customer_rebate_action"
- parent="account.menu_finance_entries"
- sequence="114"
+ name="Customer Rebate"
+ action="customer_rebate_action"
+ parent="account.menu_finance_entries"
+ sequence="114"
/>
<menuitem id="menu_customer_rebate_sales"
- name="Customer Rebate"
- action="customer_rebate_action"
- parent="sale.product_menu_catalog"
- sequence="102"
+ name="Customer Rebate"
+ action="customer_rebate_action"
+ parent="sale.product_menu_catalog"
+ sequence="102"
/>
</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/voucher.xml b/indoteknik_custom/views/voucher.xml
index ae958f05..78e42969 100755
--- a/indoteknik_custom/views/voucher.xml
+++ b/indoteknik_custom/views/voucher.xml
@@ -27,63 +27,71 @@
<group>
<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="name" required="1"/>
+ <field name="code" required="1"/>
+ <field name="voucher_category" widget="many2many"/>
+ <field name="visibility" required="1"/>
<field name="start_time" required="1"/>
<field name="end_time" required="1"/>
<field name="limit" required="1"/>
<field name="limit_user" required="1"/>
- <field name="apply_type" required="1" />
- <field name="account_type" required="1" />
- <field name="show_on_email" />
- <field name="excl_pricelist_ids" widget="many2many_tags" domain="[('id', 'in', [4, 15037, 15038, 15039, 17023, 17024, 17025, 17026,17027])]"/>
+ <field name="apply_type" required="1"/>
+ <field name="account_type" required="1"/>
+ <field name="show_on_email"/>
+ <field name="excl_pricelist_ids" widget="many2many_tags"
+ domain="[('id', 'in', [4, 15037, 15038, 15039, 17023, 17024, 17025, 17026,17027])]"/>
</group>
- <group string="Discount Settings" attrs="{'invisible': [('apply_type', 'not in', ['all', 'shipping'])]}">
- <field name="min_purchase_amount" widget="monetary" required="1" />
- <field name="discount_type" attrs="{'invisible': [('apply_type','not in', ['all', 'shipping'])], 'required': [('apply_type', 'in', ['all', 'shipping'])]}" />
+ <group string="Discount Settings"
+ attrs="{'invisible': [('apply_type', 'not in', ['all', 'shipping'])]}">
+ <field name="min_purchase_amount" widget="monetary" required="1"/>
+ <field name="discount_type"
+ attrs="{'invisible': [('apply_type','not in', ['all', 'shipping'])], 'required': [('apply_type', 'in', ['all', 'shipping'])]}"/>
- <label for="max_discount_amount" string="Discount Amount" />
+ <label for="max_discount_amount" string="Discount Amount"/>
<div class="d-flex align-items-center">
- <span
- class="mr-1 font-weight-bold"
- attrs="{'invisible': [('discount_type', '!=', 'fixed_price')]}"
+ <span
+ class="mr-1 font-weight-bold"
+ attrs="{'invisible': [('discount_type', '!=', 'fixed_price')]}"
>
Rp
</span>
- <field class="mb-0" name="discount_amount" required="1" />
- <span
- class="ml-1 font-weight-bold"
- attrs="{'invisible': [('discount_type', '!=', 'percentage')]}"
+ <field class="mb-0" name="discount_amount" required="1"/>
+ <span
+ class="ml-1 font-weight-bold"
+ attrs="{'invisible': [('discount_type', '!=', 'percentage')]}"
>
%
</span>
</div>
- <field name="max_discount_amount" widget="monetary" required="1" attrs="{'invisible': [('discount_type', '!=', 'percentage')]}"/>
+ <field name="max_discount_amount" widget="monetary" required="1"
+ attrs="{'invisible': [('discount_type', '!=', 'percentage')]}"/>
</group>
</group>
<notebook>
- <page name="voucher_line" string="Voucher Line" attrs="{'invisible': [('apply_type', '!=', 'brand')]}">
+ <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')]}" />
+ <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..." />
+ <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" />
+ <field name="terms_conditions"/>
</page>
<page name="order_page" string="Orders">
- <field name="order_ids" readonly="1" />
+ <field name="order_ids" readonly="1"/>
</page>
</notebook>
</sheet>
@@ -92,10 +100,10 @@
</record>
<menuitem id="voucher"
- name="Voucher"
- parent="website_sale.menu_catalog"
- sequence="1"
- action="voucher_action"
+ name="Voucher"
+ parent="website_sale.menu_catalog"
+ sequence="1"
+ action="voucher_action"
/>
</data>
</odoo> \ No newline at end of file