Merge pull request #4620 from expsa/request_sic

new coc & committe
This commit is contained in:
mohammed-alkhazrji 2025-09-09 17:35:54 +03:00 committed by GitHub
commit 819c1d58c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 1208 additions and 203 deletions

View File

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

View File

@ -11,12 +11,13 @@
'author': "Expert Co Ltd",
'website': "http://www.ex.com",
'category': 'Odex25-Purchase/Odex25-Purchase',
'category': 'Purchase ',
'version': '14.0',
# any module necessary for this one to work correctly
'depends': ['purchase_requisition_custom'],
# always loaded
'data': [
'security/security.xml',
@ -24,6 +25,8 @@
'views/views.xml',
'sequence/seq.xml',
'reports/report_purchase_quotation_inherit.xml',
'wizard/purchase_coc_partial_wizard.xml',
'views/email_template.xml',
],
# only loaded in demonstration mode
'demo': [

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-16 09:35+0000\n"
"PO-Revision-Date: 2025-07-16 09:35+0000\n"
"POT-Creation-Date: 2025-04-29 13:50+0000\n"
"PO-Revision-Date: 2025-04-29 13:50+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@ -16,45 +16,96 @@ msgstr ""
"Plural-Forms: \n"
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.report_purchasequotation_document_inherit_description
msgid "<strong>Description</strong>"
#: model:mail.template,body_html:odex25_purchase_coc.email_template_completion_certificate_confirmation
msgid ""
"\n"
" <div style=\"direction: rtl; text-align: right; font-family: Arial, sans-serif; padding: 20px; border: 1px solid #ddd;\">\n"
" <div style=\"text-align: left; margin-bottom: 20px;\">\n"
" <img src=\"${object.company_id.get_base_url()}/web/image/res.company/${object.company_id.id}/logo\"\n"
" alt=\"Company Logo\"\n"
" style=\"max-width: 100px; height: 50px;\"/>\n"
" </div>\n"
" <hr/>\n"
" <p style=\"font-weight:bold; font-size:14px;\">مرحبًا ${ctx.get('manager_name')},</p>\n"
" <p style=\"font-weight:bold; font-size:14px;\">\n"
" لديك شهادة إنجاز برقم\n"
" <a href=\"\"\n"
" style=\"color: blue; text-decoration: underline;\">\n"
" ${object.name}\n"
" </a>\n"
" يرجى تأكيد استلام الخدمات.\n"
" </p>\n"
"\n"
" <hr/>\n"
" <div style=\"text-align: center; margin-bottom: 20px;\">\n"
" <img src=\"${object.company_id.get_base_url()}/web/image/res.company/${object.company_id.id}/logo\"\n"
" alt=\"Company Logo\"\n"
" style=\"max-width: 100px; height: 50px;\"/>\n"
" </div>\n"
" <p style=\"text-align: center; color: #888;\">${object.company_id.name} | ${object.company_id.email}</p>\n"
" <p style=\"margin-top: 20px;\">\n"
" </p>\n"
" </div>\n"
" "
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_needaction
msgid "Action Needed"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__state__draft
msgid "Applicant"
msgstr "مقدم الطلب"
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__state__approve
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
msgid "Approve"
msgstr ""
msgstr "معتمد"
#. module: odex25_purchase_coc
#: model_terms:ir.actions.act_window,help:odex25_purchase_coc.purchase_coc_action
msgid "Approve and Confirm CoC"
msgstr "الموافقة وتأكيد شهادة الإنجاز"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__attachment_ids
msgid "Attachments"
msgstr ""
#: code:addons/odex25_purchase_coc/models/models.py:0
#, python-format
msgid "Backorder"
msgstr "مرتجع"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__backorder_lines
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__backorder_line_ids
msgid "Backorder Lines"
msgstr "المرتجعات"
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__coc_stage__before_bill
msgid "Before Bill"
msgstr ""
msgstr "قبل الفاتورة"
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__coc_stage__befor_bill_valid
msgid "Before Bill Validation"
msgstr ""
msgstr "قبل التحقق من الفاتورة"
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__coc_stage__before_payment
msgid "Before Payment"
msgstr ""
msgstr "قبل الدفع"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order__coc_created
msgid "COC Created"
msgstr ""
msgstr "تم إنشاء شهادة الإنجاز"
#. module: odex25_purchase_coc
#: model:res.groups,name:odex25_purchase_coc.group_coc_manager
@ -84,33 +135,38 @@ msgstr "شهادة الانجاز"
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.view_id
msgid "Certificates of Completion"
msgstr "شهادات الانجاز"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__coc_id
msgid "CoC"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order__coc
msgid "CoC Created"
msgstr ""
msgstr "تم إنشاء شهادة الإنجاز"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order__coc_id
msgid "CoC Ref"
msgstr ""
msgstr "مرجع شهادة الإنجاز"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__coc_stage
msgid "CoC Stage"
msgstr ""
msgstr "مرحلة شهادة الإنجاز"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order__coc_ids
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.view_id
msgid "CoCs"
msgstr ""
msgstr "شهادات الإنجاز"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__coc_id
msgid "Coc"
msgstr ""
msgstr "شهادة إنجاز"
#. module: odex25_purchase_coc
#: code:addons/odex25_purchase_coc/models/models.py:0
@ -121,63 +177,133 @@ msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order__coc_count
msgid "Cocs"
msgstr "عدد شهادات الإنجاز"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__company_id
msgid "Company"
msgstr ""
#. module: odex25_purchase_coc
#: model:mail.template,subject:odex25_purchase_coc.email_template_completion_certificate_confirmation
msgid "Completion Certificate Confirmation: ${object.name}"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__state__confirm
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
msgid "Confirm"
msgstr ""
msgstr "للتأكيد"
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.view_purchase_coc_partial_wizard_form
msgid "Create Backorder"
msgstr "انشاء أمر مؤجلات"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__create_uid
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__create_uid
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line_history__create_uid
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__create_uid
msgid "Created by"
msgstr ""
msgstr "تم الإنشاء بواسطة"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__create_date
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__create_date
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line_history__create_date
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__create_date
msgid "Created on"
msgstr ""
msgstr "تم الإنشاء في"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__date
msgid "Date"
msgstr ""
msgstr "التاريخ"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__description
msgid "Description"
msgstr "وصف المطلوب"
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__state__manager
#: model:res.groups,name:odex25_purchase_coc.group_purchase_coc_direct_manager
msgid "Direct Manager"
msgstr "المدير المباشر"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_account_move__display_name
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__display_name
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__display_name
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order__display_name
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__display_name
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line_history__display_name
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__display_name
msgid "Display Name"
msgstr "الاسم المعروض"
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__state__draft
msgid "Draft"
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__confirm_create
msgid "Do you want to create a new CoC?"
msgstr "هل تريد إنشاء CoC جديد؟"
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
msgid "Documents"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__attach_no
msgid "Documents Count"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__state__confirm
msgid "Executive Director of Administration"
msgstr "المدير التنفيذي للادارة"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_follower_ids
msgid "Followers"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_channel_ids
msgid "Followers (Channels)"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_account_move__id
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__id
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__id
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order__id
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__id
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line_history__id
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__id
msgid "ID"
msgstr "المُعرف"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__name
msgid "Item"
msgstr "وصف المنتج"
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__message_needaction
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__message_unread
msgid "If checked, new messages require your attention."
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__message_has_error
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__message_has_sms_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__is_return
msgid "Is Return"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model,name:odex25_purchase_coc.model_account_move
@ -187,104 +313,239 @@ msgstr "قيد اليومية"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_account_move____last_update
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc____last_update
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard____last_update
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order____last_update
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line____last_update
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line_history____last_update
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc____last_update
msgid "Last Modified on"
msgstr "آخر تعديل في"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__write_uid
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__write_uid
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line_history__write_uid
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__write_uid
msgid "Last Updated by"
msgstr ""
msgstr "آخر تحديث من قبل"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__write_date
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__write_date
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line_history__write_date
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__write_date
msgid "Last Updated on"
msgstr "آخر تحديث في"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_main_attachment_id
msgid "Main Attachment"
msgstr ""
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
msgid "Manager Approve"
msgstr "تعميد"
#. module: odex25_purchase_coc
#: model:res.groups,name:odex25_purchase_coc.group_coc_manager_direct
msgid "Manager Direct Group"
msgstr "المدير المباشر"
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
msgid "Manager Reject"
msgstr "مرفوض"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_ids
msgid "Messages"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__name
msgid "Name"
msgstr ""
msgstr "رقم اﻹشارة"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order__need_coc
msgid "Need CoC?"
msgstr ""
msgstr "هل تحتاج شهادة الانجاز؟"
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.view_purchase_coc_partial_wizard_form
msgid "No Backorder"
msgstr "لا يوجد أوامر مؤجلات"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__note
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
msgid "Note"
msgstr "الملاحظات"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__message_needaction_counter
msgid "Number of messages which requires an action"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__message_unread_counter
msgid "Number of unread messages"
msgstr ""
#. module: odex25_purchase_coc
#: code:addons/odex25_purchase_coc/models/models.py:0
#, python-format
msgid "Only the department manager can approve this CoC."
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__origin
msgid "Origin"
msgstr ""
msgstr "الأصل"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__origin_name
msgid "Origin Name"
msgstr "اسم المصدر"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line_history__po_line_id
msgid "PO Line"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__po_line_ids
msgid "PO Lines"
msgstr "بنود أوامر الشراء"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__po_return_line_ids
msgid "PO Return Lines"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__parent_coc_id
msgid "Parent CoC"
msgstr "أمر مؤجل لـ"
#. module: odex25_purchase_coc
#: model:ir.model,name:odex25_purchase_coc.model_purchase_coc_partial_wizard
msgid "Partial Quantities Wizard for CoC"
msgstr ""
#. module: odex25_purchase_coc
#: code:addons/odex25_purchase_coc/models/models.py:0
#, python-format
msgid "Partial Receipt Confirmation"
msgstr "تأكيد الاستلام الجزئي"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__po_id
msgid "Po Ref."
msgstr ""
msgstr "المستند المصدر"
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
msgid "Products"
msgstr ""
msgstr "الخدمات"
#. module: odex25_purchase_coc
#: model:ir.model,name:odex25_purchase_coc.model_purchase_coc
msgid "Purchase CoC"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.module.category,name:odex25_purchase_coc.module_category_purchase_management
msgid "Purchase Management"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model,name:odex25_purchase_coc.model_purchase_order
msgid "Purchase Order"
msgstr "أمر شراء"
msgstr "أوامر الشراء المؤكدة"
#. module: odex25_purchase_coc
#: model:ir.model,name:odex25_purchase_coc.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "بند أمر الشراء"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__qty_history
msgid "Qty History"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__qty_received_fake_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line_history__qty_received
msgid "Qty Received"
msgstr "كمية الاستلام"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__qty_received_fake
msgid "Qty Received Fake"
msgstr "كمية الاستلام"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__back_qty_remain
msgid "Qty Remain"
msgstr "الكمية المتبقيه"
#. module: odex25_purchase_coc
#: code:addons/odex25_purchase_coc/models/models.py:0
#, python-format
msgid "Receipt cannot be confirmed without entering the receipt."
msgstr "لا يمكن تأكيد الاستلام دون إدخال الكمية المستلمة."
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__state__cancel
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
msgid "Reject"
msgstr ""
msgstr "مرفوض"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__reject_reason
msgid "Reject Reason"
msgstr ""
msgstr "سبب الرفض"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__reject_reason
msgid "Reject Reson"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__return_id
msgid "Return Ref"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_has_sms_error
msgid "SMS Delivery error"
msgstr ""
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
msgid "Set to Draft"
msgstr "تعيين الى مسودة"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__show_manager_buttons
msgid "Show Manager Buttons"
msgstr ""
#. module: odex25_purchase_coc
@ -293,6 +554,13 @@ msgstr ""
msgid "Sorry This object have no field named Selection Reasoon"
msgstr ""
#. module: odex25_purchase_coc
#: code:addons/odex25_purchase_coc/models/models.py:0
#: code:addons/odex25_purchase_coc/models/models.py:0
#, python-format
msgid "Sorry You are not allowed to Cancel this CoC ."
msgstr ""
#. module: odex25_purchase_coc
#: code:addons/odex25_purchase_coc/models/models.py:0
#, python-format
@ -315,38 +583,84 @@ msgstr "لايمكن اعتماد الفاتورة قبل انشاء وتصدي
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__state
msgid "State"
msgstr ""
msgstr "الحالة"
#. module: odex25_purchase_coc
#. openerp-web
#: code:addons/odex25_purchase_coc/static/src/xml/tender_templates.xml:0
#, python-format
msgid "Submit Your Prices"
msgstr "تأكيد الأسعار"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__tender_name
msgid "Tender Name"
msgstr "اسم المشروع"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_unread
msgid "Unread Messages"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__message_unread_counter
msgid "Unread Messages Counter"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__vendor_id
msgid "Vendor"
msgstr "المورد"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: odex25_purchase_coc
#: code:addons/odex25_purchase_coc/models/models.py:0
#, python-format
msgid "You are not allowed to approve this CoC."
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__vendor_id
msgid "You can find a vendor by its Name, TIN, Email or Internal Reference."
msgstr "لاتستطيع البحث عن مورد بهذا الاسم ابحث بالايميل او الكود"
#. module: odex25_purchase_coc
#: code:addons/odex25_purchase_coc/models/models.py:0
#, python-format
msgid ""
"You cannot approve this CoC because the received quantity exceeds the "
"ordered quantity."
msgstr ""
"لا يمكنك الموافقة على شهادة المطابقة هذه لأن الكمية المستلمة تتجاوز الكمية "
"المطلوبة."
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.view_purchase_coc_partial_wizard_form
msgid "You have processed less product than the initial order."
msgstr "لقد قمت بمعالجة منتج أقل من الطلب الأولي."
#. module: odex25_purchase_coc
#. openerp-web
#: code:addons/odex25_purchase_coc/static/src/xml/tender_templates.xml:0
#, python-format
msgid "delivary date"
msgstr "تاريخ التسليم"
msgstr ""
#. module: odex25_purchase_coc
#. openerp-web
#: code:addons/odex25_purchase_coc/static/src/xml/tender_templates.xml:0
#, python-format
msgid "price"
msgstr "السعر"
msgstr ""
#. module: odex25_purchase_coc
#. openerp-web
@ -360,14 +674,19 @@ msgstr ""
#: code:addons/odex25_purchase_coc/static/src/xml/tender_templates.xml:0
#, python-format
msgid "product id"
msgstr "الصنف"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model,name:odex25_purchase_coc.model_purchase_order_line_history
msgid "purchase.order.line.history"
msgstr ""
#. module: odex25_purchase_coc
#. openerp-web
#: code:addons/odex25_purchase_coc/static/src/xml/tender_templates.xml:0
#, python-format
msgid "quantity"
msgstr "الكمية"
msgstr ""
#. module: odex25_purchase_coc
#: model:ir.model,name:odex25_purchase_coc.model_reject_wizard_coc
@ -375,11 +694,31 @@ msgid "reject.wizard.coc"
msgstr ""
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.report_purchasequotation_document_inherit_description
msgid "Item"
msgstr "المنتج"
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.view_purchase_coc_partial_wizard_form
msgid "الكميات الجزئية"
msgstr ""
#. module: odex25_purchase_coc
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.report_purchasequotation_document_inherit_description
msgid "<strong>Description</strong>"
msgstr "<strong>الوصف</strong>"
#: code:addons/odex25_purchase_coc/models/models.py:0
#: code:addons/odoo/dev_purchase/odex25_purchase/odex25_purchase_coc/models/models.py:0
#, python-format
msgid "You must receive at least one product before confirmation."
msgstr ".يجب استلام منتج واحد على الأقل قبل التأكيد"
#. module: odex25_purchase_coc
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__receiving_meth
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__receiving_meth
msgid "Receiving Method"
msgstr "الإستلام بحسب"
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__receiving_meth__quantity
msgid "Quantity"
msgstr "كمية"
#. module: odex25_purchase_coc
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__receiving_meth__percentage
msgid "Percentage"
msgstr "بنسبة الإنجاز"

View File

@ -19,8 +19,8 @@ class POCustom(models.Model):
@api.depends('coc_ids')
def _compute_coc_count(self):
for rec in self:
rec.coc_count = len(rec.coc_ids)
rec.coc_count = self.env['purchase.coc'].search_count([('po_id', '=', rec.id)])
def button_confirm(self):
super_action = super(POCustom, self).button_confirm()
service_products = self.order_line.filtered(lambda line: line.product_id.type == "service")
@ -53,16 +53,54 @@ class POCustom(models.Model):
self.coc_created = True
def action_create_invoice(self):
for rec in self:
if rec and rec.coc_ids.filtered(lambda coc: coc.coc_stage == 'before_bill' and coc.state != 'approve'):
raise ValidationError(_("Sorry You cannot Create Bill untill CoC Created and Approved."))
return super(POCustom, self).action_create_invoice()
return super().action_create_invoice()
class PurchaseOrderLine(models.Model):
_inherit = 'purchase.order.line'
coc_id = fields.Many2one('purchase.coc')
name = fields.Text(string='Product description')
qty_received_fake = fields.Float(string='Qty Received Fake')
qty_history = fields.One2many('purchase.order.line.history', 'po_line_id', string='Qty History')
back_qty_remain = fields.Float(string='Qty Remain', compute='_compute_qty_remain', store=True)
qty_percentage= fields.Float(string="%", store=True)
receiving_meth = fields.Selection(
string='Receiving Method',
related = 'coc_id.receiving_meth',
)
show_percentage = fields.Boolean(
string="Show Percentage",
compute="_compute_show_percentage",
store=False
)
@api.depends('coc_id.receiving_meth')
def _compute_show_percentage(self):
for line in self:
line.show_percentage = (line.coc_id.receiving_meth == 'percentage')
@api.onchange('qty_percentage')
def _onchange_qty_percentage(self):
if self.qty_percentage and self.product_qty:
self.qty_received_fake = (self.qty_percentage / 100) * self.product_qty
@api.onchange('qty_received_fake')
def _onchange_qty_received_fake(self):
if self.qty_received_fake and self.product_qty:
self.qty_percentage = (self.qty_received_fake / self.product_qty) * 100
@api.depends('product_qty', 'qty_received','qty_history')
def _compute_qty_remain(self):
for rec in self:
sum_qty_received = sum(rec.qty_history.mapped('qty_received')) + rec.qty_received_fake
rec.back_qty_remain = rec.product_qty - sum_qty_received
class PurchaseOrderLineHistory(models.Model):
_name = 'purchase.order.line.history'
po_line_id = fields.Many2one('purchase.order.line', string='PO Line')
qty_received = fields.Float(string='Qty Received')
class AccountInvoiceCustom(models.Model):
@ -72,7 +110,7 @@ class AccountInvoiceCustom(models.Model):
def action_post(self):
if self.move_type == 'in_invoice':
context = self.env.context
print("context",context)
print("context", context)
po = self.env['purchase.order'].search([('id', '=', context.get('active_id', False))])
print(po.coc_ids.filtered(lambda coc: coc.coc_stage == 'befor_bill_valid' and coc.state != 'approve'))
if po and po.coc_ids.filtered(lambda coc: coc.coc_stage == 'befor_bill_valid' and coc.state != 'approve'):
@ -81,11 +119,11 @@ class AccountInvoiceCustom(models.Model):
return super(AccountInvoiceCustom, self).action_post()
else:
return super(AccountInvoiceCustom, self).action_post()
def action_confirm(self):
if self.move_type == 'in_invoice':
context = self.env.context
print("context",context)
print("context", context)
po = self.env['purchase.order'].search([('id', '=', context.get('active_id', False))])
print(po.coc_ids.filtered(lambda coc: coc.coc_stage == 'befor_bill_valid' and coc.state != 'approve'))
if po and po.coc_ids.filtered(lambda coc: coc.coc_stage == 'befor_bill_valid' and coc.state != 'approve'):
@ -105,55 +143,352 @@ class AccountInvoiceCustom(models.Model):
return super(AccountInvoiceCustom, self).action_register_payment()
else:
return super(AccountInvoiceCustom, self).action_register_payment()
@api.model
def create(self, vals):
if 'res_id' in vals:
del vals['res_id']
if 'res_model' in vals:
del vals['res_model']
res = super(AccountInvoiceCustom, self).create(vals)
return res
class PurchaseCoC(models.Model):
_name = 'purchase.coc'
_description = 'Purchase CoC'
name = fields.Char(string='Name')
_inherit = ['mail.thread']
parent_coc_id = fields.Many2one('purchase.coc', string='Parent CoC')
name = fields.Char(string='Name',copy=False)
coc_stage = fields.Selection(string='CoC Stage', selection=[('before_bill', 'Before Bill'),
('befor_bill_valid', 'Before Bill Validation'),
('before_payment', 'Before Payment')]
,default='before_bill')
po_id = fields.Many2one(comodel_name='purchase.order', string='Po Ref.')
vendor_id = fields.Many2one(comodel_name='res.partner', string='Vendor', related="po_id.partner_id")
date = fields.Date(string='Date')
note = fields.Text(string='Note')
state = fields.Selection(string='', selection=[('draft', 'Draft'), ('confirm', 'Confirm'), ('approve', 'Approve'),
('cancel', 'Reject')])
po_line_ids = fields.One2many('purchase.order.line', 'coc_id', string='PO Lines')
reject_reason = fields.Char(string='Reject Reason')
, default='before_bill', tracking=True,copy=False)
po_id = fields.Many2one(comodel_name='purchase.order', string='Po Ref.', tracking=True)
vendor_id = fields.Many2one(comodel_name='res.partner', string='Vendor', related="po_id.partner_id", tracking=True)
date = fields.Date(string='Date', tracking=True)
note = fields.Text(string='Note', tracking=True)
state = fields.Selection(
string='State',
selection=[('draft', 'Applicant'),
('manager', 'Direct Manager'),
('approve', 'Approve'),
('cancel', 'Reject'),
],
tracking=True,
default='draft',
copy=False
)
receiving_meth = fields.Selection(
string='Receiving Method',
selection=[('quantity', 'Quantity'),
('percentage', 'Percentage'),
],
default='quantity',
copy=False
)
return_id = fields.Many2one('purchase.coc', string='Return Ref', tracking=True)
is_return = fields.Boolean(string='Is Return', tracking=True,copy=False)
po_line_ids = fields.One2many('purchase.order.line', 'coc_id', string='PO Lines', tracking=True,)
backorder_lines = fields.Char(string='Backorder Lines', tracking=True)
po_return_line_ids = fields.Many2many('purchase.order.line','po_line_ids_coc_rel', string='PO Return Lines', tracking=True,copy=False)
reject_reason = fields.Char(string='Reject Reason', tracking=True)
# tender_name = fields.Char('Tender Name', related='po_id.tender_name')
qty_received_fake_coc = fields.Float(string='Qty Received', tracking=True, default=0.0)
attach_no = fields.Integer(
string="Documents Count",
compute='_compute_attach_no',
store=False
)
company_id = fields.Many2one('res.company', default=lambda self: self.env.user.sudo().company_id)
@api.depends('message_attachment_count')
def _compute_attach_no(self):
for rec in self:
rec.attach_no = rec.message_attachment_count
def get_attachments(self):
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'name': 'Attachments',
'res_model': 'ir.attachment',
'view_mode': 'kanban,tree,form',
'domain': [('res_model', '=', self._name), ('res_id', '=', self.id)],
'context': {'default_res_model': self._name, 'default_res_id': self.id},
'target': 'current',
}
@api.model
def create(self, vals):
vals['name'] = self.env['ir.sequence'].next_by_code(self._name)
return super(PurchaseCoC, self).create(vals)
res = super(PurchaseCoC, self).create(vals)
res.name = self.env['ir.sequence'].next_by_code(self._name)
return res
def action_manager_approve(self):
request = self.po_id.request_id
user = self.env.user
if request:
employee = request.employee_id.sudo()
if employee.parent_id.user_id.id != user.id:
raise ValidationError(_('Sorry, you are not allowed to confirm this CoC.'))
else:
department_manager = self.po_id.department_id.manager_id.sudo()
if department_manager.user_id.id != user.id:
raise ValidationError(_('Sorry, you are not allowed to confirm this CoC.'))
template = self.env.ref('odex25_purchase_coc.email_template_completion_certificate_confirmation')
if request and request.employee_id and request.employee_id.coach_id:
coach = request.employee_id.sudo().coach_id
manager = coach.work_email
manager_name = coach.name
elif not request and self.po_id.user_id.id == user.id and user.employee_id and user.employee_id.coach_id:
coach = user.employee_id.sudo().coach_id
manager = coach.work_email
manager_name = coach.name
else:
manager = None
manager_name = None
if manager and template:
template.with_context(self.env.context, manager_name=manager_name).send_mail(
self.id,
force_send=True,
email_values={'email_to': manager},
)
def action_confirm(self):
self.write({
'state': 'confirm'
'state': 'confirm',
})
def action_manager_reject(self):
request = self.po_id.request_id
user = self.env.user
if request:
employee = request.employee_id.sudo()
if employee.parent_id.user_id.id != user.id:
raise ValidationError(_('Sorry, you are not allowed to confirm this CoC.'))
else:
department_manager = self.po_id.department_id.manager_id.sudo()
if department_manager.user_id.id != user.id:
raise ValidationError(_('Sorry, you are not allowed to confirm this CoC.'))
if self.env.context['lang'] in ['ar_SY', 'ar_001']:
action_name = 'حدد سبب الرفض'
else:
action_name = 'Specify Reject Reason'
return {
'type': 'ir.actions.act_window',
'name': action_name,
'res_model': 'reject.wizard',
'view_mode': 'form',
'target': 'new',
'context': {'default_origin': self.id, 'default_origin_name': self._name}
}
def _validate_quantity(self,line):
"""Validate that received quantity does not exceed ordered quantity."""
total_qty_received = sum(line.qty_history.mapped('qty_received')) + line.qty_received_fake
if total_qty_received > line.product_qty:
raise ValidationError(
_('Receipt cannot be confirmed without entering the receipt.')
)
return total_qty_received
def action_confirm(self):
# create a backorder if the po line qty is less than the qty received
user = self.env.user
for rec in self:
request = rec.po_id.request_id
if request:
if request.employee_id.user_id.id != user.id:
raise ValidationError(_('Sorry You are not allowed to Confirm this CoC.'))
else:
if rec.po_id.department_id.manager_id.user_id.id != user.id:
raise ValidationError(_('Sorry You are not allowed to Confirm this CoC.'))
target_lines = rec.po_return_line_ids if rec.is_return else rec.po_line_ids
if not any(line.qty_received_fake > 0 for line in target_lines):
raise ValidationError(_('You must receive at least one product before confirmation.'))
for line in target_lines:
self._validate_quantity(line)
if rec.po_id.request_id and rec.po_id.request_id.employee_id:
manager = rec.po_id.request_id.employee_id.department_id.email_manager
manager_name = rec.po_id.request_id.employee_id.department_id.manager_id.name if rec.po_id.request_id else ''
if manager:
template = self.env.ref('odex25_purchase_coc.email_template_completion_certificate_confirmation')
if template:
template.with_context(manager_name=manager_name).send_mail(
rec.id,
force_send=True,
email_values={'email_to': manager},
)
rec.state = 'manager'
def action_approve(self):
self.write({
'state': 'approve'
self.ensure_one()
po = self.po_id.sudo()
"""
Approve the Certificate of Conformity (CoC) for purchase orders.
This method:
1. Validates the received quantities against ordered quantities
2. Records history of received quantities
3. Updates the receipt status
4. Creates backorders when necessary
5. Changes the state to 'approve'
Returns:
dict: Action to open backorder form if backorder is created
"""
def _create_history_and_update_line(line, total_qty_received):
"""Create history record and update line quantities."""
# Create history record
self.env['purchase.order.line.history'].sudo().create({
'po_line_id': line.id,
'qty_received': line.qty_received_fake
})
# Update the fake qty on CoC and reset line's fake qty
self.write({'qty_received_fake_coc': line.qty_received_fake})
# Update line quantities
line.write({
'qty_received_fake': 0,
'qty_percentage':0,
'qty_received': total_qty_received,
'receiving_meth':False
})
# Return whether line needs to be in backorder
return total_qty_received < line.product_qty
def _process_lines(lines):
"""Process product lines and identify those needing backorder."""
backorder_line_ids = []
if not any(line.qty_received_fake > 0 for line in lines):
raise ValidationError(_('You must receive at least one product before confirmation.'))
for line in lines:
if line.product_qty < line.qty_received_fake:
raise ValidationError(
_('You cannot approve this CoC because the received quantity exceeds the ordered quantity.')
)
total_qty_received = self._validate_quantity(line)
needs_backorder = _create_history_and_update_line(line, total_qty_received)
if needs_backorder:
backorder_line_ids.append(line.id)
return backorder_line_ids
# Access control can be uncommented if needed
self._validate_approval_permissions()
# Process the appropriate lines based on whether this is a return
target_lines = self.po_return_line_ids.sudo() if self.is_return else self.po_line_ids.sudo()
backorder_line_ids = _process_lines(target_lines)
# Create backorder if needed
backorder = None
if backorder_line_ids:
self.write({'state': 'approve'})
return {
'name': _('Partial Receipt Confirmation'),
'type': 'ir.actions.act_window',
'res_model': 'purchase.coc.partial.wizard',
'view_mode': 'form',
'target': 'new',
'context': {
'default_coc_id': self.id,
'default_backorder_line_ids': backorder_line_ids,
}
}
else:
self.write({'state': 'approve'})
# Mark as approved
# Return action to view backorder if created
if backorder:
return self._get_backorder_action(backorder)
def _validate_approval_permissions(self):
"""Validate that the current user has permission to approve this CoC."""
user = self.env.user
po = self.po_id.sudo()
request = po.request_id
if request:
employee = request.employee_id.sudo()
if employee.parent_id.user_id.id != user.id:
raise ValidationError(_('Sorry, you are not allowed to confirm this CoC.'))
else:
department_manager = self.po_id.department_id.manager_id.sudo()
if department_manager.user_id.id != user.id:
raise ValidationError(_('Sorry, you are not allowed to confirm this CoC.'))
def _create_backorder(self, backorder_line_ids):
"""Create a backorder with the specified lines."""
backorder = self.copy()
backorder.write({
'is_return': True,
'parent_coc_id': self.id,
'po_return_line_ids': [(6, 0, backorder_line_ids)],
'qty_received_fake_coc': 0,
'receiving_meth':self.receiving_meth
})
# This code is commented because the exchange request module is not needed and
# will cause a problem when we uninstall the exchange request module
# if self.po_id and self.po_id.requisition_id and self.po_id.requisition_id.exchange_request:
# self.po_id.requisition_id.exchange_request.write({
# 'state' : 'done'
# })
for line in backorder.po_return_line_ids:
line.write({'coc_id': backorder.id})
return backorder
def _get_backorder_action(self, backorder):
"""Return the action to open the backorder form."""
return {
'name': _('Backorder'),
'view_mode': 'form',
'res_model': 'purchase.coc',
'type': 'ir.actions.act_window',
'res_id': backorder.id,
'context': self.env.context,
}
def action_cancel(self):
if self.env.context['lang'] in['ar_SY','ar_001']:
user = self.env.user
po = self.po_id.sudo()
request = po.request_id
if request:
coach_user = request.employee_id.sudo().coach_id.user_id
if coach_user.id != user.id:
raise ValidationError(_('Only the department manager can approve this CoC.'))
else:
dept_manager = self.po_id.department_id.manager_id.sudo()
coach_user = dept_manager.coach_id.user_id
if coach_user.id != user.id:
raise ValidationError(_('You are not allowed to approve this CoC.'))
if self.env.context['lang'] in ['ar_SY', 'ar_001']:
action_name = 'حدد سبب الرفض'
else:
action_name = 'Specify Reject Reason'

View File

@ -2,3 +2,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_odex25_purchase_coc_odex25_purchase_coc,odex25_purchase_coc.odex25_purchase_coc,model_purchase_coc,,1,0,0,0
access_odex25_purchase_coc_odex25_purchase_coc_user,odex25_purchase_coc.odex25_purchase_coc_user,model_purchase_coc,group_coc_user,1,1,1,0
access_odex25_purchase_coc_odex25_purchase_coc_manager,odex25_purchase_coc.odex25_purchase_coc_manager,model_purchase_coc,group_coc_manager,1,1,1,1
access_purchase_order_line_history,purchase_order_line_history_name,model_purchase_order_line_history,,1,1,1,1
access_purchase_coc_partial_wizard,access_purchase_coc_partial_wizard,model_purchase_coc_partial_wizard,base.group_user,1,1,1,1
access_purchase_coc_direct_manager,purchase.coc direct manager,model_purchase_coc,group_purchase_coc_direct_manager,1,1,0,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_odex25_purchase_coc_odex25_purchase_coc odex25_purchase_coc.odex25_purchase_coc model_purchase_coc 1 0 0 0
3 access_odex25_purchase_coc_odex25_purchase_coc_user odex25_purchase_coc.odex25_purchase_coc_user model_purchase_coc group_coc_user 1 1 1 0
4 access_odex25_purchase_coc_odex25_purchase_coc_manager odex25_purchase_coc.odex25_purchase_coc_manager model_purchase_coc group_coc_manager 1 1 1 1
5 access_purchase_order_line_history purchase_order_line_history_name model_purchase_order_line_history 1 1 1 1
6 access_purchase_coc_partial_wizard access_purchase_coc_partial_wizard model_purchase_coc_partial_wizard base.group_user 1 1 1 1
7 access_purchase_coc_direct_manager purchase.coc direct manager model_purchase_coc group_purchase_coc_direct_manager 1 1 0 0

View File

@ -1,24 +1,108 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data>
<record id="module_category_purchase_management" model="ir.module.category">
<field name="name">Purchase Management</field>
</record>
<record id="module_category_coc" model="ir.module.category">
<field name="name">COC Management</field>
<field name="description">Category for COC custom module</field>
<field name="sequence">25</field>
</record>
<!-- Purchase COC groups -->
<record id="group_coc_user" model="res.groups">
<field name="name">COC User</field>
<field name="category_id" ref="odex25_purchase_coc.module_category_purchase_management"/>
<field name="category_id" ref="odex25_purchase_coc.module_category_coc"/>
</record>
<record id="group_coc_manager" model="res.groups">
<field name="name">COC Manager</field>
<field name="category_id" ref="odex25_purchase_coc.module_category_purchase_management"/>
<field name="category_id" ref="odex25_purchase_coc.module_category_coc"/>
</record>
<record id="group_coc_menu" model="res.groups">
<record id="group_coc_menu" model="res.groups">
<field name="name">COC Menu</field>
<field name="category_id" ref="odex25_purchase_coc.module_category_purchase_management"/>
<field name="category_id" ref="odex25_purchase_coc.module_category_coc"/>
</record>
<record id="group_coc_manager_direct" model="res.groups">
<field name="name">Manager Direct Group</field>
<field name="category_id" ref="odex25_purchase_coc.module_category_coc"/>
</record>
<!--this for direct manager-->
<record id="group_purchase_coc_direct_manager" model="res.groups">
<field name="name">Direct Manager</field>
<field name="category_id" ref="odex25_purchase_coc.module_category_coc"/>
</record>
<record id="purchase_coc_rule_direct_manager" model="ir.rule">
<field name="name">Purchase CoC - Direct Manager Only</field>
<field name="model_id" ref="model_purchase_coc"/>
<field name="domain_force">
[('po_id.request_id.employee_id.parent_id.user_id', '=', user.id)]
</field>
<field name="groups" eval="[(4, ref('odex25_purchase_coc.group_purchase_coc_direct_manager'))]"/>
</record>
<record id="purchase_coc_rule_department_manager" model="ir.rule">
<field name="name">Purchase CoC - Department Manager Only (No Request)</field>
<field name="model_id" ref="model_purchase_coc"/>
<field name="domain_force">
[
('po_id.request_id', '=', False),
('po_id.department_id.manager_id.user_id', '=', user.id)
]
</field>
<field name="groups" eval="[(4, ref('odex25_purchase_coc.group_purchase_coc_direct_manager'))]"/>
</record>
<!--this for direct manager-->
<!-- Purchase COC Rules -->
<record id="purchase_coc_rule_user" model="ir.rule">
<field name="name">Purchase COC Employee</field>
<field name="model_id" ref="model_purchase_coc"/>
<field name="domain_force">['|','|',('create_uid', '=', user.id),('po_id.request_id.employee_id.user_id','=',user.id),
'&amp;',('po_id.request_id', '=', False),('po_id.user_id', '=', user.id)]
</field>
<field name="groups" eval="[(4, ref('odex25_purchase_coc.group_coc_user'))]"/>
</record>
<record id="purchase_coc_rule_manager" model="ir.rule">
<field name="name">Purchase COC Manager</field>
<field name="model_id" ref="model_purchase_coc"/>
<field name="domain_force">['|','|',('create_uid', '=', user.id),('po_id.request_id.employee_id.coach_id.user_id', '=', user.id),('po_id.employee_id.coach_id.user_id', '=', user.id)]
</field>
<field name="groups" eval="[(4, ref('odex25_purchase_coc.group_coc_manager'))]"/>
</record>
<record id="purchase_coc_rule_manager_no_request" model="ir.rule">
<field name="name">Purchase COC Manager (No Request)</field>
<field name="model_id" ref="model_purchase_coc"/>
<field name="domain_force">
[
('po_id.request_id', '=', False),
('po_id.department_id.manager_id.coach_id.user_id', '=', user.id)
]
</field>
<field name="groups" eval="[(4, ref('odex25_purchase_coc.group_coc_manager'))]"/>
</record>
<record id="show_all_coc_purchase_rule" model="ir.rule">
<field name="name">Show All Purchase COC</field>
<field name="model_id" ref="model_purchase_coc" />
<field eval="True" name="global" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4,ref('purchase.group_purchase_manager'))]"/>
</record>
</data>
</odoo>

