Split FSM into separate modules and switch customer to address book

This commit is contained in:
Ruslan Bakiev
2026-02-13 15:27:48 +07:00
parent 98a92286ce
commit dc58e1ffe4
46 changed files with 3125 additions and 152 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.DS_Store
__pycache__/
*.pyc
archive/

View File

@@ -1,6 +1,6 @@
ODOO_SERVICE_PREFIX ?= sandbox-odoorepair-gfijxl
MODULES ?= all
CUSTOM_MODULES ?= dsrpt_repair_main,dsrpt_repair_customers,dsrpt_repair_technicians,dsrpt_repair_materials,dsrpt_repair_work_orders
CUSTOM_MODULES ?= dsrpt_repair_config,dsrpt_address_book,dsrpt_repair_technicians,dsrpt_repair_materials,dsrpt_repair_work_orders
ODOO_CONFIG ?= /etc/odoo/odoo.conf
ODOO_DB_NAME ?=

View File

@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import models
from . import wizard

View File

@@ -0,0 +1,25 @@
{
'name': 'DSRPT Address Book',
'summary': 'Contact management with communication methods',
'description': 'Simple address book for managing contacts and their communication methods',
'version': '19.0.1.0.0',
'category': 'Tools',
'author': 'DSRPT',
'depends': ['base', 'mail', 'calendar'],
'data': [
'security/groups.xml',
'security/ir.model.access.csv',
'data/communication_types.xml',
'views/dsrpt_communication_type_views.xml',
'views/dsrpt_contact_views.xml',
'views/contact_event_views.xml',
'views/contact_source_views.xml',
'views/change_employee_wizard_views.xml',
'views/menu.xml',
'views/contact_context_views.xml',
],
'installable': True,
'application': True,
'auto_install': False,
'license': 'LGPL-3',
}

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!-- Phone -->
<record id="communication_type_phone" model="dsrpt.communication.type">
<field name="name">Phone</field>
<field name="code">phone</field>
<field name="state">active</field>
</record>
<!-- Email -->
<record id="communication_type_email" model="dsrpt.communication.type">
<field name="name">Email</field>
<field name="code">email</field>
<field name="state">active</field>
</record>
<!-- Telegram -->
<record id="communication_type_telegram" model="dsrpt.communication.type">
<field name="name">Telegram</field>
<field name="code">telegram</field>
<field name="state">active</field>
</record>
<!-- WhatsApp -->
<record id="communication_type_whatsapp" model="dsrpt.communication.type">
<field name="name">WhatsApp</field>
<field name="code">whatsapp</field>
<field name="state">active</field>
</record>
<!-- Skype -->
<record id="communication_type_skype" model="dsrpt.communication.type">
<field name="name">Skype</field>
<field name="code">skype</field>
<field name="state">active</field>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!-- No demo contacts -->
</data>
</odoo>

View File

@@ -0,0 +1,869 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * dsrpt_address_book
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0-20250807\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-09-02 04:26+0000\n"
"PO-Revision-Date: 2025-09-02 04:26+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_needaction
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_needaction
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_needaction
msgid "Action Needed"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_form
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_form
msgid "Activate"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__active
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__active
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__active
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_source__state__active
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_communication_type__state__active
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_search
msgid "Active"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_ids
msgid "Activities"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_exception_decoration
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_exception_decoration
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_exception_decoration
msgid "Activity Exception Decoration"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_state
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_state
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_state
msgid "Activity State"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_type_icon
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_type_icon
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_type_icon
msgid "Activity Type Icon"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Add notes about this contact..."
msgstr ""
#. module: dsrpt_address_book
#: model:ir.module.category,name:dsrpt_address_book.module_category_dsrpt_address_book
#: model:ir.ui.menu,name:dsrpt_address_book.menu_dsrpt_address_book_root
msgid "Address Book"
msgstr ""
#. module: dsrpt_address_book
#: model:res.groups,name:dsrpt_address_book.group_dsrpt_address_book_admin
msgid "Administrator"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_change_employee_wizard_form
msgid "Apply"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_form
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Archived"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_attachment_count
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_attachment_count
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__awaiting_qualification
msgid "Awaiting Qualification"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__calendar_event_id
msgid "Calendar Event"
msgstr ""
#. module: dsrpt_address_book
#: model:res.groups,comment:dsrpt_address_book.group_dsrpt_address_book_admin
msgid "Can configure communication types and delete contacts"
msgstr ""
#. module: dsrpt_address_book
#: model:res.groups,comment:dsrpt_address_book.group_dsrpt_address_book_user
msgid "Can view and manage contacts"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_change_employee_wizard_form
msgid "Cancel"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_event__state__cancelled
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__cancelled
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Cancelled"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.actions.server,name:dsrpt_address_book.action_server_change_employee_contacts
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_change_employee_wizard_form
msgid "Change Employee"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_change_employee_wizard
msgid "Change Employee Wizard"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__code
msgid "Code"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__color
msgid "Color"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Communication"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_dsrpt_communication_type
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_form
msgid "Communication Type"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_dsrpt_communication_type
#: model:ir.ui.menu,name:dsrpt_address_book.menu_dsrpt_communication_types
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_list
msgid "Communication Types"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_dsrpt_communication_type
msgid ""
"Communication types define the ways to contact people (Phone, Email, "
"Telegram, etc.)"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__communication_ids
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Communications"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.ui.menu,name:dsrpt_address_book.menu_dsrpt_address_book_config
msgid "Configuration"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_dsrpt_contact
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__contact_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__contact_id
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Contact"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_contact_context
msgid "Contact Activity Context"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_calendar
msgid "Contact Calendar"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_dsrpt_contact_communication
msgid "Contact Communication"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_form
msgid "Contact Context"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_contact_context_mixin
msgid "Contact Context Mixin"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_contact_context
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_tree
msgid "Contact Contexts"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_contact_event
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_form
msgid "Contact Event"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_contact_event
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_calendar
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_tree
msgid "Contact Events"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Contact Name..."
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_contact_source
msgid "Contact Source"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_contact_source
#: model:ir.ui.menu,name:dsrpt_address_book.menu_contact_sources
msgid "Contact Sources"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_context
msgid ""
"Contact contexts are automatically created when linking a contact to documents\n"
" that inherit contact.context.mixin."
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__status
msgid "Contact processing status for AI analysis"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_source
msgid "Contact sources help you track where your contacts come from."
msgstr ""
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_dsrpt_contact
#: model:ir.ui.menu,name:dsrpt_address_book.menu_dsrpt_contacts
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_list
msgid "Contacts"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_form
msgid "Context"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__context_count
#: model:ir.ui.menu,name:dsrpt_address_book.menu_contact_context
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Contexts"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_dsrpt_communication_type
msgid "Create your first communication type!"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_context
msgid "Create your first contact context"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_event
msgid "Create your first contact event"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_source
msgid "Create your first contact source!"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_dsrpt_contact
msgid "Create your first contact!"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__create_uid
msgid "Created by"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__create_date
msgid "Created on"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Creation Date"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.module.category,description:dsrpt_address_book.module_category_dsrpt_address_book
msgid "DSRPT Address Book"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Date"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__date_start
msgid "Date & Time"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__description
msgid "Description"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__display_name
msgid "Display Name"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_event__state__done
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Done"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_source__state__draft
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_communication_type__state__draft
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_search
msgid "Draft"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__duration
msgid "Duration (hours)"
msgstr ""
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_email
msgid "Email"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__event_count
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__event_ids
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Events"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__field_name
msgid "Field Name"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_follower_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_follower_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_follower_ids
msgid "Followers"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_partner_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_partner_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__activity_type_icon
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__activity_type_icon
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__activity_type_icon
msgid "Font awesome icon e.g. fa-tasks"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Group By"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__has_message
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__has_message
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__has_message
msgid "Has Message"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__has_request
msgid "Has Request"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__id
msgid "ID"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__res_id
msgid "ID документа"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_context__res_id
msgid "ID записи в модели"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_exception_icon
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_exception_icon
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_exception_icon
msgid "Icon"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__activity_exception_icon
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__activity_exception_icon
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__activity_exception_icon
msgid "Icon to indicate an exception activity."
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__message_needaction
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__message_needaction
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__message_needaction
msgid "If checked, new messages require your attention."
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__message_has_error
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__message_has_error
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_is_follower
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_is_follower
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_context__context
msgid "JSON с информацией о документе для AI"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__write_uid
msgid "Last Updated by"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__write_date
msgid "Last Updated on"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_dsrpt_contact
msgid "Manage your contacts and their communication methods in one place."
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_has_error
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_has_error
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_ids
msgid "Messages"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
msgid "Model"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__model_name
msgid "Model Name"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__my_activity_date_deadline
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__my_activity_date_deadline
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__my_activity_date_deadline
msgid "My Activity Deadline"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__name
msgid "Name"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__user_id
msgid "New Employee"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_calendar_event_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_calendar_event_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_calendar_event_id
msgid "Next Activity Calendar Event"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_date_deadline
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_date_deadline
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_date_deadline
msgid "Next Activity Deadline"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_summary
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_summary
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_summary
msgid "Next Activity Summary"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_type_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_type_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_type_id
msgid "Next Activity Type"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__next_contact
msgid "Next Contact"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__not_customer
msgid "Not Customer"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__note
msgid "Note"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__notes
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_form
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Notes"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_needaction_counter
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_needaction_counter
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_has_error_counter
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_has_error_counter
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__message_needaction_counter
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__message_needaction_counter
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__message_needaction_counter
msgid "Number of messages requiring action"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__message_has_error_counter
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__message_has_error_counter
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_form
msgid "Open Document"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__parent_path
msgid "Parent Path"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__parent_id
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
msgid "Parent Source"
msgstr ""
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_phone
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Phone"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__phone_numbers
msgid "Phone Numbers"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_event__state__planned
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Planned"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__is_preferred
msgid "Preferred"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_form
msgid "Reset to Draft"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__user_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__user_id
msgid "Responsible"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_user_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_user_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_user_id
msgid "Responsible User"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Search Contact Events"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
msgid "Search Contexts"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.actions.server,name:dsrpt_address_book.action_server_send_transcription_added
msgid "Send Need Qualification Event"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.actions.server,name:dsrpt_address_book.action_server_send_context_update
msgid "Send Need Summary/Calendar Events"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_form
msgid "Set to Draft"
msgstr ""
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_skype
msgid "Skype"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__source_id
msgid "Source"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__state
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__state
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "State"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__state
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__status
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
msgid "Status"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__activity_state
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__activity_state
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__activity_state
msgid ""
"Status based on activities\n"
"Overdue: Due date is already passed\n"
"Today: Activity date is today\n"
"Planned: Future activities."
msgstr ""
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_telegram
msgid "Telegram"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "This Week"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Today"
msgstr ""
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_event
msgid "Track meetings, calls and other events with your contacts."
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__communication_type_id
msgid "Type"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__activity_exception_decoration
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__activity_exception_decoration
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__activity_exception_decoration
msgid "Type of the exception activity on record."
msgstr ""
#. module: dsrpt_address_book
#: model:res.groups,name:dsrpt_address_book.group_dsrpt_address_book_user
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "User"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__value
msgid "Value"
msgstr ""
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_whatsapp
msgid "WhatsApp"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__document_name
msgid "Документ"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__contact_id
msgid "Контакт"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__context
msgid "Контекст"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__res_model
msgid "Модель"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__display_name
msgid "Название"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__document_url
msgid "Ссылка"
msgstr ""
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_context__res_model
msgid "Техническое название модели документа"
msgstr ""

