summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-09-18 16:20:15 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-09-18 16:20:15 +0700
commitadbc9b985f1c5fb2b2f41f79c686b3a573003e62 (patch)
tree27ca97d7c6540ccaf3556efadb9c8b439ac2f2fb
parent0ace4356bdbe27c3acd75c33d5259ef950eecb24 (diff)
Update promotion program feature
-rw-r--r--indoteknik_api/controllers/api_v1/sale_order.py39
-rw-r--r--indoteknik_custom/models/promotion_program_line.py53
-rwxr-xr-xindoteknik_custom/models/sale_order.py54
-rw-r--r--indoteknik_custom/models/website_user_cart.py14
-rwxr-xr-xindoteknik_custom/views/sale_order.xml1
5 files changed, 113 insertions, 48 deletions
diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py
index adc89f66..2c6958d8 100644
--- a/indoteknik_api/controllers/api_v1/sale_order.py
+++ b/indoteknik_api/controllers/api_v1/sale_order.py
@@ -302,43 +302,32 @@ class SaleOrder(controller.Controller):
source = params['value']['source']
products = user_cart.get_product_by_user(user_id=user_id, selected=True, source=source)
for product in products:
- total_qty = product['quantity']
price_unit = product['price']['price']
price_discount =product['price']['discount_percentage']
- if product['program'] and product['program']['type']['value'] != 'special_price':
- total_qty += sum(x['quantity'] for x in product['program']['items'])
- price_unit = product['subtotal'] / total_qty
- price_discount = 0
-
- param = {
+ order_line = {
'company_id': 1,
'order_id': sale_order.id,
'price_unit': price_unit,
- 'discount': price_discount
- }
-
- primary_product = {
- **param,
+ 'discount': price_discount,
'product_id': product['id'],
'product_uom_qty': product['quantity']
}
+
if product['program']:
- primary_product.update({
+ order_line.update({
'program_line_id': product['program']['id']
})
- parameters.append(primary_product)
-
- if not product['program']:
- continue
-
- for item in product['program']['items']:
- parameters.append({
- **param,
- 'product_id': item['id'],
- 'product_uom_qty': item['quantity'],
- })
+
+ parameters.append(order_line)
+ # if product['program'] and product['program']['type']['value'] != 'special_price':
+ # total_qty += sum(x['quantity'] for x in product['program']['items'])
+ # price_unit = product['subtotal'] / total_qty
+ # price_discount = 0
request.env['sale.order.line'].create(parameters)
+
+ if any(x['program'] for x in products):
+ sale_order.apply_promotion_program()
voucher_code = params['value']['voucher']
voucher = request.env['voucher'].search([('code', '=', voucher_code)])
@@ -347,7 +336,7 @@ class SaleOrder(controller.Controller):
sale_order.apply_voucher()
cart_ids = [x['cart_id'] for x in products]
- user_cart.browse(cart_ids).unlink()
+ # user_cart.browse(cart_ids).unlink()
return self.response({
'id': sale_order.id,
'name': sale_order.name
diff --git a/indoteknik_custom/models/promotion_program_line.py b/indoteknik_custom/models/promotion_program_line.py
index 077f7e12..71418d6c 100644
--- a/indoteknik_custom/models/promotion_program_line.py
+++ b/indoteknik_custom/models/promotion_program_line.py
@@ -1,5 +1,6 @@
from odoo import fields, models, api
from datetime import datetime
+import math
class PromotionProgramLine(models.Model):
@@ -14,15 +15,21 @@ class PromotionProgramLine(models.Model):
("fixed_price", "Fixed Price"),
], string="Discount Type")
discount_amount = fields.Float(string="Discount Amount")
- promotion_type = fields.Selection(selection=[
- ("special_price", "Special Price"),
- ("bundling", "Bundling"),
- ("discount_loading", "Discount Loading"),
- ("merchandise", "Merchandise")
- ], string="Promotion Type")
- minimum_purchase_qty = fields.Integer(string="Minimum Purchase Qty", help="Minimum Qty to applied discount loading")
- applies_multiply = fields.Boolean(string="Applies Multiply", help="Is applies multiply")
- limit_qty = fields.Integer(string="Limit Qty", help="Limit Qty product in promotion")
+ promotion_type = fields.Selection(string="Promotion Type",
+ selection=[
+ ("special_price", "Special Price"),
+ ("bundling", "Bundling"),
+ ("discount_loading", "Discount Loading"),
+ ("merchandise", "Merchandise")
+ ],
+ help='- Special Price: Potongan harga barang.\n'
+ '- Bundling: Menggabungkan beberapa produk menjadi satu paket.\n'
+ '- Discount Loading: Semakin banyak unit yang dibeli maka semakin murah harga yang dibayar.\n'
+ '- Merchandise: Pemberian barang gratis.'
+ )
+ minimum_purchase_qty = fields.Integer(string="Minimum Purchase Qty", help="Minimum unit barang yang perlu dibeli untuk dapat menggunakan promosi")
+ applies_multiply = fields.Boolean(string="Applies Multiply", help="Diterapkan berlipat ganda")
+ limit_qty = fields.Integer(string="Limit Qty", help="Kuota promosi keseluruhan")
limit_qty_user = fields.Integer(string="Limit Qty / User", help="Limit Qty per User")
limit_qty_transaction = fields.Integer(string="Limit Qty / Transaction", help="Limit Qty per Transaction")
line_free_item = fields.One2many(comodel_name="promotion.program.free_item", inverse_name="line_id", string="Line Free Item")
@@ -118,7 +125,7 @@ class PromotionProgramLine(models.Model):
'label': dict(self._fields['promotion_type'].selection).get(self.promotion_type)
}
- def format(self, user = None):
+ def format(self, user = None, qty = 0):
ir_attachment = self.env['ir.attachment']
product_price = self.product_id.calculate_website_price()
limit_qty = self._res_limit_qty()
@@ -126,7 +133,19 @@ class PromotionProgramLine(models.Model):
percent_remaining = 0
if limit_qty['all'] > 0:
percent_remaining = (limit_qty['all'] - remaining_qty['all']) / limit_qty['all'] * 100
- return {
+
+ qty_can_buy = min(remaining_qty['user'], qty)
+ if self.limit_qty_transaction > 0:
+ qty_can_buy = min(qty_can_buy, self.limit_qty_transaction)
+
+ multiplier = 0
+ if qty_can_buy > self.minimum_purchase_qty:
+ multiplier = 1
+
+ if self.applies_multiply and qty_can_buy > 0:
+ multiplier = math.floor(qty_can_buy / self.minimum_purchase_qty)
+
+ response = {
'id': self.id,
'name': self.name,
'image': ir_attachment.api_image('promotion.program.line', 'image', self.id),
@@ -137,14 +156,16 @@ class PromotionProgramLine(models.Model):
'limit_qty': limit_qty,
'remaining_qty': remaining_qty,
'used_percentage': percent_remaining,
- 'price': self.calculate_price(price=product_price)
+ 'price': self.calculate_price(price=product_price),
+ 'items': [{
+ 'product_id': line.product_id.id,
+ 'quantity': line.qty * multiplier
+ } for line in self.line_free_item]
}
+
+ return response
def res_format(self, user):
data = [x.format(user) for x in self]
return data
-
- def res_format_cart(self, user):
- data = self.format(user)
- return data
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index 8317e1fd..2510d9e5 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -78,6 +78,7 @@ class SaleOrder(models.Model):
amount_voucher_disc = fields.Float(string='Voucher Discount')
source_id = fields.Many2one('utm.source', 'Source', domain="[('id', 'in', [32, 59, 60, 61])]")
estimated_arrival_days = fields.Integer('Estimated Arrival Days', default=0)
+ picking_iu_id = fields.Many2one('stock.picking', 'Picking IU')
def _compute_purchase_total(self):
for order in self:
@@ -447,6 +448,59 @@ class SaleOrder(models.Model):
line.discount = line.initial_discount
line.initial_discount = False
+ def apply_promotion_program(self):
+ userdata = {
+ 'user_id': self.partner_id.user_id.id,
+ 'partner_id': self.partner_id.id
+ }
+
+ iu_items = []
+ for line in self.order_line:
+ promotion = line.program_line_id.format(user=userdata, qty=line.product_uom_qty)
+ if promotion['type']['value'] == 'merchandise':
+ iu_items += filter(lambda x: x['quantity'] > 0, promotion['items'])
+
+ if len(iu_items) > 0:
+ self._create_promotion_program_iu_docs(iu_items)
+
+ def _create_promotion_program_iu_docs(self, items):
+ default = {
+ 'picking_type_id': 33, # PT Indoteknik (Bandengan): Internal Transfers
+ 'location_id': 57, # BU/Stock
+ 'location_dest_id': 49, # Virtual Locations/Internal Use
+ 'account_id': 596, # Biaya awareness
+ 'product_uom': 1 # Unit
+ }
+
+ picking_type = self.env['stock.picking.type'].browse(default['picking_type_id'])
+ picking = self.env['stock.picking'].create({
+ 'name': picking_type.sequence_id.next_by_id(),
+ 'picking_type_id': default['picking_type_id'],
+ 'partner_id': self.partner_id.id,
+ 'real_shipping_id': self.real_shipping_id.id,
+ 'location_id': default['location_id'],
+ 'location_dest_id': default['location_dest_id'],
+ 'account_id': default['account_id'],
+ 'origin': self.display_name,
+ 'is_internal_use': True
+ })
+
+ product_model = self.env['product.product']
+ for item in items:
+ picking.move_ids_without_package.create({
+ 'product_id': item['product_id'],
+ 'name': product_model.browse(item['product_id']).display_name,
+ 'product_uom_qty': item['quantity'],
+ 'product_uom': default['product_uom'],
+ 'location_id': default['location_id'],
+ 'location_dest_id': default['location_dest_id'],
+ 'picking_id': picking.id
+ })
+
+ self.picking_iu_id = picking.id
+
+
+
diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py
index b3695ba1..1468e9dc 100644
--- a/indoteknik_custom/models/website_user_cart.py
+++ b/indoteknik_custom/models/website_user_cart.py
@@ -22,10 +22,6 @@ class WebsiteUserCart(models.Model):
record.user_other_carts = others
def get_product(self):
- user_data = {
- 'partner_id': self.user_id.partner_id.id,
- 'user_id': self.user_id.id
- }
product = self.product_id.v2_api_single_response(self.product_id)
product['cart_id'] = self.id
product['quantity'] = self.qty
@@ -33,10 +29,14 @@ class WebsiteUserCart(models.Model):
product['selected'] = self.is_selected
product['program'] = None
product['can_buy'] = True
- product_flashsale = self.product_id._get_active_flash_sale()
- product['has_flashsale'] = True if len(product_flashsale) > 0 else False
+ flashsales = self.product_id._get_active_flash_sale()
+ product['has_flashsale'] = True if len(flashsales) > 0 else False
if self.program_line_id:
- product['program'] = self.program_line_id.res_format_cart(user=user_data, quantity=self.qty)
+ userdata = {
+ 'partner_id': self.user_id.partner_id.id,
+ 'user_id': self.user_id.id
+ }
+ product['program'] = self.program_line_id.format(user=userdata, qty=self.qty)
if product['program']:
if self.qty < product['program']['minimum_purchase_qty'] or self.qty > product['program']['remaining_qty']['transaction']:
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index f2cab699..3ea65498 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -109,6 +109,7 @@
<field name="effective_date" position="after">
<field name="carrier_id"/>
<field name="estimated_arrival_days"/>
+ <field name="picking_iu_id"/>
</field>
<page name="customer_signature" position="after">