View File

@ -0,0 +1,39 @@
<odoo>
<record id="email_template_completion_certificate_confirmation" model="mail.template">
<field name="name">Completion Certificate Confirmation</field>
<field name="model_id" ref="odex25_purchase_coc.model_purchase_coc"/>
<field name="subject">Completion Certificate Confirmation: ${object.name}</field>
<field name="auto_delete" eval="True"/>
<field name="body_html"><![CDATA[
<div style="direction: rtl; text-align: right; font-family: Arial, sans-serif; padding: 20px; border: 1px solid #ddd;">
<div style="text-align: left; margin-bottom: 20px;">
<img src="${object.company_id.get_base_url()}/web/image/res.company/${object.company_id.id}/logo"
alt="Company Logo"
width="120" height="50"
style="display: block; margin: auto;"/>
</div>
<hr/>
<p style="font-weight:bold; font-size:14px;">مرحبًا ${ctx.get('manager_name')},</p>
<p style="font-weight:bold; font-size:14px;">
لديك شهادة إنجاز برقم
<a href=""
style="color: blue; text-decoration: underline;">
${object.name}
</a>
يرجى تأكيد استلام الخدمات.
</p>
<hr/>
<div style="text-align: center; margin-bottom: 20px;">
<img src="${object.company_id.get_base_url()}/web/image/res.company/${object.company_id.id}/logo"
alt="Company Logo"
width="120" height="50"
style="display: block; margin: auto;"/>
</div>
<p style="text-align: center; color: #888;">${object.company_id.name} | ${object.company_id.email}</p>
<p style="margin-top: 20px;">
</p>
</div>
]]></field>
</record>
</odoo>

