From 0c47847a430d10c04272ed378e6f52f0cdbc8d63 Mon Sep 17 00:00:00 2001 From: dhruvikalariyaa Date: Fri, 5 Jun 2026 14:12:29 +0530 Subject: [PATCH 1/7] [ADD] estate: initialize estate tutorial module create the directory structure and main manifest file for the estate real estate business module. This module will serve as the base for developing the property advertisement and offer management application. --- estate/__init__.py | 0 estate/__manifest__.py | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 estate/__init__.py create mode 100644 estate/__manifest__.py diff --git a/estate/__init__.py b/estate/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/estate/__manifest__.py b/estate/__manifest__.py new file mode 100644 index 00000000000..8bc552b75df --- /dev/null +++ b/estate/__manifest__.py @@ -0,0 +1,6 @@ +{ + "name": "Real Estate", + "depends": ["base"], + "application" : True, + +} \ No newline at end of file From 77a62827b1febd2651e647ac9fe05f1f5922e30d Mon Sep 17 00:00:00 2001 From: dhruvikalariyaa Date: Mon, 8 Jun 2026 12:50:52 +0530 Subject: [PATCH 2/7] [ADD] estate: introduce the estate.property model Create the foundation of the 'estate' module (Real Estate application). Define the core model 'estate.property' to represent properties in the system. This model includes fields to track basic property information such as: - Name - Description - Postcode - Date of availability - Expected price - Selling price - Bedrooms, living area, facades, garage, and garden details --- estate/__init__.py | 1 + estate/__manifest__.py | 5 ++--- estate/models/__init__.py | 1 + estate/models/estate_property.py | 23 +++++++++++++++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 estate/models/__init__.py create mode 100644 estate/models/estate_property.py diff --git a/estate/__init__.py b/estate/__init__.py index e69de29bb2d..0650744f6bc 100644 --- a/estate/__init__.py +++ b/estate/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/estate/__manifest__.py b/estate/__manifest__.py index 8bc552b75df..d36fb1c0983 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -1,6 +1,5 @@ { "name": "Real Estate", "depends": ["base"], - "application" : True, - -} \ No newline at end of file + "application": True, +} diff --git a/estate/models/__init__.py b/estate/models/__init__.py new file mode 100644 index 00000000000..5e1963c9d2f --- /dev/null +++ b/estate/models/__init__.py @@ -0,0 +1 @@ +from . import estate_property diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py new file mode 100644 index 00000000000..f4cdc524147 --- /dev/null +++ b/estate/models/estate_property.py @@ -0,0 +1,23 @@ +from odoo import fields, models + + +class EstateProperty(models.Model): + _name = "estate.property" + _description = "Real Estate Property" + + name = fields.Char(string="Title", required=True) + description = fields.Text(string="Description") + postcode = fields.Char(string="Postcode") + date_availability = fields.Date(string="Available From") + expected_price = fields.Float(string="Expected Price", required=True) + selling_price = fields.Float(string="Selling Price") + bedrooms = fields.Integer(string="Bedrooms") + living_area = fields.Integer(string="Living Area (sqm)") + facades = fields.Integer(string="Facades") + garage = fields.Boolean(string="Garage") + garden = fields.Boolean(string="Garden") + garden_area = fields.Integer(string="Garden Area (sqm)") + garden_orientation = fields.Selection( + [("north", "North"), ("south", "South"), ("east", "East"), ("west", "West")], + string="Garden Orientation", + ) From 7a047798d40719fb3f5aeba68d471a6f9debcd3d Mon Sep 17 00:00:00 2001 From: dhruvikalariyaa Date: Tue, 9 Jun 2026 16:10:05 +0530 Subject: [PATCH 3/7] [ADD] estate: add access rights for estate.property model - Create `ir.model.access.csv` to define access control rules. - Grant full CRUD (read, write, create, delete) permissions to the base user group (`base.group_user`). - Register the security CSV file inside the manifest `__manifest__.py`. --- estate/__manifest__.py | 6 ++++++ estate/security/ir.model.access.csv | 2 ++ 2 files changed, 8 insertions(+) create mode 100644 estate/security/ir.model.access.csv diff --git a/estate/__manifest__.py b/estate/__manifest__.py index d36fb1c0983..04c285bde27 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -1,5 +1,11 @@ { "name": "Real Estate", "depends": ["base"], + "data" : [ + 'security/ir.model.access.csv', + ], "application": True, + "author" : "dhruvi kalariya", + "license" : "LGPL-3", + "installable" : True, } diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv new file mode 100644 index 00000000000..73a8b2a8ba7 --- /dev/null +++ b/estate/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink +access_estate_property,estate_property_access,model_estate_property,base.group_user,1,1,1,1 From 700fea3161fffe0df49c2f9f626036543ac30fee Mon Sep 17 00:00:00 2001 From: dhruvikalariyaa Date: Thu, 11 Jun 2026 18:28:43 +0530 Subject: [PATCH 4/7] [ADD] estate: ui views, menus, actions and field attributes - Add window action for estate.property model - Add 3-level menu hierarchy (Root, Advertisements) with web_icon - Set selling_price as read-only and non-copyable - Set default values for bedrooms (2) and date_availability (3 months from today) - Add active and state reserved fields with default values --- estate/__manifest__.py | 12 ++++++---- estate/models/estate_property.py | 29 +++++++++++++++++++---- estate/static/description/icon.png | Bin 0 -> 8240 bytes estate/views/estate_menus.xml | 31 +++++++++++++++++++++++++ estate/views/estate_property_views.xml | 9 +++++++ 5 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 estate/static/description/icon.png create mode 100644 estate/views/estate_menus.xml create mode 100644 estate/views/estate_property_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index 04c285bde27..15f8e200187 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -1,11 +1,13 @@ { "name": "Real Estate", "depends": ["base"], - "data" : [ - 'security/ir.model.access.csv', + "data": [ + "security/ir.model.access.csv", + "views/estate_property_views.xml", + "views/estate_menus.xml", ], "application": True, - "author" : "dhruvi kalariya", - "license" : "LGPL-3", - "installable" : True, + "author": "dhruvi kalariya", + "license": "LGPL-3", + "installable": True, } diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index f4cdc524147..ebafa73e5fa 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,17 +1,24 @@ from odoo import fields, models +from dateutil.relativedelta import relativedelta class EstateProperty(models.Model): _name = "estate.property" _description = "Real Estate Property" - name = fields.Char(string="Title", required=True) + name = fields.Char(string="Title", required=True, default="Unknown") description = fields.Text(string="Description") postcode = fields.Char(string="Postcode") - date_availability = fields.Date(string="Available From") - expected_price = fields.Float(string="Expected Price", required=True) - selling_price = fields.Float(string="Selling Price") - bedrooms = fields.Integer(string="Bedrooms") + date_availability = fields.Date( + string="Available From", + copy=False, + default=lambda self: fields.Date.context_today(self) + relativedelta(months=3), + ) + expected_price = fields.Float( + string="Expected Price", required=True, digits=(16, 4) + ) + selling_price = fields.Float(string="Selling Price", readonly=True, copy=False) + bedrooms = fields.Integer(string="Bedrooms", default=2) living_area = fields.Integer(string="Living Area (sqm)") facades = fields.Integer(string="Facades") garage = fields.Boolean(string="Garage") @@ -21,3 +28,15 @@ class EstateProperty(models.Model): [("north", "North"), ("south", "South"), ("east", "East"), ("west", "West")], string="Garden Orientation", ) + active = fields.Boolean(string="Active", default=True) + state = fields.Selection( + [ + ("new", "New"), + ("offer_received", "Offer Received"), + ("offer_accepted", "Offer Accepted"), + ("sold", "Sold"), + ("cancelled", "Cancelled"), + ], + copy=False, + default="new", + ) diff --git a/estate/static/description/icon.png b/estate/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..49aa15839db6d2e844b885766df54b9ee128e1f3 GIT binary patch literal 8240 zcmeHMX*|?x-@nF$>R`@&TC5rOiFA%a5s5Kc4u)(oDOp3>EXg{|;wYU{qA0Rtlx!oE zMAn&dYMNxt*d~oFG`7N!VP>9dob$YVUOca!`^Dq)@%hhO^SiF!_Wf)~JQdcQy5_YEP|Coe<#9?3uA(9WzV zxTqZV+lese;4@*7KB4{~GBQ&4T+oHfzCI!Ty1}6VSu2J z$oE^)od0x#$>_$R<0-fFT@IdIXU4o-DZTFKx*8VxF2dMUIFin~xFaTdY#GxwI~VI! zPB%;+nEm#`fVxU*tEW5b=;$E8yNcpzBmgZ20OVRgO*g*l=5mMH z$wqzIR($G_!`R&o&#VY};gSTg! zhdu|7@m0X0=w0j~{)ExI|5lQQ+S0@gR-7CE4YM%YdWTUtcxW zTz;m>HJI~S`Tpl_laPtDk6~Y|tV9=(rC*i7L>-&vHJ7IaAl|H3;r%vV=caYNkguN#42>?oe@BR9X%8^gDl&~gB| z4o1fy&4WCL<_CFPN7NP49+0b-P%PNzzua37&%NOa+Qaee+40oXl|({i^6(Z0p>Etf z<4dWY3+hVH{5nv3@zT(qVj9WzOEa}6-YSRM)XaT5SziBQIu8VNC+qEWe0a%4m>J3y zj*sUwMbcysMJj{#-!9E4CTYQym2+PA`OxDm;=(!aNj^oym|dx(tvP`8-9V$5P2l5!*~Nm(OpOW1sgnS^$I~FF~=3?{~G8jOz8N$CdMmk z2%S8~P5|4nd=Rs4 zljemjl6}RH1N&9+bdeM4N?epQDEz>rarJjhLnp%kN{0bdBKs;2$~IXnuuD2@MJ-cb zUl;%w#ak5{u{2UDG?#s|4zS*l$1_gEk=Nuhdz`Ho7P5mz`V8T8En3Q=k4ED%kDc!= ztkec2RY4}V2cDHT*U`T>RwY;X7<)=*`F- zecg*rXL})t6F$!6yH*mj~dTt|y<%$=QeqlLO5jP*08f6v7j<-8}W;=*H z`4%>V8$fDcDQ`Rr8}EdA^rH+&wPh#!6w4k1<=~!K{&AsF=_XXrySNx`nyOy3Q$cm3 zHRcv>rHT}`uE#a$x?ZP24EqJhPEU4VZQeD)rl=QR=@i|`;m(U9ceW6@8Nt4 z!F!NPbrGKBNP@cGe4|{G4iG@by2ZS>;P)leRU$8L;ifiNxJE;J;V(%cz6J8Yv_~Ho0EIstb88N$;;j z?(i$@bs9RGRWpsr6whz#C__a8#6l*5@dnx!r5SyRV}f&Y&H?N<#$zde`ht)M2#!d2s=iab)Zlv;A=r_o4a_oWXvSX#AnFmc9|u=OWkw1@q^wUG&Bep+`xF` z#7BAq_@m@$A;Wm&2%ku^pL5pHNZ{fvZ9pvG$ue%qQ5ui&^O9PeS+Ae53gTIc5n3qw z=ft0LePk@q&=gCW8Nn+%7uw&Cjdm{kF~|I(P5PqEmTzEK|MF7E)fD};^d}7+e!qHm zO;i~{>dAT0k-3jZb}EH_|J>|Fi#&Kd#6?oEref=kWG+cSr~7L~kG=G3`!Ue6Y>i1jRoDtT%f@bxseIo|b_zY3H7u4FYlWTSF;dFcVe5BV+`-So`ERT6s z`nY9`Ztf;IiY^UW);83qS^Gh9)lseV_pV~T7tU4*wGb2rdPUHC#? z&mHH>GU?Dqhk1ZQPXEZEuH_W@lGcvjmy;9>sH z)uT8$ekUtOV?GHSuq~P&-)$fwGru^w^eabbJ^QPsB|1nTRX5@38+d= zAeOB0a~pE#&)uphik6U2|K@2KEft~*BgHtSzIHmV-8mH&Zm5ajn@yBwFto_(+*Rc_ zW5uH>HKVx3<>0r_lFG8FE#{jUw`O7nO=^~}tM;2)rYnPhhmcXK``YesHPgo3vI@kX z%WI}wIp#L5cBPL`^d?Iz1N#nP3pr?I-FU=l8_X?2L@UYMfK%4|Nx1Z!ct`i!x37Ix9rqeHEgxjp(MZO=ua^INS$Y7F#(A9@1A?3-%^{ zv12($+)Z5wY`SWdI;r4--hAbzo4FA+MuB{wykRv!B1n|1y9>C_`#ybE|5e zB1=#5=hsjOyU(N#u$?|mvl8i@ljMQ4VxB7fQLri8;L3HDm+CEAnZaV0)EW)S>sH@D zCTV+REnu8-C3uJ3(*t$uZA^!YthmF~qp;|7E;{u)b_W26(+iz65^+_I@g+O^80t|@ zO-A{dh?RY?UY>${fB9^NfIv{d(}SE*kIJ?;D~=7`F2C!7+T{yiz+Izxk&9%HF_Fwd zG)-1y!?8N|%8xDu+rMDjIVi;;hx^9&-OWsEe5knSwQeSSI$P*|rpg1$;xkx8sVB$z z^DWeyF)w&MsgLxMAE{e=TuU-1c235nnn;8@%nlB9k20+B#N7I~T@)sy!V>}6xf|x)tq?VM0P1aWsKbI*mIDRVj;cbJhHt?; zQ0s=OKm9W)yIzd6fRQqW7hcc%Z|lTxsad+h5RO%G37sm@ybM7^+2r+t3Ky+n;ZQetp}s;)a^y0=P9PqlJZsUDEKM&1@Y6 z-y)%7gy2o~MC{VNh?`qnzoP#bR}Rk}{YQ<~K90e&=^A3O?Bd8j$L{$9W`!)m9NIDr zjuUM~yf|0$lIc9Thbu_$OGC@Wq`zhb(8#D_!BZzib-S_^C}Y#fH9Qh`NbuNi{;no$ zX$!-RJ-ZucR2{1#D5``FX}#2b1850e6y`}5GM6SGYP>R+oBUnbhk8&61XQPtmMxE# z)$qs(H!}xB)9+i%v}2aI1B*`Glb>_|Og4^u-#cB%;*uslBS`+A1$VfRmj@T>r6gu! z20Q3(UhLB^2S#I~E}_iWId)%_!y&KmBK2O;Cdr-?rGmRT3;D`f$7$$Iv2R}Tm@+={mG{ab4`wm?wP*7>?U$q_De?qS6I*acm2Wi~i36unZO2Ne^8sP? zQcAm_P5LoQSc3*W)zAs0CYE?n7f=7T2Ut2_Zq-8JBymyxW|@KlcUVC_cs7!5 zHbWTvF7wY~BwT#zhFbk*i``$wJ-tva!Llv8+{6=+NR{BIZPh>GBK=GkpV48CfZ;+- z3Kq#7W+&q+-B7Uw1dYQ7>Q^6K>Oxu>gRP3B{V@L&Z(rH>3v5GEXEwmY^%Dr*LRX1_ z@_9Y# zB&tmQz75}(9Hb9weYEfMUGR8$w2?&#Udzi7^(cX+9z|T7p_BP~r5H(+!^X(r7(f1LZ#~Qn5Nbm%d`9rt zm=5)+Af2`bAlNc6iv=%Fctk<}HI?wvK^K)NB^YGbRK&~_&X)+FWpupXWXpZn zaSj-7;aju@^?XE+V!UF_a_pm?6o<^HScKDy;x(@GS_(4SME$v1w70KE^8n_(XRyXr~^6DDuG~#yWG&;XIM>K)n}TSTh>n*d!0qWx~0zEB_Fo zefd!jkkpMn?S<+sxp^CJ$Q3={EfScp$e3S zS|pp)dJ9_m{73Bmna*4vI7|}r)lYccl$`fTa^BGUU|dg=;%*;#!cmyaP9n9U7~G#s~sD4&xIEkuPRwnY4Nv+4?WlZWx6-p z{ea%o;dytNBOj73;zXw%LVF$dVcz{AG5d$M4DPMbALPY3128J@9Kn2DD5(B~r9oNP zQ=kZXWax#VH5;`voiMl^pT1fj<^n~hEjwh^NR~C6Q11JNCB&^(Ew+u4C2zYge8wJk z2oNK3_v3n7IDr85Kn`m(Q))8K7Xr|6TAq@kD}RiS++Ur-i}S6QEOno;d0}{#WXpf+ z#YPQ&Y$a<%f4b6xWX3}9^|!U)(`AIQ9H!C@HjP`gC~lK$SLMKt&(rV$pW$(tY}hIh z;qL5F*!HaiqEGulp1cg3(9i3-kpb0YgAb>?J}&M_DU+k{I&;y@n(iuC}KDen-|7f_J<`Z&Rekm)ZP-aC9DF zFa5LD*G!RN7uv=b7~>U}*RQl&=^`H{D+HD5Zg!htedtcmgJ!PI0gt~h^ABbfnCJ6k z+n>N@|Kma=$NZhi^AM(QS&{G-j(;)-)#x_LSGAGldsVNp^6M zxpM_!Bb~WkwsZBnrdJ3YS%mlf$bm~2B3eYksch&EtLTXo>eZ^`OS%JSFzuxhrpaoq zsGQY)RvG;JNEg6VM~aEd3=fAk-^fOTEH}Z)mkJVG%%CWbT5RKItmmfSxzh<`FOb0h zWXioaAJJ&|;S~Dp!qW6xi3ga#y8ngYL=wX@Mwbrpk9x*9p~?a!&4m7Mo2vCp4! zpKX_j8jNL#sx*7FmS64>sWVgR_rTILqC`f4H-WPvm^5}8dk8wbximNw{*KG9C4N- zx#cuFBdVC{6;0n3)oznOSEveDMSAiFGW_b!J8>T8yzB~ zV=eGb7#zhs8If!eBQ=y4I&+2a8fY*~rc`!u5b9|61{7sacjltBY9x0}1_xX*PqZQR z`A`|g7pPO(s63RI2AhF?cq=<`vtfmP7d1e1T6|A7bauW#Zm{~B*rGzznM=2a^Bz9} zC2cV)x!N^zM@{uXFJ?YQ+v(Y|UsW;Xy3V*h{eZtSe&rdsO0^_(~7nsv(2z|5eP^#RW-QvC9#of${= zg4}5AZB^2&aliQyz1WH0xh+I5@q?;lMCx0e|KvAz|A}uA|6iv6<;&f(=l%WjrwtZ3 zXi@uORkFpbTAMt52?BNEsyM8#O4GF8TxJ`;!W30Sykfrga@iB{pZ+TOe*nRP7%_AE X;A!7?anA7VKEVBEf28b?_wWA&&u8eI literal 0 HcmV?d00001 diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml new file mode 100644 index 00000000000..ef769c396f2 --- /dev/null +++ b/estate/views/estate_menus.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml new file mode 100644 index 00000000000..b8fd94b7a7b --- /dev/null +++ b/estate/views/estate_property_views.xml @@ -0,0 +1,9 @@ + + + + Properties + estate.property + list,form,kanban + + + From 35680e7b72dfaaad44f5688ab7e4eaf54d4bc7aa Mon Sep 17 00:00:00 2001 From: dhruvikalariyaa Date: Tue, 16 Jun 2026 10:13:43 +0530 Subject: [PATCH 5/7] [ADD] estate: add views and security groups - Create security/security_groups.xml to define the Real Estate category, Access privilege, and user groups (Agent, Buyer, Owner) - Add list, form, and search views for the estate.property model in views/estate_property_views.xml --- estate/security/security_groups.xml | 30 +++++++++++ estate/views/estate_property_views.xml | 75 ++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 estate/security/security_groups.xml diff --git a/estate/security/security_groups.xml b/estate/security/security_groups.xml new file mode 100644 index 00000000000..5cd2216d79a --- /dev/null +++ b/estate/security/security_groups.xml @@ -0,0 +1,30 @@ + + + + Real Estate + + + + Access + + + + + Agent + + + + + + Buyer + + + + + + Owner + + + + diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index b8fd94b7a7b..f69ecea57bf 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -6,4 +6,79 @@ list,form,kanban + + estate.property.list + estate.property + + + + + + + + + + + + + + + + estate.property.form + estate.property + +
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + estate.property.search + estate.property + + + + + + + + + + + + + + + From 0f0ba95fad12a9e68fd493ec357c0d0cc08b1c4d Mon Sep 17 00:00:00 2001 From: dhruvikalariyaa Date: Fri, 19 Jun 2026 11:13:25 +0530 Subject: [PATCH 6/7] [IMP] estate: add new features and refactor code to match guidelines Introduce property types, tags, and offers to expand module capabilities, while refactoring existing code to comply with Odoo standards. - Add new models and views for property types, tags, and offers. - Rename Many2one fields 'buyer' and 'salesperson' to 'buyer_id' and 'salesperson_id' in 'estate.property'. - Rename XML view and action record IDs to use '[model_name]_view_[type]' and '[model_name]_action' naming patterns. - Move security configurations to 'security/estate_security.xml'. - Align Python imports and XML files formatting. --- estate/__manifest__.py | 4 ++ estate/models/__init__.py | 3 + estate/models/estate_property.py | 20 ++++++- estate/models/estate_property_offer.py | 18 ++++++ estate/models/estate_property_tag.py | 8 +++ estate/models/estate_property_type.py | 8 +++ ...ecurity_groups.xml => estate_security.xml} | 10 ++-- estate/security/ir.model.access.csv | 18 ++++++ estate/views/estate_menus.xml | 55 ++++++++++--------- estate/views/estate_property_offer_views.xml | 30 ++++++++++ estate/views/estate_property_tag_views.xml | 8 +++ estate/views/estate_property_type_views.xml | 8 +++ estate/views/estate_property_views.xml | 26 ++++++--- 13 files changed, 176 insertions(+), 40 deletions(-) create mode 100644 estate/models/estate_property_offer.py create mode 100644 estate/models/estate_property_tag.py create mode 100644 estate/models/estate_property_type.py rename estate/security/{security_groups.xml => estate_security.xml} (73%) create mode 100644 estate/views/estate_property_offer_views.xml create mode 100644 estate/views/estate_property_tag_views.xml create mode 100644 estate/views/estate_property_type_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index 15f8e200187..bfe686cc3f9 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -2,8 +2,12 @@ "name": "Real Estate", "depends": ["base"], "data": [ + "security/estate_security.xml", "security/ir.model.access.csv", "views/estate_property_views.xml", + "views/estate_property_type_views.xml", + "views/estate_property_tag_views.xml", + "views/estate_property_offer_views.xml", "views/estate_menus.xml", ], "application": True, diff --git a/estate/models/__init__.py b/estate/models/__init__.py index 5e1963c9d2f..2f1821a39c1 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1 +1,4 @@ from . import estate_property +from . import estate_property_type +from . import estate_property_tag +from . import estate_property_offer diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index ebafa73e5fa..42db6d6fc84 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,12 +1,15 @@ -from odoo import fields, models from dateutil.relativedelta import relativedelta +from odoo import fields, models + class EstateProperty(models.Model): _name = "estate.property" _description = "Real Estate Property" name = fields.Char(string="Title", required=True, default="Unknown") + property_type_id = fields.Many2one("estate.property.type", string="Property Type") + tag_ids = fields.Many2many("estate.property.tag", string="Tags") description = fields.Text(string="Description") postcode = fields.Char(string="Postcode") date_availability = fields.Date( @@ -25,7 +28,12 @@ class EstateProperty(models.Model): garden = fields.Boolean(string="Garden") garden_area = fields.Integer(string="Garden Area (sqm)") garden_orientation = fields.Selection( - [("north", "North"), ("south", "South"), ("east", "East"), ("west", "West")], + [ + ("north", "North"), + ("south", "South"), + ("east", "East"), + ("west", "West"), + ], string="Garden Orientation", ) active = fields.Boolean(string="Active", default=True) @@ -37,6 +45,14 @@ class EstateProperty(models.Model): ("sold", "Sold"), ("cancelled", "Cancelled"), ], + string="Status", copy=False, default="new", ) + buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False) + salesperson_id = fields.Many2one( + "res.users", + string="Salesperson", + default=lambda self: self.env.user, + ) + offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers") diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py new file mode 100644 index 00000000000..e238ea5e280 --- /dev/null +++ b/estate/models/estate_property_offer.py @@ -0,0 +1,18 @@ +from odoo import fields, models + + +class EstatePropertyOffer(models.Model): + _name = "estate.property.offer" + _description = "Real Estate Property Offer" + + price = fields.Float(string="Price") + status = fields.Selection( + [ + ("accepted", "Accepted"), + ("rejected", "Rejected"), + ], + string="Status", + copy=False, + ) + partner_id = fields.Many2one("res.partner", string="Partner", required=True) + property_id = fields.Many2one("estate.property", string="Property", required=True) diff --git a/estate/models/estate_property_tag.py b/estate/models/estate_property_tag.py new file mode 100644 index 00000000000..2c62c64ee93 --- /dev/null +++ b/estate/models/estate_property_tag.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class EstatePropertyTag(models.Model): + _name = "estate.property.tag" + _description = "Real Estate Property Tag" + + name = fields.Char(string="Name", required=True) diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py new file mode 100644 index 00000000000..643c791ed2e --- /dev/null +++ b/estate/models/estate_property_type.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class EstatePropertyType(models.Model): + _name = "estate.property.type" + _description = "Real Estate Property Type" + + name = fields.Char(string="Type", required=True) \ No newline at end of file diff --git a/estate/security/security_groups.xml b/estate/security/estate_security.xml similarity index 73% rename from estate/security/security_groups.xml rename to estate/security/estate_security.xml index 5cd2216d79a..bcfbd7bb73b 100644 --- a/estate/security/security_groups.xml +++ b/estate/security/estate_security.xml @@ -4,25 +4,23 @@ Real Estate - + Access - - + Agent - + Buyer - + Owner diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv index 73a8b2a8ba7..5800cb94f40 100644 --- a/estate/security/ir.model.access.csv +++ b/estate/security/ir.model.access.csv @@ -1,2 +1,20 @@ id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink access_estate_property,estate_property_access,model_estate_property,base.group_user,1,1,1,1 +access_estate_property_agent,estate_property_agent,model_estate_property,estate.res_groups_agent,1,1,1,1 +access_estate_property_buyer,estate_property_buyer,model_estate_property,estate.res_groups_buyer,1,0,0,0 +access_estate_property_owner,estate_property_owner,model_estate_property,estate.res_groups_owner,1,1,1,1 + +access_estate_property_type,estate_property_type_access,model_estate_property_type,base.group_user,1,1,1,1 +access_estate_property_type_agent,estate_property_type_agent,model_estate_property_type,estate.res_groups_agent,1,1,1,1 +access_estate_property_type_buyer,estate_property_type_buyer,model_estate_property_type,estate.res_groups_buyer,1,0,0,0 +access_estate_property_type_owner,estate_property_type_owner,model_estate_property_type,estate.res_groups_owner,1,1,1,1 + +access_estate_property_tag,estate_property_tag_access,model_estate_property_tag,base.group_user,1,1,1,1 +access_estate_property_tag_agent,estate_property_tag_agent,model_estate_property_tag,estate.res_groups_agent,1,1,1,1 +access_estate_property_tag_buyer,estate_property_tag_buyer,model_estate_property_tag,estate.res_groups_buyer,1,0,0,0 +access_estate_property_tag_owner,estate_property_tag_owner,model_estate_property_tag,estate.res_groups_owner,1,1,1,1 + +access_estate_property_offer,estate_property_offer_access,model_estate_property_offer,base.group_user,1,1,1,1 +access_estate_property_offer_agent,estate_property_offer_agent,model_estate_property_offer,estate.res_groups_agent,1,1,1,1 +access_estate_property_offer_buyer,estate_property_offer_buyer,model_estate_property_offer,estate.res_groups_buyer,1,0,0,0 +access_estate_property_offer_owner,estate_property_offer_owner,model_estate_property_offer,estate.res_groups_owner,1,1,1,1 diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml index ef769c396f2..6929b0344ec 100644 --- a/estate/views/estate_menus.xml +++ b/estate/views/estate_menus.xml @@ -1,31 +1,36 @@ - + - - - - - - - - + + + + diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml new file mode 100644 index 00000000000..8b2af3d04eb --- /dev/null +++ b/estate/views/estate_property_offer_views.xml @@ -0,0 +1,30 @@ + + + + estate.property.offer.list + estate.property.offer + + + + + + + + + + + estate.property.offer.form + estate.property.offer + +
+ + + + + + + +
+
+
+
diff --git a/estate/views/estate_property_tag_views.xml b/estate/views/estate_property_tag_views.xml new file mode 100644 index 00000000000..0ec3dc550e0 --- /dev/null +++ b/estate/views/estate_property_tag_views.xml @@ -0,0 +1,8 @@ + + + + Property Tags + estate.property.tag + list,form + + diff --git a/estate/views/estate_property_type_views.xml b/estate/views/estate_property_type_views.xml new file mode 100644 index 00000000000..6384061b8ee --- /dev/null +++ b/estate/views/estate_property_type_views.xml @@ -0,0 +1,8 @@ + + + + Property Types + estate.property.type + list,form + + diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index f69ecea57bf..6b9ab3631fc 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -1,4 +1,4 @@ - + Properties @@ -6,12 +6,13 @@ list,form,kanban - + estate.property.list estate.property + @@ -22,8 +23,7 @@ - - + estate.property.form estate.property @@ -34,6 +34,8 @@ + + @@ -57,13 +59,22 @@ + + + + + + + + + - - - + + + estate.property.search estate.property @@ -77,6 +88,7 @@ + From bc5555ef2677438755828be161920ceda45340c6 Mon Sep 17 00:00:00 2001 From: dhruvikalariyaa Date: Mon, 22 Jun 2026 17:37:36 +0530 Subject: [PATCH 7/7] [IMP] estate: add demo data and improve property views - Add demo data files for property types (demo_types.xml), property tags (demo_tags.xml), and properties (demo_property.xml). - Add tag_ids field with widget 'many2many_tags' to property list view. - Add 'Has garden' and 'Has garage' filters to the property search view. --- estate/__manifest__.py | 3 ++ estate/data/demo_property.xml | 38 ++++++++++++++++++++++++++ estate/data/demo_tags.xml | 14 ++++++++++ estate/data/demo_types.xml | 14 ++++++++++ estate/models/estate_property_offer.py | 2 +- estate/models/estate_property_type.py | 3 +- estate/views/estate_property_views.xml | 4 +++ 7 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 estate/data/demo_property.xml create mode 100644 estate/data/demo_tags.xml create mode 100644 estate/data/demo_types.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index bfe686cc3f9..81784e94540 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -9,6 +9,9 @@ "views/estate_property_tag_views.xml", "views/estate_property_offer_views.xml", "views/estate_menus.xml", + "data/demo_types.xml", + "data/demo_tags.xml", + "data/demo_property.xml", ], "application": True, "author": "dhruvi kalariya", diff --git a/estate/data/demo_property.xml b/estate/data/demo_property.xml new file mode 100644 index 00000000000..ce115dce60e --- /dev/null +++ b/estate/data/demo_property.xml @@ -0,0 +1,38 @@ + + + + House in ahemedabad + 700000 + near sg highway + 123456 + 123456 + 3 + 180 + 2 + True + True + 120 + south + True + + + + + + Flat in surat + 500000 + near station + 543210 + 123456 + 3 + 180 + 2 + True + True + 120 + west + True + + + + diff --git a/estate/data/demo_tags.xml b/estate/data/demo_tags.xml new file mode 100644 index 00000000000..fd46541c1e0 --- /dev/null +++ b/estate/data/demo_tags.xml @@ -0,0 +1,14 @@ + + + + Renovated + + + + Cozy + + + + Luxury + + diff --git a/estate/data/demo_types.xml b/estate/data/demo_types.xml new file mode 100644 index 00000000000..879d4a4e2f0 --- /dev/null +++ b/estate/data/demo_types.xml @@ -0,0 +1,14 @@ + + + + House + + + + Apartment + + + + villa + + diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py index e238ea5e280..af8929d2c84 100644 --- a/estate/models/estate_property_offer.py +++ b/estate/models/estate_property_offer.py @@ -15,4 +15,4 @@ class EstatePropertyOffer(models.Model): copy=False, ) partner_id = fields.Many2one("res.partner", string="Partner", required=True) - property_id = fields.Many2one("estate.property", string="Property", required=True) + property_id = fields.Many2one("estate.property", string="Property", required=True, ondelete="cascade") diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py index 643c791ed2e..1a97c3f4a96 100644 --- a/estate/models/estate_property_type.py +++ b/estate/models/estate_property_type.py @@ -5,4 +5,5 @@ class EstatePropertyType(models.Model): _name = "estate.property.type" _description = "Real Estate Property Type" - name = fields.Char(string="Type", required=True) \ No newline at end of file + name = fields.Char(string="Type", required=True) + \ No newline at end of file diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 6b9ab3631fc..2f3a03db7ce 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -14,6 +14,7 @@ + @@ -86,6 +87,9 @@ + + +