Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Do NOT update manually; changes here will be overwritten by Copier
_commit: v1.27
_commit: v1.29
_src_path: https://github.com/OCA/oca-addons-repo-template.git
ci: GitHub
convert_readme_fragments_to_markdown: false
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ jobs:
pre-commit:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v2
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Get python version
run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
- uses: actions/cache@v1
- uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
name: Detect unreleased dependencies
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: |
for reqfile in requirements.txt test-requirements.txt ; do
if [ -f ${reqfile} ] ; then
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:
ports:
- 5432:5432
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install addons and dependencies
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ repos:
- --header
- "# generated from manifests external_dependencies"
- repo: https://github.com/PyCQA/flake8
rev: 3.9.2
rev: 5.0.0
hooks:
- id: flake8
name: flake8
Expand Down
3 changes: 0 additions & 3 deletions queue_management/views/queue_location.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,9 @@
name='token_location_cancelled_ids'
context="{'location_id': id}"
/>


</page>
</notebook>
</sheet>
<div class="oe_chatter" />
</form>
</field>
</record>
Expand Down
1 change: 0 additions & 1 deletion queue_management/views/queue_token.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
</page>
</notebook>
</sheet>
<div class="oe_chatter" />
</form>
</field>
</record>
Expand Down
9 changes: 9 additions & 0 deletions queue_management_display/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3

========================
Queue Management Display
========================

Management of queue displays
1 change: 1 addition & 0 deletions queue_management_display/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
27 changes: 27 additions & 0 deletions queue_management_display/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2022 CreuBlanca
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Queue Management Display",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"website": "https://github.com/tegin/kiwi",
"author": "CreuBlanca",
"depends": ["queue_management", "bus", "base_sparse_field"],
"data": [
"views/queue_token_location.xml",
"views/queue_location.xml",
"security/ir.model.access.csv",
"views/queue_display.xml",
"views/queue_management.xml",
],
# "qweb": ["static/src/xml/queue_management.xml"],
"demo": ["demo/data.xml"],
"assets": {
Copy link
Author

@luisDIXMIT luisDIXMIT Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

He eliminado la carpeta templates que contenía assets.xml y los he añadido aquí. No se si la estructura de static/src es la correcta. WDYT?

"web.assets_backend": [
"/queue_management_display/static/src/**/*.esm.js",
"/queue_management_display/static/src/**/*.xml",
"/queue_management_display/static/src/**/*.scss",
]
},
}
14 changes: 14 additions & 0 deletions queue_management_display/demo/data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2022 CreuBlanca
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo noupdate="1">
<record id="queue_display_demo_1" model="queue.display">
<field name="name">Display DEMO</field>
<field name="description">Display CreuBlanca</field>
<field
name="location_ids"
eval="[(4,ref('queue_management.queue_location_demo_1')),
(4,ref('queue_management.queue_location_demo_2'))]"
/>
</record>
</odoo>
6 changes: 6 additions & 0 deletions queue_management_display/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from . import queue_display
from . import queue_location
from . import queue_token_location
from . import queue_location_group
from . import queue_token_location_action
from . import ir_websocket
36 changes: 36 additions & 0 deletions queue_management_display/models/ir_websocket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import re

from odoo import models
from odoo.exceptions import AccessDenied


class IrWebsocket(models.AbstractModel):
_inherit = "ir.websocket"

def _build_bus_channel_list(self, channels):
if self.env.uid:
# Do not alter original list.
channels = list(channels)

Check warning on line 13 in queue_management_display/models/ir_websocket.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/ir_websocket.py#L13

Added line #L13 was not covered by tests
for channel in channels:
if isinstance(channel, str):
match = re.match(r"queue.display:(\d+)", channel)

Check warning on line 16 in queue_management_display/models/ir_websocket.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/ir_websocket.py#L16

Added line #L16 was not covered by tests
if match:
res_id = int(match[1])

Check warning on line 18 in queue_management_display/models/ir_websocket.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/ir_websocket.py#L18

Added line #L18 was not covered by tests

# Verify access to the edition channel.
if not self.env.user._is_internal():
raise AccessDenied()

Check warning on line 22 in queue_management_display/models/ir_websocket.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/ir_websocket.py#L22

Added line #L22 was not covered by tests

document = self.env["queue.display"].browse([res_id])

Check warning on line 24 in queue_management_display/models/ir_websocket.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/ir_websocket.py#L24

Added line #L24 was not covered by tests
if not document.exists():
continue

Check warning on line 26 in queue_management_display/models/ir_websocket.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/ir_websocket.py#L26

Added line #L26 was not covered by tests

document.check_access_rights("read")
document.check_access_rule("read")
document.check_access_rights("write")
document.check_access_rule("write")

Check warning on line 31 in queue_management_display/models/ir_websocket.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/ir_websocket.py#L28-L31

Added lines #L28 - L31 were not covered by tests

channels.append(

Check warning on line 33 in queue_management_display/models/ir_websocket.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/ir_websocket.py#L33

Added line #L33 was not covered by tests
(self.env.registry.db_name, document._name, document.id)
)
return super()._build_bus_channel_list(channels)

Check warning on line 36 in queue_management_display/models/ir_websocket.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/ir_websocket.py#L36

