summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIT Fixcomart <it@fixcomart.co.id>2024-01-04 02:27:45 +0000
committerIT Fixcomart <it@fixcomart.co.id>2024-01-04 02:27:45 +0000
commit63abd2dc32f952af7234f3d6a7774cbb8c7bcb47 (patch)
treeb4cee127fc7d467b33cef4ffae9218f8acb9aeaa
parent13b31fc3d89957d23582efb2c51ab143ca1d425a (diff)
parent717cb3b43c729e265603b3df61234c0b430742a7 (diff)
Merged in change/feature/promotion-program (pull request #133)
Change/feature/promotion program
-rw-r--r--indoteknik_api/controllers/api_v1/cart.py21
-rw-r--r--indoteknik_api/controllers/api_v1/promotion.py22
-rwxr-xr-xindoteknik_custom/models/__init__.py2
-rw-r--r--indoteknik_custom/models/promotion/promotion_program.py1
-rw-r--r--indoteknik_custom/models/promotion/promotion_program_line.py10
-rw-r--r--indoteknik_custom/models/solr/__init__.py4
-rw-r--r--indoteknik_custom/models/solr/promotion_program.py68
-rw-r--r--indoteknik_custom/models/solr/promotion_program_line.py69
-rw-r--r--indoteknik_custom/models/website_user_cart.py20
-rw-r--r--indoteknik_custom/views/promotion/promotion_program.xml1
-rw-r--r--indoteknik_custom/views/promotion/promotion_program_line.xml1
11 files changed, 204 insertions, 15 deletions
diff --git a/indoteknik_api/controllers/api_v1/cart.py b/indoteknik_api/controllers/api_v1/cart.py
index 8ef2c1c1..907c8288 100644
--- a/indoteknik_api/controllers/api_v1/cart.py
+++ b/indoteknik_api/controllers/api_v1/cart.py
@@ -36,18 +36,21 @@ class Cart(controller.Controller):
def create_or_update_cart(self, user_id, **kw):
# Convert input values to appropriate types
user_id = int(user_id)
- product_id = int(kw.get('product_id', 0))
- qty = int(kw.get('qty', 0))
- source = kw.get('source')
- is_selected = kw.get('selected', False)
+ product_id = kw.get('product_id', 0)
+ product_id = False if product_id == 'null' or not product_id else int(product_id)
+
program_line_id = kw.get('program_line_id', False)
program_line_id = False if program_line_id == 'null' or not program_line_id else int(program_line_id)
+ qty = int(kw.get('qty', 0))
+ source = kw.get('source')
+
+ is_selected = kw.get('selected', False)
is_selected = is_selected in ('true', True)
# Check required fields
- if not user_id or not product_id or not qty:
- return self.response(code=400, description='user_id, product_id and qty is required')
+ if not user_id:
+ return self.response(code=400, description='user_id is required')
website_user_cart = request.env['website.user.cart']
@@ -97,9 +100,15 @@ class Cart(controller.Controller):
def delete_cart_by_user_id(self, user_id, **kw):
user_id = int(user_id)
query = [('user_id', '=', user_id)]
+
+ ids = kw.get('ids')
+ if ids:
+ query += [('id', 'in', [int(x) for x in ids.split(',')])]
+
product_ids = kw.get('product_ids')
if product_ids:
query += [('product_id', 'in', [int(x) for x in product_ids.split(',')])]
+
cart = request.env['website.user.cart'].search(query).unlink()
return self.response(cart)
diff --git a/indoteknik_api/controllers/api_v1/promotion.py b/indoteknik_api/controllers/api_v1/promotion.py
index f84b8c1c..221f6e10 100644
--- a/indoteknik_api/controllers/api_v1/promotion.py
+++ b/indoteknik_api/controllers/api_v1/promotion.py
@@ -6,6 +6,28 @@ from datetime import datetime
class Promotion(controller.Controller):
prefix = '/api/v1/'
+
+ @http.route(prefix + 'program-line/<id>/stock', auth='public', methods=['GET', 'OPTIONS'])
+ @controller.Controller.must_authorized()
+ def get_promotion_stock(self, id):
+ program_line = request.env['promotion.program.line'].browse(int(id))
+ if not program_line.id:
+ return self.response(code=400, description='program not found')
+
+ user_data = self.verify_user_token()
+
+ limit_qty = program_line._res_limit_qty()
+ remaining_qty = program_line._get_remaining_qty(user_data)
+
+ percent_remaining = 0
+ if limit_qty['all'] > 0:
+ percent_remaining = (limit_qty['all'] - remaining_qty['all']) / limit_qty['all'] * 100
+
+ return self.response({
+ 'limit_qty': limit_qty,
+ 'remaining_qty': remaining_qty,
+ 'used_percentage': percent_remaining,
+ })
@http.route(prefix + 'promotion/<id>', auth='public', methods=['GET'])
diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py
index c6f61ffa..e7bcd323 100755
--- a/indoteknik_custom/models/__init__.py
+++ b/indoteknik_custom/models/__init__.py
@@ -81,12 +81,12 @@ from . import po_sync_price
from . import base_import_import
from . import product_attribute
from . import mrp_production
+from . import promotion
from . import solr
from . import cost_centre
from . import account_account
from . import account_move_line
from . import stock_scheduler_compute
-from . import promotion
from . import sale_orders_multi_update
from . import quotation_so_multi_update
from . import product_monitoring
diff --git a/indoteknik_custom/models/promotion/promotion_program.py b/indoteknik_custom/models/promotion/promotion_program.py
index 29aaa753..1a1ee6bf 100644
--- a/indoteknik_custom/models/promotion/promotion_program.py
+++ b/indoteknik_custom/models/promotion/promotion_program.py
@@ -6,6 +6,7 @@ class PromotionProgram(models.Model):
name = fields.Char(string="Name")
banner = fields.Binary(string="Banner")
+ image = fields.Binary(string="Image")
icon = fields.Binary(string="Icon", help="Image 1:1 ratio")
icon_top = fields.Binary(string="Icon Top", help="Icon ini ditampilkan sebagai atribut pada atas gambar di product card pada website")
icon_bottom = fields.Binary(string="Icon Bottom", help="Icon ini ditampilkan sebagai atribut pada bawah gambar di product card pada website")
diff --git a/indoteknik_custom/models/promotion/promotion_program_line.py b/indoteknik_custom/models/promotion/promotion_program_line.py
index 34a0fbb2..d77123ce 100644
--- a/indoteknik_custom/models/promotion/promotion_program_line.py
+++ b/indoteknik_custom/models/promotion/promotion_program_line.py
@@ -13,7 +13,6 @@ class PromotionProgramLine(models.Model):
("discount_loading", "Discount Loading"),
("merchandise", "Merchandise")
], 'Type')
- image = fields.Binary(string="Image")
package_limit = fields.Integer('Package limit')
package_limit_user = fields.Integer('Package limit / user')
@@ -96,16 +95,21 @@ class PromotionProgramLine(models.Model):
weight = 0
if not any(x['package_weight'] == 0 for x in merged_products):
weight = sum(x['package_weight'] for x in merged_products)
-
+
+ # Sum of products and free products in 1 package quantity
+ products_total = sum(x['price']['price_discount'] * x['qty'] / qty for x in products)
+ free_products_total = sum(x['price']['price_discount'] * x['qty'] / qty for x in free_products)
+ package_price = products_total + free_products_total
+
response = {
'id': self.id,
'name': self.name,
- 'image': ir_attachment.api_image(self._name, 'image', self.id),
'remaining_time': self._get_remaining_time(),
'promotion_type': self._res_promotion_type(),
'limit_qty': limit_qty,
'remaining_qty': remaining_qty,
'used_percentage': percent_remaining,
+ 'package_price': package_price,
'price': {
'price': self.price,
'price_discount': self.price,
diff --git a/indoteknik_custom/models/solr/__init__.py b/indoteknik_custom/models/solr/__init__.py
index f2d13116..606c0035 100644
--- a/indoteknik_custom/models/solr/__init__.py
+++ b/indoteknik_custom/models/solr/__init__.py
@@ -8,4 +8,6 @@ from . import website_categories_homepage
from . import x_manufactures
from . import x_banner_banner
from . import product_public_category
-from . import x_banner_category \ No newline at end of file
+from . import x_banner_category
+from . import promotion_program
+from . import promotion_program_line \ No newline at end of file
diff --git a/indoteknik_custom/models/solr/promotion_program.py b/indoteknik_custom/models/solr/promotion_program.py
new file mode 100644
index 00000000..0d417b3e
--- /dev/null
+++ b/indoteknik_custom/models/solr/promotion_program.py
@@ -0,0 +1,68 @@
+from odoo import models, api
+from datetime import datetime
+from pytz import timezone
+from typing import Type
+import pysolr
+
+
+class PromotionProgram(models.Model):
+ _inherit = 'promotion.program'
+ _solr_schema = 'promotion_programs'
+
+ def solr(self) -> Type[pysolr.Solr]:
+ return self.env['apache.solr'].connect(self._solr_schema)
+
+ def _create_solr_queue(self, function_name: str):
+ for rec in self:
+ self.env['apache.solr.queue'].create_unique({
+ 'res_model': self._name,
+ 'res_id': rec.id,
+ 'function_name': function_name
+ })
+
+ def _sync_to_solr(self):
+ ir_attachment = self.env['ir.attachment']
+ solr_model = self.env['apache.solr']
+
+ for rec in self:
+ document = solr_model.get_doc(self._solr_schema, rec.id)
+ document.update({
+ 'id': rec.id,
+ 'name_s': rec.name,
+ 'banner_s': ir_attachment.api_image(self._name, 'banner', rec.id) if rec.banner else '',
+ 'keywords': [x.name for x in rec.keyword_ids],
+ 'line_ids': [x.id for x in rec.program_line],
+ 'start_time_s': self._time_format(rec.start_time),
+ 'end_time_s': self._time_format(rec.end_time),
+ 'applies_to_s': rec.applies_to,
+ 'icon_s': ir_attachment.api_image(self._name, 'icon', rec.id) if rec.icon else '',
+ 'icon_top_s': ir_attachment.api_image(self._name, 'icon_top', rec.id) if rec.icon_top else '',
+ 'icon_bottom_s': ir_attachment.api_image(self._name, 'icon_bottom', rec.id) if rec.icon_bottom else '',
+ })
+
+ self.solr().add([document])
+
+ self.solr().commit()
+
+ def _time_format(self, object) -> str:
+ time = ''
+ tz_jakarta = timezone('Asia/Jakarta')
+ if isinstance(object, datetime):
+ time = object.astimezone(tz_jakarta).strftime("%Y-%m-%d %H:%M:%S")
+ return time
+
+ @api.model
+ def create(self, vals):
+ self._create_solr_queue('_sync_to_solr')
+ return super(PromotionProgram, self).create(vals)
+
+ def write(self, vals):
+ self._create_solr_queue('_sync_to_solr')
+ return super(PromotionProgram, self).write(vals)
+
+ @api.constrains('program_line')
+ def constrains_program_line(self):
+ for rec in self:
+ for line in rec.program_line:
+ line._create_solr_queue('_sync_to_solr')
+
diff --git a/indoteknik_custom/models/solr/promotion_program_line.py b/indoteknik_custom/models/solr/promotion_program_line.py
new file mode 100644
index 00000000..6e182324
--- /dev/null
+++ b/indoteknik_custom/models/solr/promotion_program_line.py
@@ -0,0 +1,69 @@
+from odoo import models, api
+from typing import Type
+import pysolr
+import json
+
+
+class PromotionProgramLine(models.Model):
+ _inherit = 'promotion.program.line'
+ _solr_schema = 'promotion_program_lines'
+
+ def solr(self) -> Type[pysolr.Solr]:
+ return self.env['apache.solr'].connect(self._solr_schema)
+
+ def _create_solr_queue(self, function_name: str):
+ for rec in self:
+ self.env['apache.solr.queue'].create_unique({
+ 'res_model': self._name,
+ 'res_id': rec.id,
+ 'function_name': function_name
+ })
+
+ def _sync_to_solr(self):
+ solr_model = self.env['apache.solr']
+
+ for rec in self:
+ document = solr_model.get_doc(self._solr_schema, rec.id)
+
+ products = [{
+ 'product_id': x.product_id.id,
+ 'qty': x.qty
+ } for x in rec.product_ids]
+
+ free_products = [{
+ 'product_id': x.product_id.id,
+ 'qty': x.qty
+ } for x in rec.free_product_ids]
+
+ promotion_type = rec._res_promotion_type()
+
+ document.update({
+ 'id': rec.id,
+ 'program_id_i': rec.program_id.id,
+ 'name_s': rec.name,
+ 'image_s': self.env['ir.attachment'].api_image(self._name, 'image', rec.id) if rec.image else '',
+ 'type_value_s': promotion_type['value'],
+ 'type_label_s': promotion_type['label'],
+ 'package_limit_i': rec.package_limit,
+ 'package_limit_user_i': rec.package_limit_user,
+ 'package_limit_trx_i': rec.package_limit_trx,
+ 'price_f': rec.price,
+ 'product_ids': [x.product_id.id for x in rec.product_ids],
+ 'products_s': json.dumps(products),
+ 'free_product_ids': [x.product_id.id for x in rec.free_product_ids],
+ 'free_products_s': json.dumps(free_products),
+ 'total_qty_i': sum([x.qty for x in rec.product_ids] + [x.qty for x in rec.free_product_ids]),
+ })
+
+ self.solr().add([document])
+
+ self.solr().commit()
+
+ @api.model
+ def create(self, vals):
+ self._create_solr_queue('_sync_to_solr')
+ return super(PromotionProgramLine, self).create(vals)
+
+ def write(self, vals):
+ self._create_solr_queue('_sync_to_solr')
+ return super(PromotionProgramLine, self).write(vals)
diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py
index bbc14c88..eaa5f009 100644
--- a/indoteknik_custom/models/website_user_cart.py
+++ b/indoteknik_custom/models/website_user_cart.py
@@ -51,7 +51,9 @@ class WebsiteUserCart(models.Model):
return res
def get_products(self):
- return [x.get_product() for x in self]
+ products = [x.get_product() for x in self]
+
+ return products
def get_product_by_user(self, user_id, selected=False, source=False):
user_id = int(user_id)
@@ -75,8 +77,20 @@ class WebsiteUserCart(models.Model):
def get_user_checkout(self, user_id, voucher=False, source=False):
products = self.get_product_by_user(user_id=user_id, selected=True, source=source)
- total_purchase = sum(x['price']['price'] * x['quantity'] for x in products)
- total_discount = sum((x['price']['price'] - x['price']['price_discount']) * x['quantity'] for x in products)
+
+ total_purchase = 0
+ total_discount = 0
+ for product in products:
+ if product['cart_type'] == 'promotion':
+ 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
+
subtotal = total_purchase - total_discount
discount_voucher = 0
if voucher:
diff --git a/indoteknik_custom/views/promotion/promotion_program.xml b/indoteknik_custom/views/promotion/promotion_program.xml
index f8432d8a..724f80c7 100644
--- a/indoteknik_custom/views/promotion/promotion_program.xml
+++ b/indoteknik_custom/views/promotion/promotion_program.xml
@@ -22,6 +22,7 @@
<group>
<field name="name" />
<field name="banner" widget="image" height="160" />
+ <field name="image" widget="image" height="160" />
<field name="keyword_ids" widget="many2many_tags" />
</group>
<group>
diff --git a/indoteknik_custom/views/promotion/promotion_program_line.xml b/indoteknik_custom/views/promotion/promotion_program_line.xml
index db6d5252..346a08c9 100644
--- a/indoteknik_custom/views/promotion/promotion_program_line.xml
+++ b/indoteknik_custom/views/promotion/promotion_program_line.xml
@@ -23,7 +23,6 @@
<group>
<field name="name" />
<field name="promotion_type" />
- <field name="image" widget="image" height="160" />
</group>
<group>
<field name="package_limit" />