Public release from ruodoo-project: 19.0 - 2026-07-26 21:17:35 UTC

This commit is contained in:
CI Publish Bot
2026-07-26 21:17:45 +00:00
commit 4f7b594ec8
1335 changed files with 191620 additions and 0 deletions

View File

@ -0,0 +1,7 @@
from . import project_task
from . import sale_order
from . import directive_directive
from . import account_move
from . import account_payment
from . import mrp_workorder
from . import stock_picking

View File

@ -0,0 +1,32 @@
from odoo import models, fields
class AccountMove(models.Model):
_name = "account.move"
_inherit = ["account.move", "directive.mixin"]
def _directive_generation_spec(self):
return [
{
"event": "on_write",
"key": "am_audit_trigger",
"field": "state",
"from": "draft",
"to": "posted",
"use_record_template_group": True,
"mode": "create_once",
# Генерируем только для входящих инвойсов от поставщиков
"domain": [("move_type", "=", "in_invoice")],
}
]
def action_audit_response(self, payload: dict):
"""
Вызывается агентом-аудитором.
"""
for move in self:
move.message_post(
body=f"Audit Bot: Обнаружен риск, 30/100."
f"Директива #{payload.get('directive_id')} завершена с предупреждением."
)

View File

@ -0,0 +1,32 @@
from odoo import models, fields
class AccountPayment(models.Model):
_name = 'account.payment'
_inherit = ["account.payment", "directive.mixin"]
def _directive_generation_spec(self):
return [
{
"event": "on_write",
"key": "pay_bank_trigger",
"field": "state",
"from": "draft",
"to": "in_process",
"use_record_template_group": True,
"mode": "create_once",
# Только для исходящих платежей
"domain": [("payment_type", "=", "outbound")],
}
]
def action_bank_gateway_response(self, payload: dict):
for pay in self:
bank_ref = f"REF-{pay.id}-X99"
pay.message_post(
body=f"Bank Gateway: Платеж отправлен в банк."
f"Bank Reference: {bank_ref}"
f"Комиссия агента: 0.00 у.е."
)
return True

View File

@ -0,0 +1,27 @@
from odoo import api, models
class Directive(models.Model):
_inherit = "directive.directive"
@api.model
def _cron_simulate_system_agents(self):
"""
Этот метод имитирует работу внешних систем (WMS, Банк, AI).
Запускается раз в минуту.
"""
system_directives = self.search([
('executor_type', 'in', ['software', 'machine']),
('stage_code', 'in', ['draft', 'planned', 'in_progress']),
('stage_code', '!=', 'done')
], limit=50)
for d in system_directives:
if d.stage_code == 'planned':
d._set_stage('in_progress')
print(f"Agent started directive {d.id}")
elif d.stage_code == 'in_progress':
d.action_done()
print(f"Agent finished directive {d.id}")

View File

@ -0,0 +1,77 @@
from odoo import models, fields
class MrpWorkorder(models.Model):
_name = "mrp.workorder"
_inherit = ["mrp.workorder", "directive.mixin"]
def _directive_generation_spec(self):
return [
{
"event": "on_write",
"key": "mrp_iot_trigger",
"field": "state",
"from": "pending",
"to": "ready",
"use_record_template_group": True,
"mode": "create_once",
"domain": [("name", "ilike", "резка")],
}
]
def action_iot_signal(self, payload: dict):
"""
Метод-обработчик завершения директивы оборудованием.
Записывает телеметрию в саму операцию и в головной заказ (MO).
"""
for wo in self:
telemetry = payload.get('telemetry', {})
temp = telemetry.get('temperature', 59)
vibro = telemetry.get('vibration', 'Норма')
message = (
f"IoT CNC [{wo.name}]: Операция завершена.<br/>"
f"Температура шпинделя: {temp}°C<br/>"
f"Вибрация: {vibro}."
)
if wo.production_id:
wo.production_id.message_post(
body=f"Отчет по операции {wo.name}: {message}"
)
return True
class MrpProduction(models.Model):
_inherit = 'mrp.production'
def action_choose_directive_group(self):
self.ensure_one()
workorder = self.workorder_ids[:1]
if not workorder:
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Внимание',
'message': 'Сначала подтвердите заказ, чтобы появились операции (Work Orders)',
'type': 'warning',
'sticky': False,
}
}
return {
"type": "ir.actions.act_window",
"name": f"Назначить директивы для: {workorder.name}",
"res_model": "directive.choose.group.wizard",
"view_mode": "form",
"target": "new",
"context": {
# КОСТЫЛЬ
"active_model": "mrp.workorder",
"active_id": workorder.id,
},
}

View File

@ -0,0 +1,44 @@
from odoo import models
class ProjectTask(models.Model):
_name = 'project.task'
_inherit = ["project.task", "directive.mixin"]
def directive_on_done_post_message(self, payload: dict):
for task in self:
task.message_post(
body=f"Директива выполнена: {payload.get('directive_name')})"
)
return True
# def _directive_generation_spec(self):
# return [
# {
# "event": "on_callback",
# "callback": "action_demo_directive_callback",
# "mode": "create_once",
# "when": "after",
# "if_result": True,
# "use_record_template_group": True,
# "key": "demo_callback_v1",
# }
# ]
def _directive_generation_spec(self):
return [
{
"event": "on_write",
"key": "stage_draft_to_progress",
"field": "stage_id",
"from": 9,
"to": 10,
"use_record_template_group": True,
"mode": "create_once",
}
]
def action_demo_directive_callback(self):
for task in self:
task.message_post(body="Demo callback executed")
return True

View File

@ -0,0 +1,31 @@
from odoo import models, fields, api
class SaleOrder(models.Model):
_name = 'sale.order'
_inherit = ["sale.order", "directive.mixin"]
def _directive_generation_spec(self):
return [
{
"event": "on_write",
"key": "so_trigger_wms",
"field": "state",
"from": "draft",
"to": "sale",
"use_record_template_group": True,
"mode": "create_once",
}
]
def action_wms_response(self, payload: dict):
for order in self:
bin_location = "ZONE-A-ROW-5"
order.message_post(
body=f"WMS Агент: Товар зарезервирован."
f"Ячейка: {bin_location}<br/>"
f"Директива #{payload.get('directive_id')} закрыта успешно."
)
return True

View File

@ -0,0 +1,26 @@
from odoo import models, fields
class StockPicking(models.Model):
_name = 'stock.picking'
_inherit = ["stock.picking", "directive.mixin"]
def _directive_generation_spec(self):
return [
{
"event": "on_callback",
"callback": "button_validate",
"mode": "create_once",
"when": "after",
"if_result": True,
"use_record_template_group": True,
"key": "picking_done_check_finance",
}
]
def action_agv_callback(self, payload: dict):
for picking in self:
picking.message_post(
body=f"AGV Unit 01: Доставка в зону производства выполнена."
f"Батарея: 84%."
)
return True