Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions task_manager/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from . import models

from odoo import Command


def add_tags(env):
tags = []
for i in range(10):
tags.append(
{
"name": f"tag_{i + 1}",
"color": i,
}
)

env["task.manager.tags"].create(tags)


def _pre_init_hook(env):
query = """
DO $$
DECLARE
i INT;
new_partner_id INT;
BEGIN
FOR i IN 0..9 LOOP
INSERT INTO res_partner (name, phone, company_id, active, type)
VALUES ('user_' || i, '0987654321', 1, true, 'contact')
RETURNING id INTO new_partner_id;

INSERT INTO res_users (login, partner_id, company_id, active, notification_type)
VALUES ('user_' || i || '@example.com', new_partner_id, 1, true, 'email');
END LOOP;
END $$;
"""
env.cr.execute(query)


def remove_users_with_mobile_number(env):
target_logins = [f"user_{i}@example.com" for i in range(10)]
users_to_remove = env["res.users"].search([("login", "in", target_logins)])

if users_to_remove:
partner_records = users_to_remove.partner_id
users_to_remove.unlink()
partner_records.unlink()
18 changes: 18 additions & 0 deletions task_manager/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "Task Manager",
"application": True,
"installable": True,
"author": "sngoh",
"depends": ["mail"],
"license": "LGPL-3",
"data": [
"security/ir.access.csv",
"data/ir_cron_data.xml",
"views/task_manager_tags_view.xml",
"views/task_manager_view.xml",
"views/task_manager_menus.xml",
],
"pre_init_hook": "_pre_init_hook",
"post_init_hook": "add_tags",
"uninstall_hook": "remove_users_with_mobile_number",
}
20 changes: 20 additions & 0 deletions task_manager/data/ir_cron_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<data noupdate="1">

<record id="ir_cron_auto_archive_task_after_7_pm" model="ir.cron">
<field name="name">Auto Archive Task After 7pm</field>
<field name="model_id" ref="model_task_manager" />
<field name="state">code</field>
<field name="code">model._auto_archive()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="user_id" ref="base.user_root" />
<field name="nextcall" eval="(DateTime.now().replace(hour=19, minute=0, second=0)).strftime('%Y-%m-%d %H:%M:%S')" />
</record>

</data>


</odoo>
2 changes: 2 additions & 0 deletions task_manager/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import task_manager
from . import task_manager_tags
134 changes: 134 additions & 0 deletions task_manager/models/task_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
from odoo import api, Command, fields, models
from odoo.exceptions import UserError


class TaskManagerTask(models.Model):
_name = "task.manager"
_inherit = ["mail.thread"]
_description = "Task Manager"

def _get_default_deadline(self):
return fields.Datetime.add(fields.Datetime.today(), days=3)

name = fields.Char(tracking=True, required=True)
active = fields.Boolean(default=True)
assigned_user = fields.Many2one("res.users", tracking=True)
deadline = fields.Datetime(
tracking=True,
required=True,
default=lambda self: self._get_default_deadline(),
)
status = fields.Selection(
string="Status",
selection=[
("new", "New"),
("in_progress", "In Progress"),
("done", "Done"),
],
default="new",
tracking=True,
)
tag_ids = fields.Many2many(
"task.manager.tags",
compute="_compute_assigned_user",
store=True,
)
days_remaining = fields.Integer(compute="_compute_days_remaining")
count_of_assignes = fields.Integer(compute="_compute_count_of_assignes")

@api.depends("deadline")
def _compute_days_remaining(self):
for task in self:
task.days_remaining = (task.deadline - fields.Datetime.today()).days

@api.depends("assigned_user")
def _compute_count_of_assignes(self):
for task in self:
task.count_of_assignes = len(task.assigned_user)

@api.depends("assigned_user")
def _compute_assigned_user(self):
tag_name = "assigned"
tag = self.env["task.manager.tags"].search([("name", "=", tag_name)], limit=1)
if not tag:
tag = self.env["task.manager.tags"].create({"name": tag_name})

unlink_ids = []
link_ids = []

for task in self:
if not task.assigned_user and tag in task.tag_ids:
unlink_ids.append(task.id)
elif task.assigned_user and tag not in task.tag_ids:
link_ids.append(task.id)

if unlink_ids:
self.browse(unlink_ids).tag_ids = [Command.unlink(tag.id)]
if link_ids:
self.browse(link_ids).tag_ids = [Command.link(tag.id)]

def write(self, vals):
is_archiving = "active" in vals
for task in self:
if task.status == "done" and not is_archiving:
raise UserError("Cannot update task's details in the Done state.")

return super().write(vals)

def quick_archive(self):
if self:
tasks = self.filtered(lambda t: t.status == "done" and t.active)
else:
tasks = self.env["task.manager"].search(
[
("status", "=", "done"),
("active", "=", True),
],
)
if tasks:
tasks.action_archive()

def print_task_count(self):
task_count = self.env["task.manager"].search_count([])
return {
"effect": {
"fadeout": "slow",
"message": f"{task_count} Tasks are there.",
"img_url": "/web/static/img/smile.svg",
"type": "rainbow_man",
}
}