View File

@@ -0,0 +1,893 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * dsrpt_address_book
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 18.0-20250807\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-09-02 04:26+0000\n"
"PO-Revision-Date: 2025-09-02 04:26+0000\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Language: ru\n"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_needaction
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_needaction
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_needaction
msgid "Action Needed"
msgstr "Требуется действие"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_form
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_form
msgid "Activate"
msgstr "Активировать"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__active
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__active
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__active
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_source__state__active
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_communication_type__state__active
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_search
msgid "Active"
msgstr "Активный"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_ids
msgid "Activities"
msgstr "Действия"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_exception_decoration
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_exception_decoration
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_exception_decoration
msgid "Activity Exception Decoration"
msgstr "Исключение действия"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_state
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_state
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_state
msgid "Activity State"
msgstr "Состояние действия"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_type_icon
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_type_icon
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_type_icon
msgid "Activity Type Icon"
msgstr "Иконка типа действия"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Add notes about this contact..."
msgstr "Добавить заметки об этом контакте..."
#. module: dsrpt_address_book
#: model:ir.module.category,name:dsrpt_address_book.module_category_dsrpt_address_book
#: model:ir.ui.menu,name:dsrpt_address_book.menu_dsrpt_address_book_root
msgid "Address Book"
msgstr "Адресная книга"
#. module: dsrpt_address_book
#: model:res.groups,name:dsrpt_address_book.group_dsrpt_address_book_admin
msgid "Administrator"
msgstr "Администратор"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_change_employee_wizard_form
msgid "Apply"
msgstr "Применить"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_form
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Archived"
msgstr "Архивные"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_attachment_count
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_attachment_count
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_attachment_count
msgid "Attachment Count"
msgstr "Количество вложений"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__awaiting_qualification
msgid "Awaiting Qualification"
msgstr "Ожидает квалификацию"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__calendar_event_id
msgid "Calendar Event"
msgstr "Событие календаря"
#. module: dsrpt_address_book
#: model:res.groups,comment:dsrpt_address_book.group_dsrpt_address_book_admin
msgid "Can configure communication types and delete contacts"
msgstr "Может настраивать типы связи и удалять контакты"
#. module: dsrpt_address_book
#: model:res.groups,comment:dsrpt_address_book.group_dsrpt_address_book_user
msgid "Can view and manage contacts"
msgstr "Может просматривать и управлять контактами"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_change_employee_wizard_form
msgid "Cancel"
msgstr "Отмена"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_event__state__cancelled
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__cancelled
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Cancelled"
msgstr "Отменен"
#. module: dsrpt_address_book
#: model:ir.actions.server,name:dsrpt_address_book.action_server_change_employee_contacts
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_change_employee_wizard_form
msgid "Change Employee"
msgstr "Изменить сотрудника"
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_change_employee_wizard
msgid "Change Employee Wizard"
msgstr "Мастер смены сотрудника"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__code
msgid "Code"
msgstr "Код"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__color
msgid "Color"
msgstr "Цвет"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Communication"
msgstr "Связь"
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_dsrpt_communication_type
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_form
msgid "Communication Type"
msgstr "Тип связи"
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_dsrpt_communication_type
#: model:ir.ui.menu,name:dsrpt_address_book.menu_dsrpt_communication_types
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_list
msgid "Communication Types"
msgstr "Типы связи"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_dsrpt_communication_type
msgid ""
"Communication types define the ways to contact people (Phone, Email, "
"Telegram, etc.)"
msgstr "Типы связи определяют способы связи с людьми (телефон, email, "
"Telegram и т.д.)"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__communication_ids
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Communications"
msgstr "Средства связи"
#. module: dsrpt_address_book
#: model:ir.ui.menu,name:dsrpt_address_book.menu_dsrpt_address_book_config
msgid "Configuration"
msgstr "Настройки"
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_dsrpt_contact
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__contact_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__contact_id
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Contact"
msgstr "Контакт"
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_contact_context
msgid "Contact Activity Context"
msgstr "Контекст действий контакта"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_calendar
msgid "Contact Calendar"
msgstr "Календарь контактов"
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_dsrpt_contact_communication
msgid "Contact Communication"
msgstr "Средство связи с контактом"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_form
msgid "Contact Context"
msgstr "Контекст контакта"
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_contact_context_mixin
msgid "Contact Context Mixin"
msgstr "Миксин контекста контакта"
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_contact_context
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_tree
msgid "Contact Contexts"
msgstr "Контексты контакта"
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_contact_event
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_form
msgid "Contact Event"
msgstr "Событие контакта"
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_contact_event
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_calendar
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_tree
msgid "Contact Events"
msgstr "События контакта"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Contact Name..."
msgstr "Имя контакта..."
#. module: dsrpt_address_book
#: model:ir.model,name:dsrpt_address_book.model_contact_source
msgid "Contact Source"
msgstr "Источник контакта"
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_contact_source
#: model:ir.ui.menu,name:dsrpt_address_book.menu_contact_sources
msgid "Contact Sources"
msgstr "Источники контактов"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_context
msgid ""
"Contact contexts are automatically created when linking a contact to "
"documents\n"
" that inherit contact.context.mixin."
msgstr "Контексты контакта автоматически создаются при связывании контакта с "
"документами,\n"
" наследующими contact.context.mixin."
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__status
msgid "Contact processing status for AI analysis"
msgstr "Статус обработки контакта для анализа ИИ"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_source
msgid "Contact sources help you track where your contacts come from."
msgstr "Источники контактов помогают отслеживать, откуда пришли ваши контакты."
#. module: dsrpt_address_book
#: model:ir.actions.act_window,name:dsrpt_address_book.action_dsrpt_contact
#: model:ir.ui.menu,name:dsrpt_address_book.menu_dsrpt_contacts
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_list
msgid "Contacts"
msgstr "Контакты"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_form
msgid "Context"
msgstr "Контекст"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__context_count
#: model:ir.ui.menu,name:dsrpt_address_book.menu_contact_context
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Contexts"
msgstr "Контексты"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_dsrpt_communication_type
msgid "Create your first communication type!"
msgstr "Создайте ваш первый тип связи!"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_context
msgid "Create your first contact context"
msgstr "Создайте ваш первый контекст контакта"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_event
msgid "Create your first contact event"
msgstr "Создайте ваше первое событие контакта"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_source
msgid "Create your first contact source!"
msgstr "Создайте ваш первый источник контакта!"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_dsrpt_contact
msgid "Create your first contact!"
msgstr "Создайте ваш первый контакт!"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__create_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__create_uid
msgid "Created by"
msgstr "Создано пользователем"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__create_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__create_date
msgid "Created on"
msgstr "Дата создания"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Creation Date"
msgstr "Дата создания"
#. module: dsrpt_address_book
#: model:ir.module.category,description:dsrpt_address_book.module_category_dsrpt_address_book
msgid "DSRPT Address Book"
msgstr "DSRPT Адресная книга"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Date"
msgstr "Дата"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__date_start
msgid "Date & Time"
msgstr "Дата и время"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__description
msgid "Description"
msgstr "Описание"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__display_name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__display_name
msgid "Display Name"
msgstr "Отображаемое имя"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_event__state__done
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Done"
msgstr "Выполнено"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_source__state__draft
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_communication_type__state__draft
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_search
msgid "Draft"
msgstr "Черновик"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__duration
msgid "Duration (hours)"
msgstr "Длительность (часы)"
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_email
msgid "Email"
msgstr "Email"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__event_count
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__event_ids
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Events"
msgstr "События"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__field_name
msgid "Field Name"
msgstr "Имя поля"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_follower_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_follower_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_follower_ids
msgid "Followers"
msgstr "Подписчики"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_partner_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_partner_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_partner_ids
msgid "Followers (Partners)"
msgstr "Подписчики (Партнеры)"
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__activity_type_icon
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__activity_type_icon
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__activity_type_icon
msgid "Font awesome icon e.g. fa-tasks"
msgstr "Иконка Font Awesome, например fa-tasks"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Group By"
msgstr "Группировать по"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__has_message
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__has_message
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__has_message
msgid "Has Message"
msgstr "Есть сообщение"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__has_request
msgid "Has Request"
msgstr "Есть запрос"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__id
msgid "ID"
msgstr "ID"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__res_id
msgid "ID документа"
msgstr "ID документа"
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_context__res_id
msgid "ID записи в модели"
msgstr "ID записи в модели"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_exception_icon
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_exception_icon
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_exception_icon
msgid "Icon"
msgstr "Иконка"
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__activity_exception_icon
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__activity_exception_icon
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__activity_exception_icon
msgid "Icon to indicate an exception activity."
msgstr "Иконка для обозначения исключительного действия."
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__message_needaction
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__message_needaction
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__message_needaction
msgid "If checked, new messages require your attention."
msgstr "Если отмечено, новые сообщения требуют вашего внимания."
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__message_has_error
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__message_has_error
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr "Если отмечено, некоторые сообщения имеют ошибку доставки."
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_is_follower
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_is_follower
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_is_follower
msgid "Is Follower"
msgstr "Является подписчиком"
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_context__context
msgid "JSON с информацией о документе для AI"
msgstr "JSON с информацией о документе для AI"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__write_uid
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__write_uid
msgid "Last Updated by"
msgstr "Последнее обновление пользователем"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__write_date
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__write_date
msgid "Last Updated on"
msgstr "Дата последнего обновления"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_dsrpt_contact
msgid "Manage your contacts and their communication methods in one place."
msgstr "Управляйте контактами и способами связи с ними в одном месте."
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_has_error
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_has_error
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_has_error
msgid "Message Delivery error"
msgstr "Ошибка доставки сообщения"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_ids
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_ids
msgid "Messages"
msgstr "Сообщения"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
msgid "Model"
msgstr "Модель"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__model_name
msgid "Model Name"
msgstr "Имя модели"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__my_activity_date_deadline
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__my_activity_date_deadline
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__my_activity_date_deadline
msgid "My Activity Deadline"
msgstr "Срок моего действия"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__name
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__name
msgid "Name"
msgstr "Название"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_change_employee_wizard__user_id
msgid "New Employee"
msgstr "Новый сотрудник"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_calendar_event_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_calendar_event_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_calendar_event_id
msgid "Next Activity Calendar Event"
msgstr "Следующее событие календаря"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_date_deadline
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_date_deadline
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_date_deadline
msgid "Next Activity Deadline"
msgstr "Срок следующего действия"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_summary
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_summary
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_summary
msgid "Next Activity Summary"
msgstr "Сводка следующего действия"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_type_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_type_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_type_id
msgid "Next Activity Type"
msgstr "Тип следующего действия"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__next_contact
msgid "Next Contact"
msgstr "Следующий контакт"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__not_customer
msgid "Not Customer"
msgstr "Не клиент"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__note
msgid "Note"
msgstr "Заметка"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__notes
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_form
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_form
msgid "Notes"
msgstr "Заметки"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_needaction_counter
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_needaction_counter
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_needaction_counter
msgid "Number of Actions"
msgstr "Количество действий"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__message_has_error_counter
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__message_has_error_counter
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__message_has_error_counter
msgid "Number of errors"
msgstr "Количество ошибок"
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__message_needaction_counter
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__message_needaction_counter
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__message_needaction_counter
msgid "Number of messages requiring action"
msgstr "Количество сообщений, требующих действий"
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__message_has_error_counter
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__message_has_error_counter
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr "Количество сообщений с ошибкой доставки"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_form
msgid "Open Document"
msgstr "Открыть документ"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__parent_path
msgid "Parent Path"
msgstr "Родительский путь"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__parent_id
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
msgid "Parent Source"
msgstr "Родительский источник"
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_phone
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_contact_search
msgid "Phone"
msgstr "Телефон"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__phone_numbers
msgid "Phone Numbers"
msgstr "Номера телефонов"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__contact_event__state__planned
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Planned"
msgstr "Запланировано"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__is_preferred
msgid "Preferred"
msgstr "Предпочтительный"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_form
msgid "Reset to Draft"
msgstr "Вернуть в черновик"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__user_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__user_id
msgid "Responsible"
msgstr "Ответственный"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__activity_user_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__activity_user_id
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__activity_user_id
msgid "Responsible User"
msgstr "Ответственный пользователь"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Search Contact Events"
msgstr "Поиск событий контакта"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
msgid "Search Contexts"
msgstr "Поиск контекстов"
#. module: dsrpt_address_book
#: model:ir.actions.server,name:dsrpt_address_book.action_server_send_transcription_added
msgid "Send Need Qualification Event"
msgstr "Отправить событие требуется квалификация"
#. module: dsrpt_address_book
#: model:ir.actions.server,name:dsrpt_address_book.action_server_send_context_update
msgid "Send Need Summary/Calendar Events"
msgstr "Отправить события сводки/календаря"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_dsrpt_communication_type_form
msgid "Set to Draft"
msgstr "Установить как черновик"
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_skype
msgid "Skype"
msgstr "Skype"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__source_id
msgid "Source"
msgstr "Источник"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_source__state
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_communication_type__state
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "State"
msgstr "Состояние"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_event__state
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact__status
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_source_search
msgid "Status"
msgstr "Статус"
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__activity_state
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__activity_state
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__activity_state
msgid ""
"Status based on activities\n"
"Overdue: Due date is already passed\n"
"Today: Activity date is today\n"
"Planned: Future activities."
msgstr "Статус на основе действий\n"
"Просрочено: Срок уже прошел\n"
"Сегодня: Действие запланировано на сегодня\n"
"Запланировано: Будущие действия."
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_telegram
msgid "Telegram"
msgstr "Telegram"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "This Week"
msgstr "Эта неделя"
#. module: dsrpt_address_book
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_context_search
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "Today"
msgstr "Сегодня"
#. module: dsrpt_address_book
#: model_terms:ir.actions.act_window,help:dsrpt_address_book.action_contact_event
msgid "Track meetings, calls and other events with your contacts."
msgstr "Отслеживайте встречи, звонки и другие события с вашими контактами."
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__communication_type_id
msgid "Type"
msgstr "Тип"
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_event__activity_exception_decoration
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_source__activity_exception_decoration
#: model:ir.model.fields,help:dsrpt_address_book.field_dsrpt_contact__activity_exception_decoration
msgid "Type of the exception activity on record."
msgstr "Тип исключительного действия в записи."
#. module: dsrpt_address_book
#: model:res.groups,name:dsrpt_address_book.group_dsrpt_address_book_user
#: model_terms:ir.ui.view,arch_db:dsrpt_address_book.view_contact_event_search
msgid "User"
msgstr "Пользователь"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_dsrpt_contact_communication__value
msgid "Value"
msgstr "Значение"
#. module: dsrpt_address_book
#: model:dsrpt.communication.type,name:dsrpt_address_book.communication_type_whatsapp
msgid "WhatsApp"
msgstr "WhatsApp"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__document_name
msgid "Документ"
msgstr "Документ"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__contact_id
msgid "Контакт"
msgstr "Контакт"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__context
msgid "Контекст"
msgstr "Контекст"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__res_model
msgid "Модель"
msgstr "Модель"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__display_name
msgid "Название"
msgstr "Название"
#. module: dsrpt_address_book
#: model:ir.model.fields,field_description:dsrpt_address_book.field_contact_context__document_url
msgid "Ссылка"
msgstr "Ссылка"
#. module: dsrpt_address_book
#: model:ir.model.fields,help:dsrpt_address_book.field_contact_context__res_model
msgid "Техническое название модели документа"
msgstr "Техническое название модели документа"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__has_contract
msgid "Has Contract"
msgstr "Есть договор"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__supplier
msgid "Supplier"
msgstr "Поставщик"
#. module: dsrpt_address_book
#: model:ir.model.fields.selection,name:dsrpt_address_book.selection__dsrpt_contact__status__potential_investor
msgid "Potential Investor"
msgstr "Потенциальный инвестор"

