diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-09-18 16:20:15 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-09-18 16:20:15 +0700 |
| commit | adbc9b985f1c5fb2b2f41f79c686b3a573003e62 (patch) | |
| tree | 27ca97d7c6540ccaf3556efadb9c8b439ac2f2fb | |
| parent | 0ace4356bdbe27c3acd75c33d5259ef950eecb24 (diff) | |
Update promotion program feature
| -rw-r--r-- | indoteknik_api/controllers/api_v1/sale_order.py | 39 | ||||
| -rw-r--r-- | indoteknik_custom/models/promotion_program_line.py | 53 | ||||
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 54 | ||||
| -rw-r--r-- | indoteknik_custom/models/website_user_cart.py | 14 | ||||
| -rwxr-xr-x | indoteknik_custom/views/sale_order.xml | 1 |
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"> |
