from odoo import fields, models 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") qty = fields.Float(string='Quantity', digits='Product Unit of Measure') is_selected = fields.Boolean(string='Selected?', digits='Is selected to process checkout') source = fields.Selection([ ('add_to_cart', 'Add To Cart'), ('buy', 'Buy') ], 'Source', default='add_to_cart') user_other_carts = fields.One2many('website.user.cart', 'id', 'Other Products', compute='_compute_user_other_carts') def _compute_user_other_carts(self): for record in self: others = self.search([('user_id', '=', record.user_id.id)]) record.user_other_carts = others def get_product(self): res = { 'cart_id': self.id, 'quantity': self.qty, 'selected': self.is_selected, 'can_buy': True } if self.product_id: res['cart_type'] = 'product' product = self.product_id.v2_api_single_response(self.product_id) res.update(product) flashsales = self.product_id._get_active_flash_sale() res['has_flashsale'] = True if len(flashsales) > 0 else False elif self.program_line_id: res['cart_type'] = 'promotion' userdata = { 'partner_id': self.user_id.partner_id.id, 'user_id': self.user_id.id } program = self.program_line_id.format(user=userdata, qty=self.qty) res.update(program) if program['remaining_qty']['transaction'] < self.qty: res['can_buy'] = False res['subtotal'] = self.qty * res['price']['price_discount'] return res def get_products(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) if source == 'buy': source = ['buy'] else: source = ['add_to_cart', 'buy'] parameters = [ ('user_id', '=', user_id), ('source', 'in', source) ] if selected: parameters.append(('is_selected', '=', True)) carts = self.search(parameters) products = carts.get_products() return products 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 = 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: order_line = [] for product in products: if product['cart_type'] == 'promotion': continue order_line.append({ 'product_id': self.env['product.product'].browse(product['id']), 'price': product['price']['price'], 'discount': product['price']['discount_percentage'], 'qty': product['quantity'], 'subtotal': product['subtotal'] }) voucher_info = voucher.apply(order_line) discount_voucher = voucher_info['discount']['all'] subtotal -= discount_voucher tax = round(subtotal * 0.11) grand_total = subtotal + tax total_weight = sum(x['weight'] * x['quantity'] for x in products) total_weight = round(total_weight, 2) result = { 'total_purchase': total_purchase, 'total_discount': total_discount, 'discount_voucher': discount_voucher, 'subtotal': subtotal, 'tax': tax, 'grand_total': round(grand_total), 'total_weight': { '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), 'products': products } return result def action_mail_reminder_to_checkout(self, id): template = self.env.ref('indoteknik_custom.mail_template_user_cart_reminder_to_checkout') template.send_mail(int(id), force_send=True) def format_currency(self, number): number = int(number) return "{:,}".format(number).replace(',', '.')