View File

@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from . import dsrpt_communication_type
from . import dsrpt_contact
from . import dsrpt_contact_communication
from . import contact_event
from . import contact_source

View File

@@ -0,0 +1,125 @@
# -*- coding: utf-8 -*-
from datetime import timedelta
from odoo import models, fields, api
class ContactEvent(models.Model):
_name = 'contact.event'
_description = 'Contact Event'
_order = 'date_start desc'
_inherit = ['mail.thread', 'mail.activity.mixin']
contact_id = fields.Many2one(
'dsrpt.contact',
string='Contact',
required=True,
ondelete='cascade',
tracking=True
)
date_start = fields.Datetime(
string='Date & Time',
required=True,
default=fields.Datetime.now,
tracking=True
)
duration = fields.Float(
string='Duration (hours)',
default=1.0,
tracking=True
)
user_id = fields.Many2one(
'res.users',
string='Responsible',
default=lambda self: self.env.user,
tracking=True
)
calendar_event_id = fields.Many2one(
'calendar.event',
string='Calendar Event',
readonly=True
)
notes = fields.Text(string='Notes', required=True, tracking=True)
@api.model_create_multi
def create(self, vals_list):
records = super().create(vals_list)
for record in records:
# Get base URL for creating contact link
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url', 'http://localhost:8069')
contact_url = f"{base_url}/web#id={record.contact_id.id}&model=dsrpt.contact&view_type=form"
# Prepare description with contact link
description = f"📱 Contact in Odoo: {contact_url}\n\n"
if record.notes:
description += record.notes
calendar_event = self.env['calendar.event'].create({
'name': f"[{record.contact_id.name}] {record.notes[:50] if record.notes else 'Event'}",
'start': record.date_start,
'stop': record.date_start + timedelta(hours=record.duration),
'user_id': record.user_id.id,
'partner_ids': [(6, 0, [record.user_id.partner_id.id])] if record.user_id and record.user_id.partner_id else [],
'description': description,
})
record.calendar_event_id = calendar_event.id
# Update next_contact for affected contacts with the event date
for record in records:
record.contact_id._update_next_contact(record.date_start)
return records
def write(self, vals):
result = super().write(vals)
# Update calendar event if needed
for record in self:
if record.calendar_event_id:
update_vals = {}
if 'notes' in vals or 'contact_id' in vals:
update_vals['name'] = f"[{record.contact_id.name}] {record.notes[:50] if record.notes else 'Event'}"
if 'date_start' in vals:
update_vals['start'] = record.date_start
update_vals['stop'] = record.date_start + timedelta(hours=record.duration)
if 'duration' in vals:
update_vals['stop'] = record.date_start + timedelta(hours=record.duration)
if 'user_id' in vals:
update_vals['user_id'] = record.user_id.id
update_vals['partner_ids'] = [(6, 0, [record.user_id.partner_id.id])] if record.user_id and record.user_id.partner_id else []
if 'notes' in vals or 'contact_id' in vals:
# Get base URL for creating contact link
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url', 'http://localhost:8069')
contact_url = f"{base_url}/web#id={record.contact_id.id}&model=dsrpt.contact&view_type=form"
# Prepare description with contact link
description = f"📱 Contact in Odoo: {contact_url}\n\n"
if record.notes:
description += record.notes
update_vals['description'] = description
if update_vals:
record.calendar_event_id.write(update_vals)
# Update next_contact for affected contacts if relevant fields changed
if any(field in vals for field in ['date_start', 'contact_id']):
for record in self:
record.contact_id._update_next_contact(record.date_start)
return result
@api.ondelete(at_uninstall=False)
def _unlink_calendar_events(self):
for record in self:
if record.calendar_event_id:
record.calendar_event_id.unlink()
def unlink(self):
# Store contacts before deletion for clearing next_contact
contacts = self.mapped('contact_id')
result = super().unlink()
# Clear next_contact for affected contacts after deletion
for contact in contacts:
contact._update_next_contact(None)
return result

