1+ from odoo import api , fields , models
2+ from odoo .exceptions import UserError , MissingError
3+ from odoo .tools import _
4+
5+
6+ class SaleOrderLine (models .Model ):
7+ _inherit = 'sale.order.line'
8+
9+ is_deposit_line = fields .Boolean (default = False )
10+
11+ @api .model_create_multi
12+ def create (self , vals_list ):
13+ lines = super ().create (vals_list )
14+ rental_lines = lines .filtered (
15+ lambda l : l .product_id .rent_ok
16+ and l .product_id .requires_deposit
17+ and l .product_id .deposit_amount > 0
18+ )
19+ if not rental_lines :
20+ return lines
21+ company_map = {}
22+ for line in rental_lines :
23+ company = line .company_id
24+ if company not in company_map :
25+ if not company .deposit_product :
26+ raise UserError (_ ("Please set deposit product in settings." ))
27+ company_map [company ] = company .deposit_product
28+ deposit_vals = []
29+ for line in rental_lines :
30+ deposit_product = company_map [line .company_id ]
31+ deposit_vals .append ({
32+ 'order_id' : line .order_id .id ,
33+ 'product_id' : deposit_product .id ,
34+ 'product_uom_qty' : line .product_uom_qty ,
35+ 'price_unit' : line .product_id .deposit_amount ,
36+ 'name' : f"This amount is deposit for { line .product_id .name } product" ,
37+ 'is_deposit_line' : True ,
38+ })
39+ self .create (deposit_vals )
40+ return lines
41+
42+ @api .ondelete (at_uninstall = False )
43+ def _unlink_deposit_fee (self ):
44+ if not self .env .context .get ("bypass_deposit_protection_for_delete" ):
45+ for record in self :
46+ if record .is_deposit_line :
47+ raise UserError (_ ("You can't delete a Deposit Product line directly." ))
48+ rental_lines = self .filtered (
49+ lambda l : l .product_id .rent_ok
50+ and l .product_id .requires_deposit
51+ and l .product_id .deposit_amount > 0
52+ and not l .is_deposit_line
53+ )
54+ if not rental_lines :
55+ return
56+ deposit_lines = self .search ([
57+ ('order_id' , 'in' , rental_lines .mapped ('order_id' ).ids ),
58+ ('is_deposit_line' , '=' , True ),
59+ ])
60+ deposit_map = {}
61+ for line in deposit_lines :
62+ deposit_map [line .name ] = line
63+ for line in rental_lines :
64+ deposit_line = deposit_map .get (
65+ f"This amount is deposit for { line .product_id .name } product"
66+ )
67+ if not deposit_line :
68+ raise MissingError (_ ("Deposit fee is not present." ))
69+ deposit_line .with_context (bypass_deposit_protection_for_delete = True ).unlink ()
70+
71+ def write (self , vals ):
72+ if not self .env .context .get ("bypass_deposit_protection_for_write" ):
73+ for record in self :
74+ if record .is_deposit_line :
75+ raise UserError (_ ("You can't edit Deposit Product line directly." ))
76+ res = super ().write (vals )
77+ if 'product_uom_qty' not in vals :
78+ return res
79+ rental_lines = self .filtered (
80+ lambda l : l .product_id .rent_ok
81+ and l .product_id .requires_deposit
82+ and l .product_id .deposit_amount > 0
83+ )
84+ if not rental_lines :
85+ return res
86+ deposit_lines = self .search ([
87+ ('order_id' , 'in' , rental_lines .mapped ('order_id' ).ids ),
88+ ('is_deposit_line' , '=' , True ),
89+ ])
90+ deposit_map = {}
91+ for line in deposit_lines :
92+ deposit_map [line .name ] = line
93+ for line in rental_lines :
94+ deposit_line = deposit_map .get (
95+ f"This amount is deposit for { line .product_id .name } product"
96+ )
97+ if not deposit_line :
98+ raise MissingError (_ ("Deposit product line not found." ))
99+ deposit_line .with_context (bypass_deposit_protection_for_write = True ).write ({
100+ 'product_uom_qty' : line .product_uom_qty ,
101+ 'price_unit' : line .product_id .deposit_amount ,
102+ })
103+ return res
0 commit comments