sethy final

This commit is contained in:
Benoît Vézina 2024-03-21 13:16:15 -04:00
parent 43940f428e
commit 2081f149ee
11 changed files with 331 additions and 127 deletions

View file

@ -27,6 +27,7 @@
'data': [
# Reference to XML, CSV, and other data files
'data/membership_category_data.xml',
'data/ir_cron_data.xml',
'data/product_template_data.xml',
'data/partner_category_data.xml',
'data/partner_relation_type_data.xml',
@ -36,7 +37,7 @@
'views/property_view.xml',
'views/res_partner_views.xml',
'security/ir.model.access.csv',
'wizard/transfer_property_wizard_views.xml'
],
'demo': [
# Reference to demo data files

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="ir_cron_mail_scheduler_action" model="ir.cron">
<field name="name">Sethy: Update relation</field>
<field name="model_id" ref="model_res_partner"/>
<field name="state">code</field>
<field name="code">partners = env['res.partner'].search([])
for rec in partners:
rec._compute_relation_count()
</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">12</field>
<field name="interval_type">months</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="False" name="active"/>
</record>
</data>
</odoo>

View file

@ -2,27 +2,38 @@
from odoo import api, fields, models, _
from odoo.addons.website.models import ir_http
import logging
_logger = logging.getLogger(__name__)
class ResPartner(models.Model):
_inherit = 'res.partner'
@api.model
def _property_category_id(self):
def _tag_property(self):
return self.env.ref('bemade_sethy_configuration.partner_tag_property', raise_if_not_found=False)
surface = fields.Float(string='Surface (ha)') # terrain
lot_number = fields.Text(string='Lot Number') # terrain
@api.model
def _tag_owner(self):
return self.env.ref('bemade_sethy_configuration.partner_tag_owner', raise_if_not_found=False)
ref_project = fields.Text(string='Project No') # proprio
intent_signing = fields.Boolean(string='Intent to sign') # proprio
cyberimpact = fields.Boolean(string='Cyberimpact') # proprio
specification_date = fields.Date(string='Specification date') # proprio
crm_stage_activity = fields.Text(string='Activity Stage') # proprio
@api.model
def _relation_owner_property(self):
return self.env.ref('bemade_sethy_configuration.partner_relation_property', raise_if_not_found=False)
property_count = fields.Integer(string='Property count', compute='_compute_property_count', store=True)
is_owner = fields.Boolean(string='Is Owner', compute='_compute_property_count', store=True)
# Add new fields to the res.partner model for property management
surface = fields.Float(string='Surface (ha)')
lot_number = fields.Text(string='Lot Number')
# Add new fields to the res.partner model for owner/member management
ref_project = fields.Text(string='Project No')
intent_signing = fields.Boolean(string='Intent to sign')
cyberimpact = fields.Boolean(string='Cyberimpact')
specification_date = fields.Date(string='Specification date')
crm_stage_activity = fields.Text(string='Activity Stage')
company_use = fields.Text(string='Company related')
# Add new fields to the res.partner model for member management
sethy_first_date = fields.Date(string='First membership date') # member
sethy_last_date = fields.Date(string='Last membership date') # member
sethy_renew_date = fields.Date(string='Next renew date date') # member
@ -32,7 +43,6 @@ class ResPartner(models.Model):
is_property = fields.Boolean(
string='Is Property',
default=False,
compute='_compute_is_property',
inverse='_inverse_is_property',
store=True
@ -46,60 +56,149 @@ class ResPartner(models.Model):
('4', 'High')],
string='Interest Level') # proprio
company_use = fields.Text(string='Company related') # proprio
# Filtered fields relation_all_ids for owner
relation_owner_ids = fields.One2many(
"res.partner.relation.all",
compute="_compute_owner_ids",
string="Owner ids"
compute="_compute_relation_property_owner",
string="Owner ids",
compute_sudo=True,
)
# Filtered fields relation_all_ids for property
relation_property_ids = fields.One2many(
"res.partner.relation.all",
compute="_compute_property_ids",
string="Property ids"
compute="_compute_relation_property_owner",
string="Property ids",
compute_sudo=True,
)
# Add new fields to the res.partner model for owner management
property_count = fields.Integer(
string='Property count',
compute='_compute_property_count',
store=True,
compute_sudo=True
)
is_owner = fields.Boolean(
string='Is Owner',
compute='_compute_owner',
store=True,
compute_sudo=True,
)
@api.depends('relation_all_ids')
def _compute_owner(self):
#owner_tag = self._tag_owner()
owner_tag = self.env.ref('bemade_sethy_configuration.partner_tag_owner', raise_if_not_found=False)
for record in self:
record.is_owner = record.relation_count > 0
if record.is_owner:
record.category_id |= owner_tag
else:
record.category_id -= owner_tag
# this is an hugly fix because @api depends doesn't work on new function so hacking it here
@api.depends("relation_all_ids")
def _compute_relation_count(self):
super()._compute_relation_count()
#owner_tag = self._tag_owner()
owner_tag = self.env.ref('bemade_sethy_configuration.partner_tag_owner', raise_if_not_found=False)
for record in self:
for line in record.relation_all_ids:
if line.active and line.type_id == owner_tag:
record.relation_count += 1
record.is_owner = record.relation_count > 0 and not record.is_property
if record.is_owner:
record.category_id |= owner_tag
else:
record.category_id -= owner_tag
@api.depends('category_id')
def _compute_is_property(self):
default_is_property = self._context.get('default_is_property', None)
#property_tag = self._tag_property()
property_tag = self.env.ref('bemade_sethy_configuration.partner_tag_property', raise_if_not_found=False)
for partner in self:
# Check if the property tag exists. If it doesn't, set is_property to False.
# Because module installation order is not guaranteed, the tag may not exist yet when this method is called.
# This is due to store=True on the is_property field.
if property_tag is None:
partner.is_property = False
if default_is_property is not None and not self.id:
partner.is_property = default_is_property
else:
partner.is_property = property_tag and property_tag in partner.category_id
if property_tag is None:
partner.is_property = False
else:
partner.is_property = property_tag and property_tag in partner.category_id
def _inverse_is_property(self):
#property_tag = self._tag_property()
property_tag = self.env.ref('bemade_sethy_configuration.partner_tag_property', raise_if_not_found=False)
for partner in self:
if partner.is_property and property_tag not in partner.category_id and property_tag:
partner.category_id |= property_tag
elif not partner.is_property and property_tag in partner.category_id:
partner.category_id -= property_tag
if property_tag is not None:
for partner in self:
if partner.is_property and property_tag not in partner.category_id and property_tag:
partner.category_id |= property_tag
elif not partner.is_property and property_tag in partner.category_id:
partner.category_id -= property_tag
@api.depends('relation_property_ids')
@api.depends("relation_all_ids")
def _compute_property_count(self):
for record in self:
record.property_count = len(record.relation_property_ids)
#owner_tag = self._tag_owner()
owner_tag = self.env.ref('bemade_sethy_configuration.partner_tag_owner', raise_if_not_found=False)
record.property_count = len(record._get_owners())
record.is_owner = record.property_count > 0
if owner_tag is not None:
if record.is_owner:
record.category_id |= owner_tag
else:
record.category_id -= owner_tag
@api.depends('relation_all_ids')
def _compute_owner_ids(self):
@api.depends(
'relation_all_ids',
'relation_all_ids.type_id',
'relation_all_ids.date_end',
'relation_all_ids.this_partner_id',
'relation_all_ids.other_partner_id',
'relation_all_ids.is_inverse'
)
def _compute_relation_property_owner(self):
for record in self:
record.relation_owner_ids = record.relation_all_ids.filtered(
lambda line: (
line.type_id.name == 'Owner' and not line.is_inverse)
)
@api.depends('relation_all_ids')
def _compute_property_ids(self):
for record in self:
record.relation_property_ids = record.relation_all_ids.filtered(
lambda line: (
line.type_id.name == 'Owner' and line.is_inverse)
)
# relations = self.env['res.partner.relation.all']
# for line in record.relation_all_ids:
# if active and is_property and is_inverse:
# relations |= line
# record.relation_property_ids = relations
record.relation_property_ids = record._get_properties()
record.relation_owner_ids = record._get_owners()
# Just for debugging below this line
type_property = self._relation_owner_property()
#type_property = self.env.ref('bemade_sethy_configuration.partner_relation_property')
for line in record.relation_all_ids:
active = line.active
is_property = line.type_id == type_property
is_inverse = line.is_inverse
_logger.info(f"This partner: {line.this_partner_id.name}")
_logger.info(f"Other partner: {line.other_partner_id.name}")
_logger.info(f"Active: {active}, Property: {is_property}, Inverse: {is_inverse}, Type: {line.type_id.name}")
def _get_properties(self):
self.ensure_one()
#type_property = self._relation_owner_property()
type_property = self.env.ref('bemade_sethy_configuration.partner_relation_property')
return self.relation_all_ids.filtered(
lambda line: (line.type_id.id == type_property.id and line.is_inverse and line.active)
)
def _get_owners(self):
self.ensure_one()
#type_property = self._relation_owner_property()
type_property = self.env.ref('bemade_sethy_configuration.partner_relation_property', raise_if_not_found=False)
return self.relation_all_ids.filtered(
lambda line: (line.type_id.id == type_property.id and not line.is_inverse and line.active)
)
@api.onchange('lot_number')
def _onchange_lot_number(self):
for lot in self:

View file

@ -1,3 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_create_property_wizard_salesman,"Access Create Property Wizard Salesman",model_create_property_wizard,sales_team.group_sale_salesman,1,1,1,1
access_create_property_wizard_manager,"Access Create Property Wizard Manager",model_create_property_wizard,sales_team.group_sale_manager,1,1,1,1
access_transfer_property_wizard,access_transfer_property_wizard,model_transfer_property_wizard,base.group_user,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_create_property_wizard_salesman access_transfer_property_wizard Access Create Property Wizard Salesman access_transfer_property_wizard model_create_property_wizard model_transfer_property_wizard sales_team.group_sale_salesman base.group_user 1 1 1 1
access_create_property_wizard_manager Access Create Property Wizard Manager model_create_property_wizard sales_team.group_sale_manager 1 1 1 1

View file

@ -18,6 +18,22 @@
</field>
</record>
<record model="ir.ui.view" id="kanban_property">
<field name="name">res.partner.kanban.property</field>
<field name="model">res.partner</field>
<field name="arch" type="xml">
<kanban class="o_res_partner_kanban">
<field name="display_name"/>
<field name="city"/>
<field name="zip"/>
<field name="state_id"/>
<field name="country_id"/>
<field name="category_id" widget="many2many_tags" options="{'color_field': 'color'}"/>
<field name="active" invisible="1"/>
</kanban>
</field>
</record>
<menuitem
name="Property"
id="menu_property"
@ -29,10 +45,10 @@
<record id="action_properties" model="ir.actions.act_window">
<field name="name">Properties</field>
<field name="res_model">res.partner</field>
<field name="view_mode">tree,form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="view_id" ref="tree_property"/>
<field name="domain">[('is_property','=',True)]</field>
<field name="context">{'default_is_property': True}</field>
<field name="context">{'default_is_property': True, 'default_is_company': True}</field>
</record>
<menuitem