View File

@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class ContactSource(models.Model):
_name = 'contact.source'
_description = 'Contact Source'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'name'
_parent_store = True
name = fields.Char(string='Name', required=True, translate=True, tracking=True)
description = fields.Text(string='Description', tracking=True)
active = fields.Boolean(string='Active', default=True, tracking=True)
parent_id = fields.Many2one('contact.source', string='Parent Source', ondelete='cascade', index=True, tracking=True)
parent_path = fields.Char(index=True, unaccent=False)
# Стандартные статусы согласно требованиям
state = fields.Selection([
('draft', 'Draft'),
('active', 'Active')
], string='State', default='draft', required=True, tracking=True)
color = fields.Integer(string='Color', default=0)
def action_activate(self):
"""Активировать источник"""
self.write({'state': 'active'})
def action_draft(self):
"""Вернуть в черновик"""
self.write({'state': 'draft'})

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
from odoo import models, fields
class CommunicationType(models.Model):
_name = 'dsrpt.communication.type'
_description = 'Communication Type'
_order = 'name'
name = fields.Char(string='Name', required=True, translate=True)
code = fields.Char(string='Code', required=True)
active = fields.Boolean(string='Active', default=True)
# Стандартные статусы согласно требованиям
state = fields.Selection([
('draft', 'Draft'),
('active', 'Active')
], string='State', default='draft', required=True)
def action_activate(self):
"""Активировать тип коммуникации"""
self.write({'state': 'active'})
def action_draft(self):
"""Вернуть в черновик"""
self.write({'state': 'draft'})

View File

@@ -0,0 +1,332 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class Contact(models.Model):
_name = 'dsrpt.contact'
_description = 'Contact'
_inherit = ['mail.thread', 'mail.activity.mixin']
_rec_name = 'name'
_order = 'create_date desc, name'
name = fields.Char(string='Name', required=True, tracking=True)
display_name = fields.Char(string='Display Name') # Will be computed in realty_sales module
active = fields.Boolean(string='Active', default=True, tracking=True)
status = fields.Selection([
('awaiting_qualification', 'Awaiting Qualification'),
('not_customer', 'Not a Customer'),
('supplier', 'Supplier'),
('has_request', 'Has Request'),
('has_contract', 'Has Contract'),
('potential_investor', 'Potential Investor'),
('cancelled', 'Cancelled')
], string='Status', default='awaiting_qualification', tracking=True, help='Contact processing status for AI analysis')
user_id = fields.Many2one('res.users', string='Responsible', tracking=True)
source_id = fields.Many2one('contact.source', string='Source', tracking=True)
qualification_date = fields.Datetime(string='Qualification Date', tracking=True, help='When contact was qualified')
communication_ids = fields.One2many(
'dsrpt.contact.communication',
'contact_id',
string='Communications'
)
note = fields.Text(string='Note')
# Relations
event_ids = fields.One2many(
'contact.event',
'contact_id',
string='Events'
)
# call_ids moved to dsrpt_calls module to avoid circular dependencies
# Computed fields
event_count = fields.Integer(
string='Events',
compute='_compute_event_count'
)
phone_numbers = fields.Char(
string='Phone Numbers',
compute='_compute_phone_numbers',
store=True
)
next_contact = fields.Datetime(
string='Next Contact',
tracking=True,
help='Date of the nearest planned event'
)
# call_count moved to dsrpt_calls module
@api.depends('event_ids')
def _compute_event_count(self):
"""Counts the number of events"""
for record in self:
record.event_count = len(record.event_ids)
@api.depends('communication_ids.value', 'communication_ids.communication_type_id')
def _compute_phone_numbers(self):
"""Extracts all phone numbers for search functionality"""
for record in self:
phones = record.communication_ids.filtered(
lambda c: c.communication_type_id.code == 'phone'
).mapped('value')
record.phone_numbers = ', '.join(phones) if phones else ''
def _update_next_contact(self, date_value=None):
"""Update next_contact field with provided date"""
for record in self:
if date_value is not None:
record.next_contact = date_value
# _compute_call_count moved to dsrpt_calls module
def action_view_events(self):
"""Opens contact events"""
self.ensure_one()
return {
'name': 'Events',
'type': 'ir.actions.act_window',
'res_model': 'contact.event',
'view_mode': 'list,form',
'domain': [('contact_id', '=', self.id)],
'context': {'default_contact_id': self.id}
}
def action_qualify(self):
"""Action to trigger qualification for selected contacts"""
qualified_count = 0
no_calls_count = 0
already_qualified_count = 0
for contact in self:
# Skip if already qualified (status not 'awaiting_qualification')
if contact.status != 'awaiting_qualification':
already_qualified_count += 1
continue
# Find last call with transcription for this contact
last_call = self.env['dsrpt_calls.call'].search([
('contact_id', '=', contact.id),
('transcription', '!=', False)
], order='date_start desc', limit=1)
if last_call:
# Send on_need_qualification event directly to contact
contact._event('on_need_qualification').notify(contact)
qualified_count += 1
else:
no_calls_count += 1
# Build notification message
message_parts = []
if qualified_count:
message_parts.append(f"{qualified_count} contacts queued for qualification")
if no_calls_count:
message_parts.append(f"{no_calls_count} contacts have no calls with transcription")
if already_qualified_count:
message_parts.append(f"{already_qualified_count} contacts already qualified")
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Qualification Process',
'message': '. '.join(message_parts) if message_parts else 'No contacts to qualify',
'type': 'success' if qualified_count else 'info',
'sticky': False,
}
}
def action_view_calls(self):
"""Opens contact calls"""
self.ensure_one()
return {
'name': 'Calls',
'type': 'ir.actions.act_window',
'res_model': 'dsrpt_calls.call',
'view_mode': 'list,form',
'domain': [('contact_id', '=', self.id)],
'context': {'default_contact_id': self.id}
}
def name_get(self):
result = []
for record in self:
# Найти предпочитаемый способ связи
preferred = record.communication_ids.filtered('is_preferred')
if preferred:
name = f"{record.name} ({preferred[0].value})"
else:
name = record.name
result.append((record.id, name))
return result
def action_view_telegram_card(self):
"""Open telegram card editing form"""
self.ensure_one()
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url', 'http://localhost:8069')
card_url = f"{base_url}/telegram/contact-card/{self.id}"
return {
'type': 'ir.actions.act_url',
'url': card_url,
'target': 'new',
}
def _process_name_suggestion_from_call(self, call_record):
"""Queue job method to process name suggestion from call transcription"""
import logging
_logger = logging.getLogger(__name__)
if not call_record.transcription:
_logger.warning(f"No transcription available for call {call_record.id}")
return
# Get AI collection and component
collection = self.env['dsrpt.ai.collection'].search([], limit=1)
if not collection:
_logger.error("No AI collection found")
return
work = collection.work_on(model_name='field.change.suggestion')
ai_component = work.component(usage='field.change.suggestion')
# Get suggested name from AI
suggested_name = ai_component.suggest_name_from_transcription(call_record.transcription)
# Only create suggestion if AI returned a valid name
if suggested_name and suggested_name not in ['Не определено', 'Undefined', '', False, 'Unknown']:
# Find telegram user for notification
telegram_user = self._find_telegram_user_for_suggestions()
# Create field suggestion with AI result
suggestion_vals = {
'res_model': 'dsrpt.contact',
'res_id': self.id,
'field_name': 'name',
'current_value': self.name,
'suggested_value': suggested_name,
'telegram_user_id': telegram_user.id if telegram_user else None
}
suggestion = self.env['field.change.suggestion'].create(suggestion_vals)
_logger.info(f"Created name suggestion {suggestion.id} with value '{suggested_name}' for contact {self.id}")
else:
_logger.info(f"AI did not return valid name suggestion for contact {self.id}, skipping")
def _find_telegram_user_for_suggestions(self):
"""Find telegram user for notifications"""
telegram_user = None
# Priority: contact owner > first admin user
if hasattr(self, 'user_id') and self.user_id:
telegram_user = self.env['telegram.user'].search([
('odoo_user_id', '=', self.user_id.id),
('active', '=', True)
], limit=1)
if not telegram_user:
# Find first active telegram admin user
telegram_user = self.env['telegram.user'].search([
('active', '=', True)
], limit=1)
return telegram_user
def _process_note_suggestion_from_context(self, context_record):
"""Queue job method to process note suggestion from contact history"""
import logging
_logger = logging.getLogger(__name__)
# Get AI collection and component
collection = self.env['dsrpt.ai.collection'].search([], limit=1)
if not collection:
_logger.error("No AI collection found")
return
work = collection.work_on(model_name='field.change.suggestion')
ai_component = work.component(usage='field.change.suggestion')
# Gather contact history for AI
history = self._gather_contact_history_for_ai()
# Get suggested summary from AI
suggested_summary = ai_component.suggest_summary_from_history(history)
# Only create suggestion if AI returned a valid summary
if suggested_summary and suggested_summary not in ['Не определено', 'Undefined', '', False]:
# Find telegram user for notification
telegram_user = self._find_telegram_user_for_suggestions()
# Create field suggestion with AI result
suggestion_vals = {
'res_model': 'dsrpt.contact',
'res_id': self.id,
'field_name': 'note',
'current_value': self.note or '',
'suggested_value': suggested_summary,
'telegram_user_id': telegram_user.id if telegram_user else None
}
suggestion = self.env['field.change.suggestion'].create(suggestion_vals)
_logger.info(f"Created note suggestion {suggestion.id} with summary for contact {self.id}")
else:
_logger.info(f"AI did not return valid note suggestion for contact {self.id}, skipping")
def _gather_contact_history_for_ai(self):
"""Gather contact history for summary generation"""
history_parts = []
# Add contact basic info
history_parts.append(f"Contact: {self.name}")
# Add communications
for comm in self.communication_ids:
history_parts.append(f"{comm.communication_type_id.name}: {comm.value}")
# Add recent calls if module is installed
if 'dsrpt_calls.call' in self.env:
calls = self.env['dsrpt_calls.call'].search([
('contact_id', '=', self.id)
], limit=5, order='date_start desc')
for call in calls:
history_parts.append(f"Call {call.date_start}: {call.duration} sec")
if call.transcription:
history_parts.append(f"Summary: {call.transcription[:200]}...")
return "\n".join(history_parts)
def recompute_next_contact_all(self):
"""Clear next_contact for all contacts (simplified logic)"""
all_contacts = self.env['dsrpt.contact'].search([])
all_contacts._update_next_contact(None)
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Reset Completed',
'message': f'"Next Contact" cleared for {len(all_contacts)} contacts',
'type': 'success',
'sticky': False,
}
}
def write(self, vals):
"""Override write to automatically set qualification_date when status changes"""
# Check if status is being changed
if 'status' in vals:
for record in self:
old_status = record.status
new_status = vals['status']
# If changing FROM awaiting_qualification TO any other status
if (old_status == 'awaiting_qualification' and
new_status != 'awaiting_qualification' and
not record.qualification_date):
# Set qualification date automatically
vals['qualification_date'] = fields.Datetime.now()
return super().write(vals)