View File

@ -1,91 +1,170 @@
<odoo>
<data>
<!-- purchase.order inherit form view -->
<record id="view_id" model="ir.ui.view">
<field name="name">purchase.order.inherit.view.form</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_view_invoice']" position="after">
<button type="object" name="action_view_coc" class="oe_stat_button" icon="fa-check" attrs="{'invisible':['|',('state', 'in', ('draft','sent','to approve')),('coc_count','=', 0)]}">
<field name="coc_count" widget="statinfo" string="CoCs" help="Certificates of Completion"/>
<field name="coc_ids" invisible="1"/>
</button>
</xpath>
<xpath expr="//field[@name='company_id']" position="after">
<!-- <field name="need_coc"/> -->
<!-- <field name="coc_id" readonly="1"/> -->
<field name="coc_created" invisible="1"/>
</xpath>
</field>
</record>
<data>
<!-- purchase.order inherit form view -->
<record id="view_id" model="ir.ui.view">
<field name="name">purchase.order.inherit.view.form</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_view_invoice']" position="after">
<button type="object" name="action_view_coc" class="oe_stat_button" icon="fa-check"
attrs="{'invisible':['|',('state', 'in', ('draft','sent','to approve')),('coc_count','=', 0)]}">
<field name="coc_count" widget="statinfo" string="CoCs" help="Certificates of Completion"/>
<field name="coc_ids" invisible="1"/>
</button>
</xpath>
<xpath expr="//field[@name='company_id']" position="after">
<!-- <field name="need_coc"/> -->
<!-- <field name="coc_id" readonly="1"/> -->
<field name="coc_created" invisible="1"/>
</xpath>
</field>
</record>
<!-- purchase.coc form view -->
<record id="purchase_coc_form" model="ir.ui.view">
<field name="name">purchase.coc.view.form</field>
<field name="model">purchase.coc</field>
<field name="arch" type="xml">
<form string="" create="false" delete="false">
<header>
<button name="action_confirm" type="object" class="oe_highlight" states="draft" string="Confirm" groups="odex25_purchase_coc.group_coc_user,odex25_purchase_coc.group_coc_manager"/>
<button name="action_approve" type="object" class="oe_highlight" states="confirm" string="Approve" groups="odex25_purchase_coc.group_coc_manager"/>
<button name="action_cancel" type="object" class="oe_highlight" states="draft,confirm" string="Reject" groups="odex25_purchase_coc.group_coc_manager"/>
<button name="action_draft" type="object" class="oe_highlight" states="cancel" string="Set to Draft"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group col="4" colspan="2">
<field name="po_id" readonly="1"/>
<field name="vendor_id" readonly="1"/>
<field name="date" readonly="1"/>
<field name="coc_stage"/>
</group>
<notebook>
<page string="Products" name="products">
<field name="po_line_ids" readonly="1"/>
</page>
<page string="Note" name="note">
<field name="note"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- purchase.coc form view -->
<record id="purchase_coc_form" model="ir.ui.view">
<field name="name">purchase.coc.view.form</field>
<field name="model">purchase.coc</field>
<field name="arch" type="xml">
<form string="" create="false" delete="false">
<header>
<button name="action_confirm" type="object" class="oe_highlight" states="draft" string="Confirm"
groups="odex25_purchase_coc.group_coc_user,odex25_purchase_coc.group_coc_manager"/>
<!-- purchase.coc tree view -->
<record id="purchase_coc_view_tree" model="ir.ui.view">
<field name="name">model.name.view.tree</field>
<field name="model">purchase.coc</field>
<field name="arch" type="xml">
<tree create="false" delete="false" edit="false">
<field name="name"/>
<field name="po_id"/>
<field name="date"/>
<field name="state"/>
</tree>
</field>
</record>
<button name="action_cancel" type="object" class="oe_highlight" states="draft" string="Reject"
groups="odex25_purchase_coc.group_coc_manager"/>
<button name="action_approve"
type="object"
string="Manager Approve"
states="manager"
class="oe_highlight"
groups="odex25_purchase_coc.group_purchase_coc_direct_manager"
/>
<button name="action_manager_reject"
type="object"
string="Manager Reject"
states="manager"
class="oe_highlight"
groups="odex25_purchase_coc.group_purchase_coc_direct_manager"
/>
<button name="action_draft" type="object" class="oe_highlight" states="cancel" string="Set to Draft"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<group>
<div class="oe_button_box" name="button_box">
<button name="get_attachments"
type="object"
class="oe_stat_button"
icon="fa-file-text-o">
<field name="attach_no" widget="statinfo" string="Documents"/>
</button>
</div>
</group>
<group col="4" colspan="2">
<field name="po_id" readonly="1"/>
<field name="vendor_id" readonly="1"/>
<field name="date" readonly="1"/>
<field name="coc_stage"/>
<!-- <field name="tender_name"/>-->
<field name="receiving_meth"/>
<field name="parent_coc_id" readonly="1"/>
<field name="qty_received_fake_coc" readonly="1" invisible="1"
attrs="{'invisible': [('state', '!=', 'approve')]}" />
<field name="is_return" readonly="1" invisible="1"/>
</group>
<notebook>
<page string="Products" name="products">
<field name="po_line_ids" readonly="0" attrs="{'invisible': [('is_return', '=', True)]}">
<tree editable="bottom">
<field name="order_id" readonly="1"/>
<field name="name" readonly="1"/>
<field name="partner_id" readonly="1"/>
<field name="product_id" readonly="1"/>
<field name="price_unit" readonly="1"/>
<field name="product_qty" readonly="1"/>
<field name="show_percentage" invisible="1"/>
<field name="qty_percentage" attrs="{'invisible': [('show_percentage', '=', False)]}"/>
<field name="qty_received_fake"/>
<field name="qty_received" readonly="1" invisible="1"/>
<field name="back_qty_remain" readonly="1"/>
<field name="product_uom" readonly="1"/>
<field name="price_subtotal" readonly="1"/>
<field name="date_planned" readonly="1"/>
</tree>
</field >
<field name="po_return_line_ids" readonly="0" attrs="{'invisible': [('is_return', '=', False)]}">
<tree editable="bottom">
<field name="order_id" readonly="1"/>
<field name="name" readonly="1"/>
<field name="partner_id" readonly="1"/>
<field name="product_id" readonly="1"/>
<field name="price_unit" readonly="1"/>
<field name="show_percentage" invisible="1"/>
<field name="qty_percentage" attrs="{'invisible': [('show_percentage', '=', False)]}"/>
<field name="qty_received_fake"/>
<field name="qty_received" readonly="1" invisible="1"/>
<field name="back_qty_remain" readonly="1"/>
<field name="product_uom" readonly="1"/>
<field name="price_subtotal" readonly="1"/>
<field name="date_planned" readonly="1"/>
</tree>
</field >
</page>
<page string="Note" name="note">
<field name="note"/>
</page>
</notebook>
<!-- Add the chatter below -->
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" groups="base.group_user"/>
<field name="message_ids"/>
</div>
</form>
</field>
</record>
<!-- purchase.coc tree view -->
<record id="purchase_coc_view_tree" model="ir.ui.view">
<field name="name">model.name.view.tree</field>
<field name="model">purchase.coc</field>
<field name="arch" type="xml">
<tree create="false" delete="false" edit="false">
<field name="name"/>
<field name="po_id"/>
<field name="date"/>
<field name="state"/>
</tree>
</field>
</record>
<!-- purchase.coc action window -->
<record id="purchase_coc_action" model="ir.actions.act_window">
<field name="name">Certificate of Completion</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.coc</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Approve and Confirm CoC
</p>
</field>
</record>
<!-- purchase.coc action window -->
<record id="purchase_coc_action" model="ir.actions.act_window">
<field name="name">Certificate of Completion</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.coc</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Approve and Confirm CoC
</p>
</field>
</record>
<!-- This Menu Item must have a parent and an action -->
<menuitem id="coc_menu" name="Certificat of Completion CoC" parent="purchase.menu_purchase_root" action="purchase_coc_action" groups="group_coc_menu" sequence="3"/>
<!-- This Menu Item must have a parent and an action -->
<menuitem id="coc_menu" name="Certificat of Completion CoC" parent="purchase.menu_purchase_root"
action="purchase_coc_action" groups="group_coc_menu" sequence="3"/>
</data>
</data>
</odoo>