Added line #L36 was not covered by tests
138 changes: 138 additions & 0 deletions queue_management_display/models/queue_display.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Copyright 2022 CreuBlanca
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from datetime import timedelta

from lxml import etree

from odoo import api, fields, models


class QueueDisplay(models.Model):

_name = "queue.display"
_description = "Queue Display" # TODO

name = fields.Char()
description = fields.Text()
location_ids = fields.Many2many("queue.location")
show_items = fields.Integer(default=10)
max_time = fields.Float(default=24) # Time maximum
shiny_time = fields.Float(default=0.05) # By default, 3 minutes
items = fields.Serialized(compute="_compute_items")
kind = fields.Selection(
[("notification", "Notification screen"), ("control", "Control Screen")],
default="notification",
required=True,
)
qweb = fields.Text(default=lambda r: r._default_qweb())
parsed_qweb = fields.Html(compute="_compute_parsed_qweb")
css = fields.Text()
audio_file = fields.Binary()
audio_filename = fields.Char()

def get_data(self):
self.ensure_one()
return {

Check warning on line 36 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L35-L36

Added lines #L35 - L36 were not covered by tests
"id": self.id,
"name": self.name,
"description": self.description,
"parsed_qweb": self.parsed_qweb,
"items": self.items,
"css": self.css,
"audio_file": self.audio_file,
"shiny_time": self.shiny_time,
"max_time": self.max_time,
"show_items": self.show_items,
}

@api.depends("qweb")
def _compute_parsed_qweb(self):
qweb = self.env["ir.qweb"]

Check warning on line 51 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L51

Added line #L51 was not covered by tests
for record in self:
record.parsed_qweb = qweb._render(

Check warning on line 53 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L53

Added line #L53 was not covered by tests
etree.fromstring(record.qweb), {"data": self}
)

def _default_qweb(self):
return """
<div class="row o_queue_management_display_header">
<div class="col-2 queue_logo">
<img t-attf-src="/logo.png?company=#{company_id}" t-attf-alt="#{company}" />
</div>
<div class="col-8 o_queue_management_display_header_title">
<h1 t-esc="data.description" />
</div>
<div class="col-2 o_queue_management_display_header_datetime">
<div class="o_queue_management_display_header_clock" />
</div>
</div>
<div class="row o_queue_management_display_body">
<div class="col-4 o_queue_management_display_body_content">
<div class="o_queue_management_display_body_content_header row">
<t t-call="queue_management_display.queue_display_token">
<t t-set="token">Token</t>
<t t-set="location">Location</t>
</t>

</div>
<div class="o_queue_management_display_body_content_body row" />
</div>
<div class="col-8 o_queue_management_display_advertising">
<!-- TODO: Add your video here -->
</div>
</div>
<div class="row o_queue_management_display_footer">
<!-- TODO: Add Your Social Media data here -->
</div>
"""

def open_display(self):
"""
Open XML id depending on wich type os self.kind you have choosed.
"""
self.ensure_one()
action = self.env["ir.actions.act_window"]._for_xml_id(

Check warning on line 95 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L94-L95

Added lines #L94 - L95 were not covered by tests
"queue_management_display.queue_display_fullscreen_%s_act_window"
% self.kind
)
action["res_id"] = self.id
return action

Check warning on line 100 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L99-L100

Added lines #L99 - L100 were not covered by tests

@api.depends()
def _compute_items(self):
for record in self:
record.items = {"tokens": record._get_display_tokens()}

Check warning on line 105 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L105

Added line #L105 was not covered by tests

def _get_display_tokens(self):
actions = self.env["queue.token.location.action"].search(

Check warning on line 108 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L108

Added line #L108 was not covered by tests
[
("location_id", "in", self.location_ids.ids),
(
"date",
">",
fields.Datetime.now() + timedelta(hours=-self.max_time),
),
("action", "=", "call"),
],
order="date desc",
)
token_locations = self.env["queue.token.location"]
final_actions = self.env["queue.token.location.action"]

Check warning on line 121 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L120-L121

Added lines #L120 - L121 were not covered by tests
for action in actions:
if action.token_location_id not in token_locations:
token_locations |= action.token_location_id
final_actions |= action

Check warning on line 125 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L124-L125

Added lines #L124 - L125 were not covered by tests
if len(token_locations) >= self.show_items:
break
return [

Check warning on line 128 in queue_management_display/models/queue_display.py

View check run for this annotation

Codecov / codecov/patch

queue_management_display/models/queue_display.py#L127-L128

Added lines #L127 - L128 were not covered by tests
{
"id": action.token_location_id.id,
"token": action.token_id.name,
"location": action.location_id.display_description
or action.location_id.name,
"last_call": fields.Datetime.to_string(action.date),
"last_call_int": action.date.timestamp(),
}
for action in final_actions
]
12 changes: 12 additions & 0 deletions queue_management_display/models/queue_location.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2022 CreuBlanca
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class QueueLocation(models.Model):

_inherit = "queue.location"

display_ids = fields.Many2many("queue.display")
display_description = fields.Char()
9 changes: 9 additions & 0 deletions queue_management_display/models/queue_location_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright 2022 CreuBlanca
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import models


class QueueLocationGroup(models.Model):

_inherit = "queue.location.group"
Loading