View File

@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
from odoo.exceptions import ValidationError
class ContactCommunication(models.Model):
_name = 'dsrpt.contact.communication'
_description = 'Contact Communication'
_order = 'is_preferred desc, id'
contact_id = fields.Many2one(
'dsrpt.contact',
string='Contact',
required=True,
ondelete='cascade'
)
communication_type_id = fields.Many2one(
'dsrpt.communication.type',
string='Type',
required=True
)
value = fields.Char(string='Value', required=True)
is_preferred = fields.Boolean(string='Preferred', default=False)
@api.constrains('is_preferred')
def _check_single_preferred(self):
"""Ensure only one preferred communication per contact"""
for record in self:
if record.is_preferred:
# Проверяем есть ли другие preferred для этого контакта
domain = [
('contact_id', '=', record.contact_id.id),
('is_preferred', '=', True),
('id', '!=', record.id)
]
if self.search_count(domain) > 0:
raise ValidationError(
'Only one communication method can be marked as preferred per contact.'
)
@api.model
def create(self, vals):
# Если это первый способ связи для контакта, делаем его preferred
if 'contact_id' in vals and not vals.get('is_preferred'):
existing = self.search_count([('contact_id', '=', vals['contact_id'])])
if existing == 0:
vals['is_preferred'] = True
return super().create(vals)
def name_get(self):
result = []
for record in self:
name = f"{record.communication_type_id.name}: {record.value}"
if record.is_preferred:
name = f"{name}"
result.append((record.id, name))
return result

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- User Group -->
<record id="group_dsrpt_address_book_user" model="res.groups">
<field name="name">DSRPT Address Book / User</field>
<field name="comment">Can view and manage contacts</field>
</record>
<!-- Admin Group -->
<record id="group_dsrpt_address_book_admin" model="res.groups">
<field name="name">DSRPT Address Book / Administrator</field>
<field name="implied_ids" eval="[(4, ref('group_dsrpt_address_book_user'))]"/>
<field name="comment">Can configure communication types and delete contacts</field>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,12 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_dsrpt_contact_user,dsrpt.contact.user,model_dsrpt_contact,group_dsrpt_address_book_user,1,1,1,0
access_dsrpt_contact_admin,dsrpt.contact.admin,model_dsrpt_contact,group_dsrpt_address_book_admin,1,1,1,1
access_dsrpt_communication_type_user,dsrpt.communication.type.user,model_dsrpt_communication_type,group_dsrpt_address_book_user,1,0,0,0
access_dsrpt_communication_type_admin,dsrpt.communication.type.admin,model_dsrpt_communication_type,group_dsrpt_address_book_admin,1,1,1,1
access_dsrpt_contact_communication_user,dsrpt.contact.communication.user,model_dsrpt_contact_communication,group_dsrpt_address_book_user,1,1,1,1
access_dsrpt_contact_communication_admin,dsrpt.contact.communication.admin,model_dsrpt_contact_communication,group_dsrpt_address_book_admin,1,1,1,1
access_contact_event_user,contact.event.user,model_contact_event,group_dsrpt_address_book_user,1,1,1,0
access_contact_event_admin,contact.event.admin,model_contact_event,group_dsrpt_address_book_admin,1,1,1,1
access_contact_source_user,contact.source.user,model_contact_source,group_dsrpt_address_book_user,1,1,1,0
access_contact_source_admin,contact.source.admin,model_contact_source,group_dsrpt_address_book_admin,1,1,1,1
access_change_employee_wizard,change.employee.wizard,model_change_employee_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_dsrpt_contact_user dsrpt.contact.user model_dsrpt_contact group_dsrpt_address_book_user 1 1 1 0
3 access_dsrpt_contact_admin dsrpt.contact.admin model_dsrpt_contact group_dsrpt_address_book_admin 1 1 1 1
4 access_dsrpt_communication_type_user dsrpt.communication.type.user model_dsrpt_communication_type group_dsrpt_address_book_user 1 0 0 0
5 access_dsrpt_communication_type_admin dsrpt.communication.type.admin model_dsrpt_communication_type group_dsrpt_address_book_admin 1 1 1 1
6 access_dsrpt_contact_communication_user dsrpt.contact.communication.user model_dsrpt_contact_communication group_dsrpt_address_book_user 1 1 1 1
7 access_dsrpt_contact_communication_admin dsrpt.contact.communication.admin model_dsrpt_contact_communication group_dsrpt_address_book_admin 1 1 1 1
8 access_contact_event_user contact.event.user model_contact_event group_dsrpt_address_book_user 1 1 1 0
9 access_contact_event_admin contact.event.admin model_contact_event group_dsrpt_address_book_admin 1 1 1 1
10 access_contact_source_user contact.source.user model_contact_source group_dsrpt_address_book_user 1 1 1 0
11 access_contact_source_admin contact.source.admin model_contact_source group_dsrpt_address_book_admin 1 1 1 1
12 access_change_employee_wizard change.employee.wizard model_change_employee_wizard base.group_user 1 1 1 1