View File

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

View File

@ -0,0 +1,27 @@
from odoo import models, fields, api, _
from datetime import datetime
from odoo.exceptions import ValidationError
class PurchaseCocPartialWizard(models.TransientModel):
_name = 'purchase.coc.partial.wizard'
_description = 'Partial Quantities Wizard for CoC'
confirm_create = fields.Boolean(string="Do you want to create a new CoC?", default=True)
coc_id = fields.Many2one('purchase.coc', string="CoC")
backorder_line_ids = fields.Many2many('purchase.order.line', string="Backorder Lines")
def action_confirm(self):
print("action_confirm")
self.ensure_one()
coc = self.coc_id
backorder = coc._create_backorder(self.backorder_line_ids.ids)
coc.write({'return_id': backorder.id})
return coc._get_backorder_action(backorder)

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_purchase_coc_partial_wizard_form" model="ir.ui.view">
<field name="name">purchase.coc.partial.wizard.form</field>
<field name="model">purchase.coc.partial.wizard</field>
<field name="arch" type="xml">
<form string="الكميات الجزئية">
<p class="alert alert-info">
You have processed less product than the initial order.
</p>
<footer>
<button name="action_confirm" string="Create Backorder" type="object" class="btn-primary"/>
<button string="No Backorder" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>

View File