View file

@ -1,9 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="action_add_property" model="ir.actions.act_window">
<field name="name">Add Property</field>
<field name="res_model">create.property.wizard</field>
<record id="open_partner_form" model="ir.actions.act_window">
<field name="name">Open Partner</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.partner</field>
<field name="view_mode">form</field>
<field name="target">current</field>
</record>
<!-- Action pour ouvrir l'assistant de transfert de propriété -->
<record id="action_start_transfer_property_wizard" model="ir.actions.act_window">
<field name="name">Transfer Property</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">transfer.property.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
@ -13,17 +23,44 @@
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<sheet position="before">
<header>
<button name="%(action_start_transfer_property_wizard)d"
type="action"
class="btn-primary"
string="Transfer Property"
context="{'default_property_id': id}"
invisible="is_property == False"
/>
</header>
</sheet>
<field name="company_type" position="after">
<field name="is_property" invisible="False"/>
<field name="is_property" invisible="True"/>
</field>
<xpath expr="//field[@name='name' and @id='company']" position="replace">
<field id="company" class="text-break" name="name" default_focus="1"
placeholder="e.g. Lumber Inc"
required="type == 'contact'"
invisible="not is_company or is_property"/>
<field id="lot_number" class="text-break" name="lot_number" placeholder="123456789"
invisible="not is_property"/>
<field name="company_type" position="attributes">
<attribute name="invisible">is_property == True</attribute>
</field>
<field name="vat" position="before">
<field name="ref" position="move"/>
</field>
<xpath expr="//field[@name='name' and @id='company']" position="attributes">
<attribute name="invisible">not is_company or is_property</attribute>
</xpath>
<xpath expr="//field[@name='name' and @id='individual']" position="attributes">
<attribute name="invisible">is_company or is_property</attribute>
</xpath>
<xpath expr="//field[@name='name' and @id='company']" position="after">
<field id="lot_number"
class="text-break"
name="lot_number" placeholder="123456789"
invisible="not is_property"
/>
</xpath>
<button name="schedule_meeting" position="attributes">
@ -34,6 +71,10 @@
<attribute name="invisible">is_property == True</attribute>
</button>
<xpath expr="//field[@name='parent_id']/ancestor::div[hasclass('o_row')]" position="attributes">
<attribute name="invisible">is_property == True</attribute>
</xpath>
<button name="action_view_partner_invoices" position="attributes">
<attribute name="invisible">is_property == True</attribute>
</button>
@ -65,41 +106,41 @@
<xpath expr="//field[@name='function']/ancestor::group[1]" position="after">
<group invisible="is_property == False">
<field name="surface"/>
<field name="category_id" widget="many2many_tags"
options="{'color_field': 'color', 'no_create_edit': True}"/>
<field name="category_id"
widget="many2many_tags"
options="{'color_field': 'color', 'no_create_edit': True}"
/>
</group>
</xpath>
<xpath expr="//page[@name='contact_addresses']" position="after">
<page string="Property" name="bemade_sethy_configuration.res_partner.defaults.form">
<field name="relation_property_ids" string="All Owners" invisible="is_property == False">
<tree editable="top">
<field name="other_partner_id"
required="True"
options="{'no_create': True}"
string="Owner"/>
<tree>
<field name="other_partner_id"
required="True"
options="{'no_create': True}"
string="Owner"
/>
<field name="date_start"/>
<field name="date_end"/>
</tree>
</field>
<field name="relation_owner_ids" string="All Properties" invisible="is_property == True">
<tree editable="top">
<field name="other_partner_id"
required="True"
options="{'no_create': True}"
string="Property"/>
<tree>
<field name="other_partner_id"
required="True"
options="{'no_create': True}"
string="Property"
/>
<field name="date_start"/>
<field name="date_end"/>
</tree>
</field>
<button name="%(action_add_property)d"
type="action"
class="oe_highlight"
string="Add Property"
invisible="is_property == True"
/>
</page>
</xpath>
<xpath expr="//page[@name='contact_addresses']" position="after">
<page string="Sethy" name="bemade_sethy_configuration.res_partner.page.sethy">
<group>
@ -114,6 +155,18 @@
</field>
</record>
<record id="view_res_partner_search_inherit" model="ir.ui.view">
<field name="name">res.partner.search.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='inactive']" position="before">
<field name="ref"/>
<filter string="Owner" name="owner" domain="[('is_owner', '=', True)]"/>
</xpath>
</field>
</record>
<!-- <record id="view_res_partner_filter_inherit" model="ir.ui.view">-->
<!-- <field name="name">res.partner.select.inherit</field>-->
<!-- <field name="model">res.partner</field>-->