View File

@@ -0,0 +1,5 @@
<svg width="70" height="70" viewBox="0 0 70 70" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="70" height="70" rx="10" fill="#4B5563"/>
<path d="M35 20C30.0294 20 26 24.0294 26 29C26 33.9706 30.0294 38 35 38C39.9706 38 44 33.9706 44 29C44 24.0294 39.9706 20 35 20ZM35 34C32.2386 34 30 31.7614 30 29C30 26.2386 32.2386 24 35 24C37.7614 24 40 26.2386 40 29C40 31.7614 37.7614 34 35 34Z" fill="white"/>
<path d="M35 40C27.268 40 21 43.5817 21 48V50H49V48C49 43.5817 42.732 40 35 40ZM25 46C25.442 44.617 29.485 44 35 44C40.515 44 44.558 44.617 45 46H25Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 598 B

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_change_employee_wizard_form" model="ir.ui.view">
<field name="name">change.employee.wizard.form</field>
<field name="model">change.employee.wizard</field>
<field name="arch" type="xml">
<form string="Change Employee">
<group>
<field name="model_name" invisible="1"/>
<field name="field_name" invisible="1"/>
<field name="user_id" options="{'no_create': True, 'no_create_edit': True}"/>
</group>
<footer>
<button string="Apply" name="action_change_employee" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<delete id="view_contact_context_tree" model="ir.ui.view"/>
<delete id="view_contact_context_form" model="ir.ui.view"/>
<delete id="view_contact_context_search" model="ir.ui.view"/>
<delete id="action_contact_context" model="ir.actions.act_window"/>
<delete id="menu_contact_context" model="ir.ui.menu"/>
<delete id="access_contact_context_user" model="ir.model.access"/>
<delete id="access_contact_context_admin" model="ir.model.access"/>
</odoo>