@ -17,6 +17,7 @@
'data/server_actions.xml',
'views/purchase_requisition_custom.xml',
'views/purchase_request.xml',
'views/purchase_order.xml',
'views/res_setting.xml',
'views/vendor_type.xml',
'wizards/cancel_purchase_request.xml',

View File

@ -118,6 +118,7 @@ class PurchaseOrderCustom(models.Model):
('purchase', 'Purchase Order'),
('done', 'Locked'),
('cancel', 'Cancelled'),
('rejected_by_committee', 'Rejected by Committee'),
('budget_rejected', 'Rejected By Budget'),
('wait_for_send', 'Waiting For Send to Budget')], default='wait')
department_id = fields.Many2one('hr.department', compute="_compute_department_id", store=True, readonly=False)
@ -932,6 +933,52 @@ class PurchaseOrderCustom(models.Model):
self.action_budget()
self.write({'state': 'waiting'})
def _check_requisition_rejection(self):
PO = self.env['purchase.order'].search([
('requisition_id', '=', self.requisition_id.id)
])
if PO and all(p.state == 'rejected_by_committee' for p in PO):
self.sudo().requisition_id.state = 'rejected_by_committee'
self.sudo().requisition_id.sent_to_commitee = False
def rejection_committee_head(self):
self.sudo().state = 'rejected_by_committee'
self._check_requisition_rejection()
def _check_committee_rejection(self):
"""
This method checks two conditions:
1. If the committee members in the Purchase Requisition are the same as in the Purchase Order.
2. If all members in the Purchase Order have refused.
If both are true, it changes the PO state.
"""
self.ensure_one()
if not self.requisition_id or not self.requisition_id.committe_members:
return
requisition_users = self.requisition_id.committe_members
po_users = self.committe_members.mapped('user_id')
if set(requisition_users.ids) == set(po_users.ids):
if self.committe_members and all(member.refused for member in self.committe_members):
self.write({
'state': 'rejected_by_committee',
})
self._check_requisition_rejection()
self.message_post(body=_("تم رفض عرض السعر من قبل جميع أعضاء اللجنة."))
return True
class PurchaseOrderLineCustom(models.Model):
_inherit = 'purchase.order.line'