def generate_multiple_tasks(self):
tasks = [
{"name": "Generated Task 1", "deadline": fields.Datetime.today()},
{"name": "Generated Task 2", "deadline": fields.Datetime.today()},
]
self.env["task.manager"].create(tasks)

def _auto_archive(self):
done_tasks = self.env["task.manager"].search(
[
("status", "=", "done"),
("active", "=", True),
],
)
done_tasks.action_archive()

@api.autovacuum
def _gc_delete_archive_task(self):
old_archived_tasks = self.env["task.manager"].search(
[
("active", "=", False),
(
"create_date",
"<",
fields.Datetime.subtract(
fields.Datetime.today(),
days=31,
),
),
],
)
# breakpoint()
old_archived_tasks.unlink()
15 changes: 15 additions & 0 deletions task_manager/models/task_manager_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from odoo import fields, models


class TaskManagerTags(models.Model):
_name = "task.manager.tags"
_description = "Tags for Tasks"
_order = "name"

name = fields.Char(required=True)
color = fields.Integer()

_check_unique_tag = models.Constraint(
"UNIQUE(name)",
"A property tag name must be unique",
)
3 changes: 3 additions & 0 deletions task_manager/security/ir.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
id,name,model_id,group_id/id,operation,domain
access_task_manager,access_task_manager,task.manager,base.group_user,crud,
access_task_manager_tags,access_task_manager_tags,task.manager.tags,base.group_user,crud,
13 changes: 13 additions & 0 deletions task_manager/views/task_manager_menus.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<menuitem id="menu_root" name="Task Manager">
<menuitem id="task_menu" name="Tasks">
<menuitem id="task" action="task_manager_action_view" />
</menuitem>
<menuitem id="Configuration" name="Configuration">
<menuitem id="tags" action="task_manager_tags_action_view" />
</menuitem>
</menuitem>

</odoo>
37 changes: 37 additions & 0 deletions task_manager/views/task_manager_tags_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="task_manager_tags_view_list" model="ir.ui.view">
<field name="name">task.manager.tags.view.list</field>
<field name="model">task.manager.tags</field>
<field name="arch" type="xml">
<list>
<field name="name" />
<field name="color" widget="color_picker" />
</list>
</field>
</record>

<record id="task_manager_tags_view_form" model="ir.ui.view">
<field name="name">task.manager.tags.view.form</field>
<field name="model">task.manager.tags</field>
<field name="arch" type="xml">
<form>
<sheet>
<h1>
<field name="name" />
</h1>
<separator />
<field name="color" widget="color_picker" />
</sheet>
</form>
</field>
</record>

<record id="task_manager_tags_action_view" model="ir.actions.act_window">
<field name="name">Task Tags</field>
<field name="res_model">task.manager.tags</field>
<field name="view_mode">list,form</field>
</record>

</odoo>
85 changes: 85 additions & 0 deletions task_manager/views/task_manager_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="task_manager_view_list" model="ir.ui.view">
<field name="name">task.manager.list</field>
<field name="model">task.manager</field>
<field name="arch" type="xml">
<list string="Tasks">
<header>
<button string="Quick Archive" class="btn-secondary" name="quick_archive"
type="object" display="always" />
<button string="Print Count" class="btn-secondary" name="print_task_count"
type="object" display="always" />
<button string="Generate Task" class="btn-secondary" name="generate_multiple_tasks"
type="object" display="always" />
</header>
<field name="name" />
<field
name="tag_ids" widget="many2many_tags"
options="{'color_field': 'color'}" />
<field name="deadline" />
<field name="count_of_assignes" />
<field name="assigned_user" />
<field name="status" />
<field name="days_remaining" />
</list>
</field>
</record>

<record id="task_manager_view_form" model="ir.ui.view">
<field name="name">task.manager.form</field>
<field name="model">task.manager</field>
<field name="arch" type="xml">
<form string="Task">
<header>
<field name="status" widget="statusbar" />
</header>
<sheet>
<h1>
<field name="name" placeholder="Task's Name" />
</h1>
<field
name="tag_ids" widget="many2many_tags"
options="{'color_field': 'color'}" />
<separator />
<group>
<group>
<field name="deadline" />
<field name="status" />
</group>
<group>
<field name="assigned_user" />
</group>
</group>
</sheet>
<chatter />
</form>
</field>
</record>

<record id="task_manager_view_kanban" model="ir.ui.view">
<field name="name">task.manager.view.kanban</field>
<field name="model">task.manager</field>
<field name="arch" type="xml">
<kanban default_group_by="status">
<field name="status" />
<template>
<t t-name="card">
<div>
<field name="name" class="fw-bold fs-5" />
</div>
</t>
</template>
</kanban>
</field>

</record>

<record id="task_manager_action_view" model="ir.actions.act_window">
<field name="name">Tasks</field>
<field name="res_model">task.manager</field>
<field name="view_mode">list,form,kanban</field>
</record>

</odoo>