View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Form View -->
<record id="view_contact_event_form" model="ir.ui.view">
<field name="name">contact.event.form</field>
<field name="model">contact.event</field>
<field name="arch" type="xml">
<form string="Contact Event">
<sheet>
<group>
<group>
<field name="contact_id"/>
<field name="date_start"/>
</group>
<group>
<field name="duration" widget="float_time"/>
<field name="user_id"/>
<field name="calendar_event_id" readonly="1"/>
</group>
</group>
<group string="Notes">
<field name="notes" nolabel="1" colspan="2"/>
</group>
</sheet>
<chatter/>
</form>
</field>
</record>
<!-- Tree View -->
<record id="view_contact_event_tree" model="ir.ui.view">
<field name="name">contact.event.tree</field>
<field name="model">contact.event</field>
<field name="arch" type="xml">
<list string="Contact Events">
<field name="contact_id"/>
<field name="notes"/>
<field name="date_start"/>
<field name="duration" widget="float_time"/>
<field name="user_id" optional="show"/>
</list>
</field>
</record>
<!-- Calendar View -->
<record id="view_contact_event_calendar" model="ir.ui.view">
<field name="name">contact.event.calendar</field>
<field name="model">contact.event</field>
<field name="arch" type="xml">
<calendar string="Contact Events" date_start="date_start"
color="user_id" mode="month">
<field name="notes"/>
<field name="contact_id"/>
<field name="user_id"/>
</calendar>
</field>
</record>
<!-- Search View -->
<record id="view_contact_event_search" model="ir.ui.view">
<field name="name">contact.event.search</field>
<field name="model">contact.event</field>
<field name="arch" type="xml">
<search string="Search Contact Events">
<field name="notes"/>
<field name="contact_id"/>
<field name="user_id"/>
<separator/>
<filter string="Today" name="today"
domain="[('date_start', '&gt;=', datetime.datetime.now().replace(hour=0, minute=0, second=0)),
('date_start', '&lt;', datetime.datetime.now().replace(hour=23, minute=59, second=59))]"/>
<filter string="This Week" name="this_week"
domain="[('date_start', '&gt;=', (datetime.datetime.now() - datetime.timedelta(days=datetime.datetime.now().weekday())).replace(hour=0, minute=0, second=0)),
('date_start', '&lt;', (datetime.datetime.now() + datetime.timedelta(days=6-datetime.datetime.now().weekday())).replace(hour=23, minute=59, second=59))]"/>
<separator/>
<filter string="Contact" name="group_contact" domain="[]" context="{'group_by': 'contact_id'}"/>
<filter string="User" name="group_user" domain="[]" context="{'group_by': 'user_id'}"/>
<filter string="Date" name="group_date" domain="[]" context="{'group_by': 'date_start:day'}"/>
</search>
</field>
</record>
<!-- Action -->
<record id="action_contact_event" model="ir.actions.act_window">
<field name="name">Contact Events</field>
<field name="res_model">contact.event</field>
<field name="view_mode">calendar,list,form</field>
<field name="search_view_id" ref="view_contact_event_search"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first contact event
</p>
<p>
Track meetings, calls and other events with your contacts.
</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Contact Source Form View -->
<record id="view_contact_source_form" model="ir.ui.view">
<field name="name">Contact Source Form</field>
<field name="model">contact.source</field>
<field name="arch" type="xml">
<form>
<header>
<button name="action_activate" type="object" string="Activate"
class="btn-primary" invisible="state == 'active'"/>
<button name="action_draft" type="object" string="Reset to Draft"
invisible="state == 'draft'"/>
<field name="state" widget="statusbar" statusbar_visible="draft,active"/>
</header>
<sheet>
<group>
<group>
<field name="name"/>
<field name="parent_id"/>
</group>
<group>
<field name="color" widget="color"/>
</group>
</group>
<group>
<field name="description"/>
</group>
</sheet>
<chatter/>
</form>
</field>
</record>
<!-- Contact Source List View -->
<record id="view_contact_source_list" model="ir.ui.view">
<field name="name">Contact Source List</field>
<field name="model">contact.source</field>
<field name="arch" type="xml">
<list>
<field name="name"/>
<field name="parent_id" optional="show"/>
<field name="state" widget="badge" optional="show"/>
<field name="color" widget="color" optional="hide"/>
<field name="create_date" optional="hide"/>
<field name="write_uid" optional="hide"/>
</list>
</field>
</record>
<!-- Contact Source Search View -->
<record id="view_contact_source_search" model="ir.ui.view">
<field name="name">Contact Source Search</field>
<field name="model">contact.source</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="parent_id"/>
<field name="description"/>
<!-- Filters -->
<filter string="Draft" name="draft" domain="[('state', '=', 'draft')]"/>
<filter string="Active" name="active_state" domain="[('state', '=', 'active')]"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<!-- Group By -->
<separator/>
<filter string="Status" name="group_by_state" context="{'group_by': 'state'}"/>
<filter string="Parent Source" name="group_by_parent" context="{'group_by': 'parent_id'}"/>
</search>
</field>
</record>
<!-- Contact Source Action -->
<record id="action_contact_source" model="ir.actions.act_window">
<field name="name">Contact Sources</field>
<field name="res_model">contact.source</field>
<field name="view_mode">list,form</field>
<field name="search_view_id" ref="view_contact_source_search"/>
<field name="context">{'search_default_active_state': 1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first contact source!
</p>
<p>
Contact sources help you track where your contacts come from.
</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- List View -->
<record id="view_dsrpt_communication_type_list" model="ir.ui.view">
<field name="name">dsrpt.communication.type.list</field>
<field name="model">dsrpt.communication.type</field>
<field name="arch" type="xml">
<list string="Communication Types">
<field name="name"/>
<field name="code"/>
<field name="state" widget="badge" decoration-success="state == 'active'" decoration-info="state == 'draft'"/>
</list>
</field>
</record>
<!-- Form View -->
<record id="view_dsrpt_communication_type_form" model="ir.ui.view">
<field name="name">dsrpt.communication.type.form</field>
<field name="model">dsrpt.communication.type</field>
<field name="arch" type="xml">
<form string="Communication Type">
<header>
<button name="action_activate" type="object" string="Activate" class="oe_highlight" invisible="state == 'active'"/>
<button name="action_draft" type="object" string="Set to Draft" invisible="state == 'draft'"/>
<field name="state" widget="statusbar" statusbar_visible="draft,active"/>
</header>
<sheet>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" invisible="active"/>
<group>
<field name="name"/>
<field name="code"/>
<field name="active" invisible="1"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- Search View -->
<record id="view_dsrpt_communication_type_search" model="ir.ui.view">
<field name="name">dsrpt.communication.type.search</field>
<field name="model">dsrpt.communication.type</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="code"/>
<separator/>
<filter string="Draft" name="draft" domain="[('state', '=', 'draft')]"/>
<filter string="Active" name="active_state" domain="[('state', '=', 'active')]"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
</search>
</field>
</record>
<!-- Action -->
<record id="action_dsrpt_communication_type" model="ir.actions.act_window">
<field name="name">Communication Types</field>
<field name="res_model">dsrpt.communication.type</field>
<field name="view_mode">list,form</field>
<field name="search_view_id" ref="view_dsrpt_communication_type_search"/>
<field name="context">{'search_default_active_state': 1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first communication type!
</p>
<p>
Communication types define the ways to contact people (Phone, Email, Telegram, etc.)
</p>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,287 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- List View -->
<record id="view_dsrpt_contact_list" model="ir.ui.view">
<field name="name">dsrpt.contact.list</field>
<field name="model">dsrpt.contact</field>
<field name="arch" type="xml">
<list string="Contacts">
<field name="name"/>
<field name="user_id" optional="show"/>
<field name="next_contact" widget="date" optional="show"/>
<field name="communication_ids" widget="many2many_tags" optional="show"
context="{'tree_view_ref': 'dsrpt_address_book.view_dsrpt_contact_communication_tree_simple'}"/>
<field name="create_date" optional="hide"/>
<field name="write_date" optional="hide"/>
</list>
</field>
</record>
<!-- Form View -->
<record id="view_dsrpt_contact_form" model="ir.ui.view">
<field name="name">dsrpt.contact.form</field>
<field name="model">dsrpt.contact</field>
<field name="arch" type="xml">
<form string="Contact">
<sheet>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" invisible="active"/>
<div class="oe_button_box" name="button_box">
<button name="action_view_events" type="object" class="oe_stat_button" icon="fa-calendar">
<field name="event_count" widget="statinfo" string="Events"/>
</button>
<!-- Calls button moved to dsrpt_calls module -->
</div>
<div class="oe_title">
<h1>
<field name="name" placeholder="Contact Name..."/>
</h1>
</div>
<!-- Top row: Basic info (left) and Notes (right) -->
<group col="2">
<group>
<field name="user_id"/>
<field name="source_id"/>
<field name="next_contact" readonly="1"/>
</group>
<group string="Notes">
<field name="note" nolabel="1" placeholder="Add notes about this contact..."/>
</group>
</group>
<field name="active" invisible="1"/>
<!-- Second row: Events (left) and Requests (right) -->
<group col="2" name="middle_section">
<group string="Events">
<field name="event_ids" nolabel="1" context="{'default_contact_id': id}">
<kanban>
<field name="date_start"/>
<field name="notes"/>
<field name="duration"/>
<field name="user_id"/>
<templates>
<t t-name="card">
<div class="oe_kanban_card oe_kanban_global_click" style="margin-bottom: 8px;">
<div class="o_kanban_record_body">
<!-- Date and time in bold -->
<div class="o_kanban_record_title mb-2">
<strong>
<t t-esc="luxon.DateTime.fromISO(record.date_start.raw_value).setLocale('en').toFormat('d MMMM yyyy')"/>
<t t-esc="luxon.DateTime.fromISO(record.date_start.raw_value).toFormat('HH:mm')"/>
</strong>
</div>
<!-- Description full width -->
<div class="mb-2">
<field name="notes"/>
</div>
<!-- User avatar -->
<div t-if="record.user_id.raw_value" class="d-flex align-items-center">
<img t-attf-src="/web/image/res.users/{{record.user_id.raw_value}}/avatar_128"
class="o_kanban_image_fill_left"
width="24" height="24"
style="border-radius: 50%;"/>
<span class="ml-1 text-muted">
<field name="user_id"/>
</span>
</div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</group>
<!-- Requests group will be added by realty_sales module -->
<group name="requests_placeholder"/>
</group>
<!-- Third row: Communications (full width) -->
<group col="1" string="Communications">
<field name="communication_ids" nolabel="1" context="{'default_contact_id': id}">
<list editable="bottom">
<field name="communication_type_id" options="{'no_create': True}"/>
<field name="value"/>
<field name="is_preferred" widget="boolean_toggle"/>
</list>
</field>
</group>
<!-- Fourth row: Calls (full width) - will be added by dsrpt_calls module -->
<group col="1" name="calls_section"/>
</sheet>
<chatter/>
</form>
</field>
</record>
<!-- Search View -->
<record id="view_dsrpt_contact_search" model="ir.ui.view">
<field name="name">dsrpt.contact.search</field>
<field name="model">dsrpt.contact</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="phone_numbers" string="Phone"
filter_domain="[('phone_numbers', 'ilike', self)]"/>
<field name="communication_ids" string="Communication"
filter_domain="[('communication_ids.value', 'ilike', self)]"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<separator/>
<filter string="Create Date" name="group_create_date" context="{'group_by': 'create_date'}"/>
</search>
</field>
</record>
<!-- Simple tree for Many2many tags widget -->
<record id="view_dsrpt_contact_communication_tree_simple" model="ir.ui.view">
<field name="name">dsrpt.contact.communication.tree.simple</field>
<field name="model">dsrpt.contact.communication</field>
<field name="arch" type="xml">
<list>
<field name="communication_type_id"/>
<field name="value"/>
<field name="is_preferred"/>
</list>
</field>
</record>
<!-- Action -->
<record id="action_dsrpt_contact" model="ir.actions.act_window">
<field name="name">Contacts</field>
<field name="res_model">dsrpt.contact</field>
<field name="view_mode">list,form</field>
<field name="search_view_id" ref="view_dsrpt_contact_search"/>
<field name="context">{}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first contact!
</p>
<p>
Manage your contacts and their communication methods in one place.
</p>
</field>
</record>
<!-- Server Actions -->
<!-- Server Action: Send Need Qualification Event -->
<record id="action_server_send_transcription_added" model="ir.actions.server">
<field name="name">Send Need Qualification Event</field>
<field name="model_id" ref="dsrpt_address_book.model_dsrpt_contact"/>
<field name="binding_model_id" ref="dsrpt_address_book.model_dsrpt_contact"/>
<field name="binding_view_types">list,form</field>
<field name="state">code</field>
<field name="code">
# Send transcription added event for selected contacts
if records:
for record in records:
# Trigger event - listeners will decide what to do
# Send need events based on contact status
if record.status == 'awaiting_qualification':
record._event('on_need_qualification').notify(record)
else:
record._event('on_need_request_summary_update').notify(record)
record._event('on_need_calendar_event').notify(record)
# Show notification
# Count events sent
qualification_count = len([r for r in records if r.status == 'awaiting_qualification'])
other_count = len(records) - qualification_count
message_parts = []
if qualification_count:
message_parts.append(f"{qualification_count} qualification events")
if other_count:
message_parts.append(f"{other_count} summary/calendar events")
message = f"Need events sent: {', '.join(message_parts) if message_parts else 'none'}"
action = {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Event Sent',
'message': message,
'type': 'success',
'sticky': False,
}
}
</field>
</record>
<!-- Server Action: Send Need Summary/Calendar Events -->
<record id="action_server_send_context_update" model="ir.actions.server">
<field name="name">Send Need Summary/Calendar Events</field>
<field name="model_id" ref="dsrpt_address_book.model_dsrpt_contact"/>
<field name="binding_model_id" ref="dsrpt_address_book.model_dsrpt_contact"/>
<field name="binding_view_types">list,form</field>
<field name="state">code</field>
<field name="code">
# Send context update event for selected contacts
if records:
for record in records:
# Trigger event - ContextUpdatedListener will handle it
# Send need events for non-qualifying contacts
if record.status != 'awaiting_qualification':
record._event('on_need_request_summary_update').notify(record)
record._event('on_need_calendar_event').notify(record)
# Show notification
qualified_count = len([r for r in records if r.status == 'awaiting_qualification'])
processed_count = len(records) - qualified_count
message = f"Need events sent for {processed_count} contacts ({qualified_count} skipped - awaiting qualification)"
action = {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Event Sent',
'message': message,
'type': 'success',
'sticky': False,
}
}
</field>
</record>
<!-- Server Action: Change Employee for Contacts -->
<record id="action_server_change_employee_contacts" model="ir.actions.server">
<field name="name">Change Employee</field>
<field name="model_id" ref="dsrpt_address_book.model_dsrpt_contact"/>
<field name="binding_model_id" ref="dsrpt_address_book.model_dsrpt_contact"/>
<field name="binding_view_types">list</field>
<field name="state">code</field>
<field name="code">
if records:
action = {
'name': 'Change Employee',
'type': 'ir.actions.act_window',
'res_model': 'change.employee.wizard',
'view_mode': 'form',
'target': 'new',
'context': {
'active_model': 'dsrpt.contact',
'active_ids': records.ids,
'default_model_name': 'dsrpt.contact',
'default_field_name': 'user_id'
}
}
action = action
</field>
</record>
<!-- Server Action: Recompute Next Contact -->
<record id="action_server_recompute_next_contact" model="ir.actions.server">
<field name="name">Recompute "Next Contact"</field>
<field name="model_id" ref="dsrpt_address_book.model_dsrpt_contact"/>
<field name="binding_model_id" ref="dsrpt_address_book.model_dsrpt_contact"/>
<field name="binding_view_types">list</field>
<field name="state">code</field>
<field name="code">
if records:
action = records[0].recompute_next_contact_all()
</field>
</record>
</odoo>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Main Menu -->
<menuitem id="menu_dsrpt_address_book_root"
name="Address Book"
sequence="50"
web_icon="dsrpt_address_book,static/description/icon.png"/>
<!-- Contacts Menu -->
<menuitem id="menu_dsrpt_contacts"
name="Contacts"
parent="menu_dsrpt_address_book_root"
action="action_dsrpt_contact"
sequence="20"/>
<!-- Contact Events Calendar -->
<menuitem id="menu_dsrpt_contact_events"
name="Calendar"
parent="menu_dsrpt_address_book_root"
action="action_contact_event"
sequence="10"/>
<!-- Configuration Menu -->
<menuitem id="menu_dsrpt_address_book_config"
name="Configuration"
parent="menu_dsrpt_address_book_root"
sequence="100"/>
<!-- Communication Types Menu -->
<menuitem id="menu_dsrpt_communication_types"
name="Communication Types"
parent="menu_dsrpt_address_book_config"
action="action_dsrpt_communication_type"
sequence="10"/>
<!-- Contact Sources Menu -->
<menuitem id="menu_contact_sources"
name="Contact Sources"
parent="menu_dsrpt_address_book_config"
action="action_contact_source"
sequence="20"/>
</odoo>