View File

@ -57,6 +57,7 @@ class PurchaseRequisitionCustom(models.Model):
state_blanket_order = fields.Selection(
selection_add=[('purchase_manager', 'Purchase manager'), ('checked', 'Waiting Approval'),
('committee', 'Committee'),
('rejected_by_committee', 'Rejected by Committee'),
('purchase_manager', 'Purchase manager'),
('second_approve', 'Second Approval'),
('legal_counsel', 'Legal Counsel'),
@ -75,6 +76,7 @@ class PurchaseRequisitionCustom(models.Model):
('ongoing', 'Ongoing'),
('in_progress', 'Confirmed'),
('committee', 'Committee'),
('rejected_by_committee', 'Rejected by Committee'),
('purchase_manager', 'Purchase manager'),
('second_approve', 'Second Approval'),
('legal_counsel', 'Legal Counsel'),

View File

@ -144,5 +144,9 @@
<field name="category_id" ref="purchase_requisition_custom.module_category_purchase_requisition_custom"/>
</record>
<record id="group_reject_purchase_committee_head" model="res.groups">
<field name="name">Reject PO Committee </field>
<field name="category_id" ref="purchase_requisition_custom.module_category_purchase_requisition_custom"/>
</record>
</odoo>

View File

@ -0,0 +1,16 @@
<odoo>
<record id="po_custom_tree_view" model="ir.ui.view">
<field name="name">purchase.order.tree.custom</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_tree"/>
<field name="arch" type="xml">
<xpath expr="//tree" position="inside">
<button name="rejection_committee_head" string="Reject Committee" class="oe_highlight"
type="object" groups="purchase_requisition_custom.group_reject_purchase_committee_head"
attrs="{'invisible':[('state','!=','wait')]}"
/>
</xpath>
</field>
</record>
</odoo>

View File

@ -78,30 +78,34 @@
<field name="context">{"default_requisition_id":active_id}</field>
</record>
<!-- inherit [purchase ]tree-->
<record id="purchase_order_custom_tree" model="ir.ui.view">
<record id="purchase_order_custom_tree" model="ir.ui.view">
<field name="name">purchase.order.tree.custom</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_tree"/>
<field eval="101" name="priority"/>
<field name="arch" type="xml">
<tree>
<xpath expr="//field[@name='name']" position="before">
<field name="request_id"/>
<field name="requisition_id" string="Source Document"/>
</tree>
<xpath expr="/tree[1]/field[@name='origin']" position="attributes">
</xpath>
<xpath expr="//field[@name='origin']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="/tree[1]/field[@name='partner_id']" position="after">
<xpath expr="//field[@name='partner_id']" position="after">
<field name="recommendation_order" string="Recommend Order"/>
</xpath>
<!-- <field name="partner_id" position="after">-->
<!-- <field name="recommendation_order" string="Recommend Order"/>-->
<!-- </field>-->
</field>
</record>
<!-- Inherit the Purchase Order form ?purchase.purchase_order_form?-->
<record id="purchase_order_custom_form_view" model="ir.ui.view">
<field name="name">purchase.order.form.custom</field>
@ -176,11 +180,12 @@
<!-- attrs="{'invisible':['|',('requisition_id','=',False),'|','&amp;',('requisition_type_exclusive', '!=','exclusive'),('is_purchase_budget','=',False),('state','not in',('to approve'))]}"/>-->
<button type="object" name="action_approve_po" string="Confirm Purchase" class="oe_highlight" invisible="1"/>
<button type="object" name="action_select" groups="purchase_requisition_custom.committe_member"
attrs="{'invisible':['|', '|',('state','in',['done','purchase','waiting','cancel']),('already_voted','=',True),('can_committee_vote', '=', False)]}"
string="Select"/>
<button type="object" name="action_select" groups="purchase_requisition_custom.committe_member"
attrs="{'invisible':['|', '|',('state','in',['done','purchase','waiting','cancel','rejected_by_committee']),('already_voted','=',True),('can_committee_vote', '=', False)]}"
string="Select"/>
<button type="object" name="action_refuse" groups="purchase_requisition_custom.committe_member"
attrs="{'invisible':['|', '|',('state','in',['done','purchase','waiting','cancel']),('already_voted','=',True),('can_committee_vote', '=', False)]}"
attrs="{'invisible':['|', '|',('state','in',['done','purchase','waiting','cancel','rejected_by_committee']),('already_voted','=',True),('can_committee_vote', '=', False)]}"
string="Refuse"/>
<button type="object" name="action_recommend"
groups="purchase_requisition_custom.group_select_recommended_offer"
@ -376,7 +381,7 @@
class="oe_highlight"/>
<button type="object" groups="purchase_requisition_custom.group_quotation_purchase_requisition"
name="action_quotation" string="Quotation"
attrs="{'invisible':['&amp;','|',('state','!=','accept'),('type','!=','project'),'|',('state','not in',('in_progress', 'ongoing')),('type','!=','operational')]}"
attrs="{'invisible':['&amp;','|',('state','!=','accept'),('type','!=','project'),'|',('state','not in',('in_progress', 'ongoing','rejected_by_committee')),('type','!=','operational')]}"
class="btn-primary"/>
<button type="object" groups="purchase.group_purchase_user" name="action_budget"
string="Send To Budget" attrs="{'invisible':['|', ('state','!=', 'purchase_manager'),('is_purchase_budget','=',False)]}"
@ -443,7 +448,7 @@
</xpath>
<xpath expr="/form/header/button[@name='action_cancel']" position="replace">
<button name="action_cancel" groups="purchase_requisition_custom.group_cancel_purchase_requisition"
states="draft,in_progress,ongoing,checked,purchase_manager"
states="draft,in_progress,ongoing,checked,purchase_manager,rejected_by_committee"
string="Cancel" type="object"/>
</xpath>
<xpath expr="/form/header/button[@name='action_draft']" position="attributes">