from odoo import models, fields from datetime import datetime class PromotionProgramLine(models.Model): _name = 'promotion.program.line' program_id = fields.Many2one('promotion.program', 'Program') name = fields.Char('Name') type = fields.Selection([ ("special_price", "Special Price"), ("bundling", "Bundling"), ("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') package_limit_trx = fields.Integer('Package limit / transaction') product_ids = fields.One2many('promotion.product', 'program_line_id', 'Product') free_product_ids = fields.One2many('promotion.free_product', 'program_line_id', 'Free Product') price = fields.Float('Price') order_promotion_ids = fields.One2many('sale.order.promotion', 'program_line_id', 'Promotions') def get_active_promotions(self, product_id): current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') return self.search([ ('program_id.start_time', '<=', current_time), ('program_id.end_time', '>=', current_time), ('product_ids.product_id', '=', product_id) ]) def _res_limit_qty(self): return { 'all': self.package_limit, 'user': self.package_limit_user, 'transaction': self.package_limit_trx, } def _get_remaining_qty(self, user): remaining_qty = { 'all': self.package_limit, 'user': self.package_limit_user, 'transaction': self.package_limit_trx } for promotion in self.order_promotion_ids: order = promotion.order_id if order.state != 'cancel': remaining_qty['all'] -= promotion.quantity if user and order.partner_id.id == user['partner_id']: remaining_qty['user'] -= promotion.quantity if remaining_qty['all'] < remaining_qty['user']: remaining_qty['user'] = remaining_qty['all'] if remaining_qty['user'] < remaining_qty['transaction']: remaining_qty['transaction'] = remaining_qty['user'] return remaining_qty def _res_type(self): return { 'value': self.type, 'label': dict(self._fields['type'].selection).get(self.type) } def _get_remaining_time(self): calculate_time = self.program_id.end_time - datetime.now() return round(calculate_time.total_seconds()) def formats(self, user): return [x.format(user) for x in self] def format(self, user = None, qty = 1): ir_attachment = self.env['ir.attachment'] limit_qty = self._res_limit_qty() remaining_qty = self._get_remaining_qty(user) percent_remaining = 0 if limit_qty['all'] > 0: percent_remaining = (limit_qty['all'] - remaining_qty['all']) / limit_qty['all'] * 100 products = self.product_ids.formats(purchase_qty=qty) free_products = self.free_product_ids.formats(purchase_qty=qty) merged_products = products + free_products weight = 0 if not any(x['package_weight'] == 0 for x in merged_products): weight = sum(x['package_weight'] for x in merged_products) response = { 'id': self.id, 'name': self.name, 'image': ir_attachment.api_image(self._name, 'image', self.id), 'remaining_time': self._get_remaining_time(), 'type': self._res_type(), 'limit_qty': limit_qty, 'remaining_qty': remaining_qty, 'used_percentage': percent_remaining, 'price': { 'price': self.price, 'price_discount': self.price, 'discount_percentage': 0 }, 'products': products, 'free_products': free_products, 'weight': weight } return response