View file

@ -1 +1 @@
from . import property_wizard
from . import transfer_property_wizard

View file

@ -1,31 +0,0 @@
from odoo import models, fields, api
class CreatePropertyWizard(models.TransientModel):
_name = 'create.property.wizard'
_description = 'Property Wizard'
property_id = fields.Many2one(
comodel_name='res.partner',
string='Property',
domain=[('is_property', '=', True)],
required=True
)
def action_done(self):
# Here process your data, for example:
self.env['res.partner'].browse(self._context.get('active_ids')).write({'property_id': self.property_id.id})
def action_create_property(self):
# Redirect to the form view of 'res.partner' for user to create new property
return {
'type': 'ir.actions.act_window',
'res_model': 'res.partner',
'view_mode': 'form',
'view_type': 'form',
'context': {"default_is_property": True},
'target': 'new',
}
def action_select_property(self):
# wizard action goes here. Use self.partner_id for selected property
pass

View file

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="property_wizard_form_view" model="ir.ui.view">
<field name="name">property.wizard.form</field>
<field name="model">property.wizard</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Property Wizard">
<group>
<field name="partner_id"/>
</group>
<footer>
<button name="action_create_property" string="Create new Property" type="object" class="btn-primary"/>
<button name="action_select_property" string="Select Property" type="object" class="btn-primary"/>
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>

View file

@ -0,0 +1,44 @@
from odoo import models, fields, api
from datetime import timedelta
class TransferPropertyWizard(models.TransientModel):
_name = 'transfer.property.wizard'
_description = 'Transfer Property Wizard'
property_id = fields.Many2one(
comodel_name='res.partner',
string='Property',
domain=[('is_property', '=', True)],
required=True
)
new_owner_id = fields.Many2many(
comodel_name='res.partner',
string='New Owner',
required=True,
domain=[('is_property', '=', False)],
)
transfer_date = fields.Date(
string='Transfer Date',
required=True,
default=fields.Date.today()
)
def action_transfer_property(self):
if self.property_id.relation_property_ids.filtered("active"):
for old_owner_relation in self.property_id.relation_property_ids.filtered("active"):
if old_owner_relation.date_start and old_owner_relation.date_start >= self.transfer_date:
old_owner_relation.unlink()
else:
old_owner_relation.write({'date_end': self.transfer_date - timedelta(days=1)})
old_owner_relation.this_partner_id._compute_owner()
for new_owner in self.new_owner_id:
self.env['res.partner.relation.all'].create({
'this_partner_id': new_owner.id,
'other_partner_id': self.property_id.id,
'type_id': self.env.ref('bemade_sethy_configuration.partner_relation_property').id,
'date_start': self.transfer_date,
})
new_owner._compute_owner()
return {'type': 'ir.actions.act_window_close'}

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="property_transfer_wizard_form_view" model="ir.ui.view">
<field name="name">property.transfer.wizard.form</field>
<field name="model">transfer.property.wizard</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Property Wizard">
<group>
<field name="property_id"/>
<field name="transfer_date"/>
</group>
<group>
<field name="new_owner_id"/>
</group>
<footer>
<button name="action_transfer_property" string="Transfer Property" type="object" class="btn-primary"/>
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>