View File

@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import change_employee_wizard

View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class ChangeEmployeeWizard(models.TransientModel):
_name = 'change.employee.wizard'
_description = 'Change Employee Wizard'
model_name = fields.Char(string='Model Name', required=True)
field_name = fields.Char(string='Field Name', required=True)
user_id = fields.Many2one('res.users', string='New Employee', required=True)
def action_change_employee(self):
"""Change employee for selected records"""
self.ensure_one()
# Get active records
active_model = self._context.get('active_model')
active_ids = self._context.get('active_ids')
if active_model and active_ids:
records = self.env[active_model].browse(active_ids)
# Update field on all selected records
records.write({self.field_name: self.user_id.id})
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Employee Updated',
'message': f'{len(records)} records updated with new employee: {self.user_id.name}',
'type': 'success',
'sticky': False,
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "DSRPT Repair Main",
"summary": "Core entities for Repair FSM",
"name": "DSRPT Repair Config",
"summary": "Configuration for Repair FSM",
"version": "19.0.1.0.0",
"category": "Services",
"author": "DisruptLab",

View File

@@ -34,5 +34,5 @@
<field name="view_mode">list,form</field>
</record>
<menuitem id="menu_repair_fsm_zone" name="FSM Zones" parent="dsrpt_repair_main.menu_repair_configuration" action="action_repair_fsm_zone" sequence="10"/>
<menuitem id="menu_repair_fsm_zone" name="FSM Zones" parent="dsrpt_repair_config.menu_repair_configuration" action="action_repair_fsm_zone" sequence="10"/>
</odoo>

View File

@@ -1,14 +0,0 @@
{
"name": "DSRPT Repair Customers",
"summary": "Customers, contacts, and addresses",
"version": "19.0.1.0.0",
"category": "Services",
"author": "DisruptLab",
"license": "LGPL-3",
"depends": ["base", "dsrpt_repair_main"],
"data": [
"security/ir.model.access.csv",
"views/customer_views.xml",
],
"installable": True,
}

View File

@@ -1 +0,0 @@
from . import customer

View File

@@ -1,42 +0,0 @@
from odoo import fields, models
class RepairCustomer(models.Model):
_name = "repair.customer"
_description = "Repair Customer"
_order = "name"
name = fields.Char(required=True)
zone_id = fields.Many2one("repair.fsm.zone", string="FSM Zone")
note = fields.Text()
contact_ids = fields.One2many("repair.customer.contact", "customer_id", string="Contacts")
address_ids = fields.One2many("repair.customer.address", "customer_id", string="Addresses")
class RepairCustomerContact(models.Model):
_name = "repair.customer.contact"
_description = "Repair Customer Contact"
customer_id = fields.Many2one("repair.customer", required=True, ondelete="cascade")
contact_type = fields.Selection(
selection=[
("phone", "Phone"),
("email", "Email"),
("telegram", "Telegram"),
("other", "Other"),
],
required=True,
default="phone",
)
value = fields.Char(required=True)
class RepairCustomerAddress(models.Model):
_name = "repair.customer.address"
_description = "Repair Customer Address"
customer_id = fields.Many2one("repair.customer", required=True, ondelete="cascade")
label = fields.Char(required=True, default="Service Address")
street = fields.Char(required=True)
zone_id = fields.Many2one("repair.fsm.zone", string="FSM Zone")
details = fields.Text()

View File

@@ -1,4 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_repair_customer_user,repair.customer user,model_repair_customer,base.group_user,1,1,1,1
access_repair_customer_contact_user,repair.customer.contact user,model_repair_customer_contact,base.group_user,1,1,1,1
access_repair_customer_address_user,repair.customer.address user,model_repair_customer_address,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_repair_customer_user repair.customer user model_repair_customer base.group_user 1 1 1 1
3 access_repair_customer_contact_user repair.customer.contact user model_repair_customer_contact base.group_user 1 1 1 1
4 access_repair_customer_address_user repair.customer.address user model_repair_customer_address base.group_user 1 1 1 1

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="view_repair_customer_tree" model="ir.ui.view">
<field name="name">repair.customer.tree</field>
<field name="model">repair.customer</field>
<field name="arch" type="xml">
<list>
<field name="name"/>
<field name="zone_id"/>
</list>
</field>
</record>
<record id="view_repair_customer_form" model="ir.ui.view">
<field name="name">repair.customer.form</field>
<field name="model">repair.customer</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="name"/>
<field name="zone_id"/>
<field name="note"/>
</group>
<notebook>
<page string="Contacts">
<field name="contact_ids" context="{'default_customer_id': id}">
<list editable="bottom">
<field name="contact_type"/>
<field name="value"/>
</list>
</field>
</page>
<page string="Addresses">
<field name="address_ids" context="{'default_customer_id': id}">
<list editable="bottom">
<field name="label"/>
<field name="street"/>
<field name="zone_id"/>
<field name="details"/>
</list>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="action_repair_customer" model="ir.actions.act_window">
<field name="name">Customers</field>
<field name="res_model">repair.customer</field>
<field name="view_mode">list,form</field>
</record>
<menuitem id="menu_repair_customers" name="Customers" parent="dsrpt_repair_main.menu_repair_root" action="action_repair_customer" sequence="20"/>
</odoo>

View File

@@ -1 +0,0 @@
from . import models

View File

@@ -5,7 +5,7 @@
"category": "Services",
"author": "DisruptLab",
"license": "LGPL-3",
"depends": ["base", "dsrpt_repair_main"],
"depends": ["base", "dsrpt_repair_config"],
"data": [
"security/ir.model.access.csv",
"views/material_views.xml",

View File

@@ -38,5 +38,5 @@
<field name="view_mode">list,form</field>
</record>
<menuitem id="menu_repair_materials" name="Materials" parent="dsrpt_repair_main.menu_repair_root" action="action_repair_material" sequence="40"/>
<menuitem id="menu_repair_materials" name="Materials" parent="dsrpt_repair_config.menu_repair_root" action="action_repair_material" sequence="40"/>
</odoo>

View File

@@ -5,7 +5,7 @@
"category": "Services",
"author": "DisruptLab",
"license": "LGPL-3",
"depends": ["base", "dsrpt_repair_main"],
"depends": ["base", "dsrpt_repair_config"],
"data": [
"security/ir.model.access.csv",
"views/technician_views.xml",

View File

@@ -58,5 +58,5 @@
<field name="view_mode">list,form</field>
</record>
<menuitem id="menu_repair_technicians" name="Technicians" parent="dsrpt_repair_main.menu_repair_root" action="action_repair_technician" sequence="30"/>
<menuitem id="menu_repair_technicians" name="Technicians" parent="dsrpt_repair_config.menu_repair_root" action="action_repair_technician" sequence="30"/>
</odoo>

View File

@@ -8,8 +8,8 @@
"depends": [
"base",
"mail",
"dsrpt_repair_main",
"dsrpt_repair_customers",
"dsrpt_repair_config",
"dsrpt_address_book",
"dsrpt_repair_technicians",
"dsrpt_repair_materials",
],

View File

@@ -9,18 +9,7 @@ class RepairWorkOrder(models.Model):
_order = "id desc"
name = fields.Char(default="New", copy=False, readonly=True, tracking=True)
customer_id = fields.Many2one("repair.customer", required=True, tracking=True)
customer_contact_id = fields.Many2one(
"repair.customer.contact",
domain="[('customer_id', '=', customer_id)]",
tracking=True,
)
address_id = fields.Many2one(
"repair.customer.address",
domain="[('customer_id', '=', customer_id)]",
string="Service Address",
tracking=True,
)
contact_id = fields.Many2one("dsrpt.contact", required=True, tracking=True)
zone_id = fields.Many2one("repair.fsm.zone", string="FSM Zone", tracking=True)
description = fields.Text()
requested_datetime = fields.Datetime(default=fields.Datetime.now)
@@ -57,12 +46,6 @@ class RepairWorkOrder(models.Model):
rec.total_time_hours = sum(rec.time_line_ids.mapped("hours"))
rec.total_material_cost = sum(rec.material_line_ids.mapped("subtotal"))
@api.onchange("address_id")
def _onchange_address_id(self):
for rec in self:
if rec.address_id and rec.address_id.zone_id:
rec.zone_id = rec.address_id.zone_id
def action_confirm(self):
self.write({"state": "confirmed"})

View File

@@ -6,7 +6,7 @@
<field name="arch" type="xml">
<list>
<field name="name"/>
<field name="customer_id"/>
<field name="contact_id"/>
<field name="zone_id"/>
<field name="scheduled_datetime"/>
<field name="technician_id"/>
@@ -35,9 +35,7 @@
<group>
<group>
<field name="name" readonly="1"/>
<field name="customer_id"/>
<field name="customer_contact_id"/>
<field name="address_id"/>
<field name="contact_id"/>
<field name="zone_id"/>
</group>
<group>
@@ -88,5 +86,5 @@
<field name="view_mode">list,form</field>
</record>
<menuitem id="menu_repair_work_orders" name="Work Orders" parent="dsrpt_repair_main.menu_repair_root" action="action_repair_work_order" sequence="10"/>
<menuitem id="menu_repair_work_orders" name="Work Orders" parent="dsrpt_repair_config.menu_repair_root" action="action_repair_work_order" sequence="10"/>
</odoo>