|
| 1 | +from datetime import datetime |
| 2 | + |
| 3 | +from dateutil.relativedelta import relativedelta |
| 4 | +from odoo import api, fields, models |
| 5 | +from odoo.exceptions import UserError |
| 6 | + |
| 7 | + |
| 8 | +class EstateProperty(models.Model): |
| 9 | + _inherit = 'estate.property' |
| 10 | + |
| 11 | + auction_state = fields.Selection( |
| 12 | + [('01_template', 'Template'), ('02_auction', 'Auction'), ('03_sold', 'Sold')], |
| 13 | + string='Auction State', |
| 14 | + copy=False, |
| 15 | + default='01_template', |
| 16 | + required=True, |
| 17 | + readonly=True, |
| 18 | + ) |
| 19 | + sale_mode = fields.Selection( |
| 20 | + [('auction', 'Auction'), ('regular', 'Regular')], |
| 21 | + string='Sale Mode', |
| 22 | + default='regular', |
| 23 | + required=True, |
| 24 | + ) |
| 25 | + auction_end_time = fields.Datetime( |
| 26 | + string='End Time', default=(relativedelta(days=7) + datetime.today()) |
| 27 | + ) |
| 28 | + highest_bidder_id = fields.Many2one( |
| 29 | + 'res.partner', |
| 30 | + string='Highest Bidder', |
| 31 | + compute='_compute_highest_bid', |
| 32 | + store=True, |
| 33 | + default=False, |
| 34 | + ) |
| 35 | + highest_offer = fields.Float( |
| 36 | + 'Highest Offer', compute='_compute_highest_bid', store=True, default=0 |
| 37 | + ) |
| 38 | + |
| 39 | + @api.depends('offer_ids') |
| 40 | + def _compute_highest_bid(self): |
| 41 | + for record in self: |
| 42 | + if record.sale_mode != 'auction': |
| 43 | + continue |
| 44 | + if not record.offer_ids: |
| 45 | + record.highest_bidder_id = False |
| 46 | + record.highest_offer = 0.0 |
| 47 | + continue |
| 48 | + max_offer = max(record.offer_ids, key=lambda x: x.price, default=None) |
| 49 | + if max_offer is not None: |
| 50 | + record.highest_bidder_id = max_offer.partner_id.id |
| 51 | + record.highest_offer = max_offer.price |
| 52 | + |
| 53 | + def action_start_estate_auction(self): |
| 54 | + if not self.auction_end_time: |
| 55 | + raise UserError("You can't start the auction without defining end time.") |
| 56 | + |
| 57 | + if self.auction_end_time <= datetime.now(): |
| 58 | + raise UserError('Auction end time must be in the future.') |
| 59 | + |
| 60 | + self.auction_state = '02_auction' |
| 61 | + |
| 62 | + def automate_auction_sales(self): |
| 63 | + properties = self.search([ |
| 64 | + ('state', 'in', ('new', 'offer_received')), |
| 65 | + ('sale_mode', '=', 'auction'), |
| 66 | + ('auction_state', '=', '02_auction'), |
| 67 | + ]) |
| 68 | + |
| 69 | + for estate in properties: |
| 70 | + if not estate.auction_end_time or datetime.now() <= estate.auction_end_time: |
| 71 | + continue |
| 72 | + |
| 73 | + best_offer = self.env['estate.property.offer'].search( |
| 74 | + [('property_id', '=', estate.id)], |
| 75 | + order='price desc, create_date asc', |
| 76 | + limit=1, |
| 77 | + ) |
| 78 | + if best_offer: |
| 79 | + best_offer.action_accept() |
| 80 | + estate.auction_state = '03_sold' |
| 81 | + estate.action_sold() |
| 82 | + else: |
| 83 | + estate.auction_state = '03_sold' |
| 84 | + estate.state = 'cancelled' |
0 commit comments