manager custody employee

This commit is contained in:
mohammed-alkhazrji 2025-06-19 18:08:35 +03:00
parent bb7e2368f1
commit 2042e5b7ac
23 changed files with 2022 additions and 0 deletions

View File

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

View File

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
{
'name': "Custody Management in Odoo: From Request to Settlement",
'summary': """
Odoo Custody Lifecycle: Request, Disburse, and Settl""",
'description': """
This course provides a comprehensive, hands-on guide to managing employee custodies (Petty Cash) in Odoo. You'll learn how to handle custody requests (temporary and permanent), disbursement processes, and final settlement using Odoos standard expense module. The course focuses on both configuration and operational workflows to ensure smooth and efficient custody management.
""",
'author': "ODEX",
'website': "http://www.yourcompany.com",
# Categories can be used to filter modules in modules listing
# Check https://github.com/odoo/odoo/blob/14.0/odoo/addons/base/data/ir_module_category_data.xml
# for the full list
'category': 'Uncategorized',
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['base','hr','account','exp_payroll_custom','hr_expense','odex25_account_reports','system_dashboard_classic','odex_takaful'],
# always loaded
'data': [
'security/security.xml',
'security/ir.model.access.csv',
'views/views.xml',
'views/templates.xml',
'report/report.xml',
'data/sequence.xml',
'views/account_journal.xml',
'views/types_custody.xml',
'wizard/account_paymrnt_register_views.xml'
],
# only loaded in demonstration mode
'demo': [
'demo/demo.xml',
],
}

View File

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

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# from odoo import http
# class ReprotPointOfSale(http.Controller):
# @http.route('/reprot_point_of_sale/reprot_point_of_sale/', auth='public')
# def index(self, **kw):
# return "Hello, world"
# @http.route('/reprot_point_of_sale/reprot_point_of_sale/objects/', auth='public')
# def list(self, **kw):
# return http.request.render('reprot_point_of_sale.listing', {
# 'root': '/reprot_point_of_sale/reprot_point_of_sale',
# 'objects': http.request.env['reprot_point_of_sale.reprot_point_of_sale'].search([]),
# })
# @http.route('/reprot_point_of_sale/reprot_point_of_sale/objects/<model("reprot_point_of_sale.reprot_point_of_sale"):obj>/', auth='public')
# def object(self, obj, **kw):
# return http.request.render('reprot_point_of_sale.object', {
# 'object': obj
# })

View File

@ -0,0 +1,30 @@
<odoo>
<record id="sequence_request_pledge_ref" model="ir.sequence">
<field name="name">sequence request pledge</field>
<field name="code">hr.request.pledge</field>
<field name="prefix">PRT</field>
<field name="padding">5</field>
</record>
<!-- <record id="action_account_report_partner_ledger_inherited" model="ir.actions.client">-->
<!-- <field name="name">Partner Ledger</field>-->
<!-- <field name="tag">account_report</field>-->
<!-- <field name="context" eval="{'model': 'account.partner.ledger'}"/>-->
<!-- </record>-->
<!-- <record id="action_report_partner_ledger_inherited_test" model="ir.actions.server">-->
<!-- <field name="name">General Ledger</field>-->
<!-- <field name="model_id" ref="model_hr_employee"/>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">-->
<!-- action = model.action_open_partner_ledger_test()-->
<!-- </field>-->
<!-- </record>-->
<!-- <menuitem id="menu_action_account_report_partner_ledger_request_pledge"-->
<!-- name="Partner Ledger"-->
<!-- action="action_report_partner_ledger_inherited_test"-->
<!-- parent="hr_expense.menu_hr_expense_reports"-->
<!-- sequence="1"/>-->
</odoo>

View File

@ -0,0 +1,30 @@
<odoo>
<data>
<!--
<record id="object0" model="reprot_point_of_sale.reprot_point_of_sale">
<field name="name">Object 0</field>
<field name="value">0</field>
</record>
<record id="object1" model="reprot_point_of_sale.reprot_point_of_sale">
<field name="name">Object 1</field>
<field name="value">10</field>
</record>
<record id="object2" model="reprot_point_of_sale.reprot_point_of_sale">
<field name="name">Object 2</field>
<field name="value">20</field>
</record>
<record id="object3" model="reprot_point_of_sale.reprot_point_of_sale">
<field name="name">Object 3</field>
<field name="value">30</field>
</record>
<record id="object4" model="reprot_point_of_sale.reprot_point_of_sale">
<field name="name">Object 4</field>
<field name="value">40</field>
</record>
-->
</data>
</odoo>

View File

@ -0,0 +1,694 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * employee_custody_request
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-13 07:07+0000\n"
"PO-Revision-Date: 2024-10-13 07:07+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: employee_custody_request
#: model:res.groups,name:employee_custody_request.group_all_records_access
msgid "Access All Records"
msgstr ""
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.view_account_move_line_tree_custom
msgid "Account Move Lines"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_expense_sheet__account_payment_method_id
msgid "Account Payment Method"
msgstr "طريقة الدفع بالحساب"
#. module: employee_custody_request
#: model:res.groups,name:employee_custody_request.group_account_manager
msgid "Accounting Manager"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_needaction
msgid "Action Needed"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__activity_ids
msgid "Activities"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__activity_exception_decoration
msgid "Activity Exception Decoration"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__activity_state
msgid "Activity State"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__activity_type_icon
msgid "Activity Type Icon"
msgstr ""
#. module: employee_custody_request
#: model:res.groups,name:employee_custody_request.group_hr_manager
msgid "Administrator"
msgstr ""
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "Another Employee"
msgstr "موظف آخر"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_attachment_count
msgid "Attachment Count"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__code
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "Code"
msgstr "الرمز"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__create_uid
msgid "Created by"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__create_date
msgid "Created on"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__date
msgid "Date"
msgstr "تاريخ"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__department_id
msgid "Department"
msgstr "الهيكل الإداري"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__display_name
msgid "Display Name"
msgstr "اسم العرض"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#: model:ir.model.fields.selection,name:employee_custody_request.selection__hr_request_pledge__state__draft
#, python-format
msgid "Draft"
msgstr "مسودة"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#, python-format
msgid "Employee expect amount should be bigger than zero!"
msgstr "يجب أن يكون المبلغ المتوقع للموظف أكبر من الصفر!"
#. module: employee_custody_request
#: model:ir.model,name:employee_custody_request.model_hr_employee
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__employee_id
msgid "Employee"
msgstr "الموظف"
#. module: employee_custody_request
#: model:ir.actions.server,name:employee_custody_request.action_employee_custody_report
msgid "Employee Account"
msgstr "تقرير الموظف"
#. module: employee_custody_request
#: model:ir.ui.menu,name:employee_custody_request.employee_custody_report_menu
msgid "Employee Account Report"
msgstr "تقرير حساب الموظف"
#. module: employee_custody_request
#: model:res.groups,name:employee_custody_request.group_employee_custody_report
msgid "Employee Custody Report"
msgstr "تقرير حساب الموظف"
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "Employee Name"
msgstr "اسم الموظف"
#. module: employee_custody_request
#: model:ir.model,name:employee_custody_request.model_hr_expense
msgid "Expense"
msgstr "المصروف"
#. module: employee_custody_request
#: model:ir.model,name:employee_custody_request.model_hr_expense_sheet
msgid "Expense Report"
msgstr "تقرير المصروف"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#, python-format
msgid ""
"Expenses must have an expense journal specified to generate accounting "
"entries."
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_follower_ids
msgid "Followers"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_channel_ids
msgid "Followers (Channels)"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_partner_ids
msgid "Followers (Partners)"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__activity_type_icon
msgid "Font awesome icon e.g. fa-tasks"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__from_hr_depart
msgid "From Hr Depart"
msgstr ""
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "GM Manager Approve"
msgstr "تصديق المدير العام"
#. module: employee_custody_request
#: model:ir.actions.server,name:employee_custody_request.action_report_partner_ledger_inherited_test
#: model:ir.module.category,name:employee_custody_request.hr_general_ledger
#: model:ir.module.category,name:employee_custody_request.module_category_general_ledger_custom
msgid "General Ledger"
msgstr "دفتر الأستاذ العام"
#. module: employee_custody_request
#: model:res.groups,name:employee_custody_request.group_general_ledger_manger
msgid "General Ledger Manager"
msgstr ""
#. module: employee_custody_request
#: model:res.groups,name:employee_custody_request.group_general_manager
msgid "General Manager"
msgstr ""
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.view_account_payment_form_inherit
msgid "Go to HR Request Pledge"
msgstr ""
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "Go to account payment"
msgstr "حساب الدفع"
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.hr_view_budget_form_inherit
msgid "Go to budget confirmation"
msgstr "تأكيد الميزانية"
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "HR Manager Approve"
msgstr "تصديق الموارد البشرية"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_account_payment__hr_request_pledge
msgid "Hr Request Pledge"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__id
msgid "ID"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__activity_exception_icon
msgid "Icon"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__activity_exception_icon
msgid "Icon to indicate an exception activity."
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__message_needaction
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__message_unread
msgid "If checked, new messages require your attention."
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__message_has_error
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__message_has_sms_error
msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_is_follower
msgid "Is Follower"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__job_id
msgid "Job Position"
msgstr "المهنة"
#. module: employee_custody_request
#: model:ir.actions.act_window,name:employee_custody_request.job_request_action_pledge
msgid "Job Request pledge"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_employee__journal_id
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__journal_id
msgid "Journal"
msgstr "دفاتر اليومية"
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.view_employee_journal_form_inherit
msgid "Journal Information"
msgstr "معلومات دفاتر اليومية"
#. module: employee_custody_request
#: model:ir.model,name:employee_custody_request.model_account_move_line
msgid "Journal Item"
msgstr "عنصر اليومية"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge____last_update
msgid "Last Modified on"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__write_uid
msgid "Last Updated by"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__write_date
msgid "Last Updated on"
msgstr ""
#. module: employee_custody_request
#: model:res.groups,name:employee_custody_request.group_loan_manager
msgid "Loan Manager"
msgstr ""
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#: model:ir.model.fields.selection,name:employee_custody_request.selection__hr_request_pledge__state__closed
#, python-format
msgid "Loan Suspended"
msgstr "القرض معلق"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_main_attachment_id
msgid "Main Attachment"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_has_error
msgid "Message Delivery error"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_ids
msgid "Messages"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__my_activity_date_deadline
msgid "My Activity Deadline"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__activity_date_deadline
msgid "Next Activity Deadline"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__activity_summary
msgid "Next Activity Summary"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__activity_type_id
msgid "Next Activity Type"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_needaction_counter
msgid "Number of Actions"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_has_error_counter
msgid "Number of errors"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__message_needaction_counter
msgid "Number of messages which requires an action"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__message_unread_counter
msgid "Number of unread messages"
msgstr ""
#. module: employee_custody_request
#: model:res.groups,name:employee_custody_request.group_hr_user
msgid "Officer"
msgstr ""
#. module: employee_custody_request
#: model:ir.actions.client,name:employee_custody_request.action_account_report_partner_ledger_inherited
msgid "Partner Ledger"
msgstr "دفتر حسابات الشريك"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_expense_sheet__payment_account_id
msgid "Payment Account"
msgstr ""
#. module: employee_custody_request
#: model:ir.model,name:employee_custody_request.model_account_payment
msgid "Payments"
msgstr "الدفعات"
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "Payroll Officer Approve"
msgstr "تصديق مسؤول الرواتب"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#, python-format
msgid "Please enter Bank Journal and Payment Method!"
msgstr "الرجاء إدخال دفتر اليومية المصرفية وطريقة الدفع!"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#, python-format
msgid "Please set the journal for this employee."
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__reason
msgid "Reason/Justification"
msgstr ""
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "Refuse"
msgstr "رفض"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#: model:ir.model.fields.selection,name:employee_custody_request.selection__hr_request_pledge__state__refused
#, python-format
msgid "Refused"
msgstr "مرفوض"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__emp_expect_amount
msgid "Request Employee Amount"
msgstr "طلب مبلغ الموظف"
#. module: employee_custody_request
#: model:ir.model,name:employee_custody_request.model_hr_request_pledge
msgid "Request Pledge"
msgstr "طلب عهدة"
#. module: employee_custody_request
#: model:ir.ui.menu,name:employee_custody_request.job_request_pledge
msgid "Request pledge"
msgstr "طلب عهدة"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__activity_user_id
msgid "Responsible User"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_has_sms_error
msgid "SMS Delivery error"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__state
msgid "State"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__description
msgid "Statement"
msgstr "وصف"
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__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: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "Submit"
msgstr "إرســـال"
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "Transfer"
msgstr "ترحيل للمالية"
#. module: employee_custody_request
#: model_terms:ir.ui.view,arch_db:employee_custody_request.job_request_form_pledge_view
msgid "Financial Approval"
msgstr "اعتماد مالي"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#: model:ir.model.fields.selection,name:employee_custody_request.selection__hr_request_pledge__state__financial_approve
#, python-format
msgid "Wait Financial Approval"
msgstr "اعتماد المالية"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#: model:ir.model.fields.selection,name:employee_custody_request.selection__hr_request_pledge__state__pay
#, python-format
msgid "Transferred"
msgstr "تم الترحيل"
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__activity_exception_decoration
msgid "Type of the exception activity on record."
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_unread
msgid "Unread Messages"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__message_unread_counter
msgid "Unread Messages Counter"
msgstr ""
#. module: employee_custody_request
#: model:ir.module.category,description:employee_custody_request.module_category_general_ledger_custom
msgid "User access level for this module"
msgstr ""
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#: model:ir.model.fields.selection,name:employee_custody_request.selection__hr_request_pledge__state__hr_manager
#, python-format
msgid "Wait GM Approval"
msgstr "إنتظار المدير العام"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#: model:ir.model.fields.selection,name:employee_custody_request.selection__hr_request_pledge__state__direct_manager
#, python-format
msgid "Wait HR Department"
msgstr "إنتظار الموارد البشرية"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#: model:ir.model.fields.selection,name:employee_custody_request.selection__hr_request_pledge__state__executive_manager
#, python-format
msgid "Wait Transfer"
msgstr "إنتظار الترحيل"
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#: model:ir.model.fields.selection,name:employee_custody_request.selection__hr_request_pledge__state__submit
#, python-format
msgid "Waiting Payroll Officer"
msgstr "إنتظار مسؤول الرواتب"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__website_message_ids
msgid "Website Messages"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_hr_request_pledge__website_message_ids
msgid "Website communication history"
msgstr ""
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#, python-format
msgid "You can only generate accounting entry for approved expense(s)."
msgstr ""
#. module: employee_custody_request
#: code:addons/employee_custody_request/models/models.py:0
#, python-format
msgid "You can't mix sample expenses and regular ones"
msgstr ""
#. module: employee_custody_request
#: model:ir.ui.menu,name:employee_custody_request.menu_action_account_report_partner_ledger_request_pledge
msgid "`Partner Ledger`"
msgstr "دفتر الأستاذ العام"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_expense__action_budget_id
msgid "analytic"
msgstr ""
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_account_journal__custody_journal
msgid "Custody Journal"
msgstr "دفتر عهد"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_account_payment_register__custody_partner_id
msgid "Custody Partner"
msgstr "شريك العهده"
#. module: employee_custody_request
#: code:addons/odoo/odex25-ensan-project/employee_custody_request/models/models.py:0
#: code:addons/employee_custody_request/models/models.py:0
#, python-format
msgid "Employee must have a related partner."
msgstr "يجب أن يكون لدى الموظف شريك ذو صلة."
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_account_journal__partner_id
msgid "Partner"
msgstr "الشريك"
#. module: employee_custody_request
#: model:ir.model.fields,help:employee_custody_request.field_account_journal__partner_id
msgid "Partner associated with this journal"
msgstr "الشريك المرتبط بهذه المجلة"
#. module: employee_custody_request
#: code:addons/odoo/odex25-ensan-project/employee_custody_request/models/account_payment.py:0
#: code:addons/employee_custody_request/models/account_payment.py:0
#, python-format
msgid ""
"The journal entry %s reached an invalid state relative to its payment.\n"
"To be consistent, the journal items must share the same partner."
msgstr ""
"قيد اليومية %s وصل إلى حالة غير صالحة بالنسبة للدفع المرتبط به.\n"
"لضمان الاتساق، يجب أن تشترك قيود اليومية في نفس الشريك."
#. module: employee_custody_request
#: code:addons/odoo/odex25-ensan-project/employee_custody_request/wizard/account_payment_register.py:0
#: code:addons/employee_custody_request/wizard/account_payment_register.py:0
#, python-format
msgid "The selected partner is not linked to any employee using this journal."
msgstr "الشريك المحدد غير مرتبط بأي موظف يستخدم هذه المجلة"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__remaining_amount
msgid "Amount Remaining"
msgstr "المبلغ المتبقي"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__spent_amount
msgid "Amount Spent"
msgstr "المبلغ المنصرف"
#. module: employee_custody_request
#: code:addons/odoo/odex25-ensan-project/employee_custody_request/models/models.py:0
#: code:addons/employee_custody_request/models/models.py:0
#, python-format
msgid ""
"The requested amount (%s) exceeds the maximum allowed for the selected "
"custody type (%s)."
msgstr "المبلغ المطلوب (%s) يتجاوز الحد الأقصى المسموح به لنوع العهد المحدد (%s)."
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_custody_types__name
msgid "Custody Type Name"
msgstr "اسم نوع العهده"
#. module: employee_custody_request
#: model:ir.model.fields,field_description:employee_custody_request.field_custody_types__max_custody_amount
msgid "Maximum Custody Amount"
msgstr "الحد الأقصى"
#. module: employee_custody_request
#: code:addons/odoo/odex25-ensan-project/employee_custody_request/models/account_journal.py:0
#: code:addons/employee_custody_request/models/account_journal.py:0
#, python-format
msgid "You must select an account of type \"Debit\" for the Advances Ledger"
msgstr "يجب اختيار حساب من النوع \"مدين\" لسجل السلف."
#. module: employee_custody_request
#: code:addons/odoo/odex25-ensan-project/employee_custody_request/models/account_journal.py:0
#: code:addons/employee_custody_request/models/account_journal.py:0
#, python-format
msgid "Partner is required when Custody Journal is enabled"
msgstr "يجب تحديد الشريك عند تفعيل دفتر العهد."
#. module: employee_custody_request
#: model:ir.model,name:employee_custody_request.model_custody_types
#: model:ir.model.fields,field_description:employee_custody_request.field_hr_request_pledge__custody_type_id
#: model:ir.ui.menu,name:employee_custody_request.custody_types_menu
msgid "Custody Types"
msgstr "نوع العهده"

View File

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
from . import models
from . import hr_expense
from . import account_journal
from . import types_custody
from . import account_payment

View File

@ -0,0 +1,46 @@
from odoo import models, fields, api,_
from odoo.exceptions import ValidationError
class AccountJournalInherit(models.Model):
_inherit = 'account.journal'
custody_journal = fields.Boolean(
string='Custody Journal',
default=False,
help='Check this box if this journal is used for custody transactions'
)
partner_id = fields.Many2one(
'res.partner',
string='Partner',
help='Partner associated with this journal'
)
@api.constrains('custody_journal', 'partner_id')
def _check_custody_partner(self):
for record in self:
if record.custody_journal and not record.partner_id:
raise ValidationError(
_('Partner is required when Custody Journal is enabled'))
@api.onchange('custody_journal')
def _onchange_custody_journal(self):
if not self.custody_journal:
self.partner_id = False
return {
'domain': {'default_account_id': []}
}
else:
return {
'domain': {
'default_account_id': [('user_type_id.type', '=', 'receivable')]
}
}
@api.constrains('custody_journal', 'default_account_id')
def _check_custody_account_type(self):
for record in self:
if record.custody_journal and record.default_account_id:
if record.default_account_id.user_type_id.type != 'receivable':
raise ValidationError(_('You must select an account of type "Debit" for the Advances Ledger'))

View File

@ -0,0 +1,99 @@
from odoo import models, _
from odoo.exceptions import UserError
class AccountPayment(models.Model):
_inherit = "account.payment"
def _synchronize_from_moves(self, changed_fields):
''' Update the account.payment regarding its related account.move.
Also, check both models are still consistent.
:param changed_fields: A set containing all modified fields on account.move.
'''
if self._context.get('skip_account_move_synchronization'):
return
for pay in self.with_context(skip_account_move_synchronization=True):
# After the migration to 14.0, the journal entry could be shared between the account.payment and the
# account.bank.statement.line. In that case, the synchronization will only be made with the statement line.
if pay.move_id.statement_line_id:
continue
move = pay.move_id
move_vals_to_write = {}
payment_vals_to_write = {}
if 'journal_id' in changed_fields:
if pay.journal_id.type not in ('bank', 'cash'):
raise UserError(_("A payment must always belongs to a bank or cash journal."))
if 'line_ids' in changed_fields:
all_lines = move.line_ids
liquidity_lines, counterpart_lines, writeoff_lines = pay._seek_for_lines()
if len(liquidity_lines) != 1 or len(counterpart_lines) != 1:
raise UserError(_(
"The journal entry %s reached an invalid state relative to its payment.\n"
"To be consistent, the journal entry must always contains:\n"
"- one journal item involving the outstanding payment/receipts account.\n"
"- one journal item involving a receivable/payable account.\n"
"- optional journal items, all sharing the same account.\n\n"
) % move.display_name)
if writeoff_lines and len(writeoff_lines.account_id) != 1:
raise UserError(_(
"The journal entry %s reached an invalid state relative to its payment.\n"
"To be consistent, all the write-off journal items must share the same account."
) % move.display_name)
if any(line.currency_id != all_lines[0].currency_id for line in all_lines):
raise UserError(_(
"The journal entry %s reached an invalid state relative to its payment.\n"
"To be consistent, the journal items must share the same currency."
) % move.display_name)
# if any(line.partner_id != all_lines[0].partner_id for line in all_lines):
# raise UserError(_(
# "The journal entry %s reached an invalid state relative to its payment.\n"
# "To be consistent, the journal items must share the same partner."
# ) % move.display_name)
#✅ Special exception for trade cases
if any(line.partner_id != all_lines[0].partner_id for line in all_lines):
skip_partner_check = (
pay.journal_id.custody_journal and
pay.partner_id and
any(line.partner_id == pay.partner_id for line in all_lines)
)
if not skip_partner_check:
raise UserError(_(
"The journal entry %s reached an invalid state relative to its payment.\n"
"To be consistent, the journal items must share the same partner."
) % move.display_name)
if not pay.is_internal_transfer:
if counterpart_lines.account_id.user_type_id.type == 'receivable':
payment_vals_to_write['partner_type'] = 'customer'
else:
payment_vals_to_write['partner_type'] = 'supplier'
liquidity_amount = liquidity_lines.amount_currency
move_vals_to_write.update({
'currency_id': liquidity_lines.currency_id.id,
'partner_id': liquidity_lines.partner_id.id,
})
payment_vals_to_write.update({
'amount': abs(liquidity_amount),
'currency_id': liquidity_lines.currency_id.id,
'destination_account_id': counterpart_lines.account_id.id,
'partner_id': liquidity_lines.partner_id.id,
})
if liquidity_amount > 0.0:
payment_vals_to_write.update({'payment_type': 'inbound'})
elif liquidity_amount < 0.0:
payment_vals_to_write.update({'payment_type': 'outbound'})
move.write(move._cleanup_write_orm_values(move, move_vals_to_write))
pay.write(move._cleanup_write_orm_values(pay, payment_vals_to_write))

View File

@ -0,0 +1,15 @@
from odoo import models
class HrExpense(models.Model):
_inherit = 'hr.expense'
def _get_expense_account_destination(self):
self.ensure_one()
if self.payment_mode == 'company_account' and self.sheet_id.account_payment_method_id:
account_dest = self.env['account.account']
account_dest = self.sheet_id.account_payment_method_id.payment_account_id.id
else:
return super(HrExpense, self)._get_expense_account_destination()
return account_dest

View File

@ -0,0 +1,414 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, tools, _
import ast
from odoo.exceptions import UserError, ValidationError
from odoo.tools import float_compare, float_is_zero
# class HrEmployee(models.Model):
# _inherit='hr.employee'
# @api.model
# def action_open_bank_balance_in_gl(self):
#
# self.ensure_one()
# action = self.env["ir.actions.actions"]._for_xml_id("odex25_account_reports.action_account_report_general_ledger")
# employee = self.browse(self._context.get('active_id'))
# action['context'] = dict(ast.literal_eval(action['context']), default_filter_accounts=employee.journal_id.default_account_id.code)
#
# return action
class BaseDashboardExtended(models.Model):
_inherit = 'base.dashbord' # Inherit existing dashboard
# One2many reverse of the Many2one in pledges
pledge_ids = fields.One2many(
'hr.request.pledge',
'dashboard_id',
)
class HrRequestPledge(models.Model):
_name = 'hr.request.pledge'
_description = 'Request Pledge'
_rec_name = "code"
_inherit = ['mail.thread', 'mail.activity.mixin']
code = fields.Char()
state = fields.Selection(
[('draft', _('Draft')),
('submit', _('Waiting Payroll Officer')),
('direct_manager', _('Wait HR Department')),
('hr_manager', _('Wait GM Approval')),
('executive_manager', _('Wait Transfer')),
('financial_approve', _('Wait Financial Approval')),
('pay', _('Transferred')), ('refused', _('Refused')),
('closed', _('Loan Suspended'))],
default="draft", tracking=True)
date = fields.Date(required=True)
department_id = fields.Many2one(related='employee_id.department_id', readonly=True, store=True)
from_hr_depart = fields.Boolean()
job_id = fields.Many2one(related='employee_id.job_id', readonly=True)
dashboard_id = fields.Many2one(
'base.dashbord',
index=True
)
is_financial_impact = fields.Boolean(
compute='_compute_is_financial_impact',
store=True
)
custody_type_id = fields.Many2one(
'custody.types',
string='Custody Types',
required=True,
tracking=True
)
journal_id = fields.Many2one(related='custody_type_id.journal_id', readonly=True)
spent_amount = fields.Monetary(
string="Amount Spent",
compute="_compute_spent_amount",
currency_field='currency_id',
store=False
)
employee_id = fields.Many2one('hr.employee', 'Employee',
default=lambda item: item.get_user_id(), index=True)
emp_expect_amount = fields.Float(string='Request Employee Amount')
description = fields.Char("Statement")
currency_id = fields.Many2one(
'res.currency',
string='Currency',
default=lambda self: self.env.company.currency_id
)
remaining_amount = fields.Monetary(
string="Amount Remaining",
compute="_compute_remaining_amount",
store=True,
currency_field='currency_id'
)
@api.depends('spent_amount', 'emp_expect_amount')
def _compute_remaining_amount(self):
for rec in self:
rec.remaining_amount = rec.emp_expect_amount - rec.spent_amount
@api.depends('employee_id', 'journal_id')
def _compute_spent_amount(self):
for rec in self:
rec.spent_amount = 0.0
if not rec.employee_id or not rec.employee_id.user_id or not rec.journal_id:
continue
partner = rec.employee_id.user_id.partner_id
journal = rec.journal_id
move_data = self.env['account.move.line'].read_group(
domain=[
('partner_id', '=', partner.id),
('move_id.state', '=', 'posted'),
('move_id.journal_id', '=', journal.id),
('account_id.user_type_id.type', '=', 'receivable'),
('debit', '>', 0),
],
fields=['debit:sum'],
groupby=[]
)
total_paid = move_data[0]['debit'] if move_data else 0.0
all_requests = self.search([
('employee_id', '=', rec.employee_id.id),
('journal_id', '=', journal.id),
], order='date asc, id asc')
remaining_amount = total_paid
last_index = len(all_requests) - 1
for idx, pledge in enumerate(all_requests):
if remaining_amount <= 0:
pledge.spent_amount = 0.0
elif idx == last_index:
pledge.spent_amount = remaining_amount
remaining_amount = 0
elif remaining_amount >= pledge.emp_expect_amount:
pledge.spent_amount = pledge.emp_expect_amount
remaining_amount -= pledge.emp_expect_amount
else:
pledge.spent_amount = remaining_amount
remaining_amount = 0
@api.constrains('custody_type_id', 'emp_expect_amount')
def _check_custody_amount_limit(self):
for record in self:
if record.custody_type_id and record.emp_expect_amount:
if record.emp_expect_amount > record.custody_type_id.max_custody_amount:
raise ValidationError(_(
"The requested amount (%s) exceeds the maximum allowed for the selected custody type (%s)."
) % (record.emp_expect_amount, record.custody_type_id.max_custody_amount))
@api.depends('dashboard_id.is_financial_impact')
def _compute_is_financial_impact(self):
for record in self:
record.is_financial_impact = record.dashboard_id.is_financial_impact
def get_user_id(self):
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if employee_id:
return employee_id.id
else:
return False
# @api.model
# def default_get(self, fields):
# res = super().default_get(fields)
# res['journal_id'] = False
# return res
@api.constrains('emp_expect_amount')
def _check_positive_emp_expect_amount(self):
for rec in self:
if rec.emp_expect_amount <= 0:
raise ValidationError(
_("Employee expect amount should be bigger than zero!")
)
@api.model
def create(self, values):
# Auto-link dashboard if not provided
if not values.get('dashboard_id'):
dashboard = self.env['base.dashbord'].search([ # Fix typo: 'base.dashboard'
('model_name', '=', self._name)
], limit=1)
if dashboard:
values['dashboard_id'] = dashboard.id
# Generate sequence code (your existing logic)
seq = self.env['ir.sequence'].next_by_code('hr.request.pledge') or '/'
values['code'] = seq # Assign the sequence to the 'code' field
# Create the record
return super(HrRequestPledge, self).create(values)
def submit(self):
self.state = "submit"
def direct_manager(self):
self.state = "direct_manager"
def hr_manager(self):
self.state = "hr_manager"
def executive_manager(self):
self.state = "executive_manager"
def refused(self):
self.state = "refused"
def cancel(self):
self.state = "cancel"
def pay(self):
if not self.journal_id:
raise ValidationError(_('Please set the journal for this employee.'))
employee_partner = self.employee_id.user_id.partner_id
if not employee_partner:
raise ValidationError(_('Employee must have a related partner.'))
payment_vals = {
'payment_type': 'inbound',
'partner_type': 'supplier',
'is_internal_transfer': True,
'amount': self.emp_expect_amount,
'journal_id': self.journal_id.id,
'date': fields.datetime.today(),
'ref': self.description,
'hr_request_pledge': self.id,
}
payment = self.env['account.payment'].create(payment_vals)
employee_partner = self.employee_id.user_id.partner_id
if employee_partner:
for line in payment.move_id.line_ids:
if line.debit > 0:
line.partner_id = employee_partner.id
break
self.state = "pay"
return payment
def financialApproval(self):
self.state="financial_approve"
def action_account_payment_budget_pledge(self):
budget_account_payment = self.env['account.payment'].search(
[('hr_request_pledge', '=', self.id)],
limit=1
)
if budget_account_payment:
return {
'type': 'ir.actions.act_window',
'name': 'Achieving Budget',
'res_model': 'account.payment',
'res_id': budget_account_payment.id,
'view_mode': 'form',
'target': 'current',
}
class SmartButtonReturnRequestPledge(models.Model):
_inherit = "account.payment"
hr_request_pledge = fields.Many2one('hr.request.pledge')
def action_go_to_hr_request_pledge(self):
pledge_record = self.env['hr.request.pledge'].search(
[('id', '=', self.hr_request_pledge.id)],
limit=1
)
if pledge_record:
return {
'type': 'ir.actions.act_window',
'name': 'HR Request Pledge',
'res_model': 'hr.request.pledge',
'res_id': pledge_record.id,
'view_mode': 'form',
'view_type': 'form',
'target': 'current',
}
class EmployeeJournal(models.Model):
_inherit = "hr.employee"
journal_id = fields.Many2one('account.journal', domain="[('type', '=', 'cash')]")
department = fields.Many2one('hr.department', string="Department")
department_name = fields.Char(
string='Department Name',
related='department_id.name',
readonly=True,
store=True,
)
class HrExpenseSheetPledge(models.Model):
_inherit = "hr.expense.sheet"
bank_journal_id = fields.Many2one(default=False)
available_account_payment_method_ids = fields.Many2many('account.payment.method.line', compute="_compute_available_account_payment_method_ids")
account_payment_method_id = fields.Many2one('account.payment.method.line', default=False)
payment_account_id = fields.Many2one(
comodel_name='account.account',
check_company=True,
copy=False,
ondelete='restrict', )
@api.depends('bank_journal_id')
def _compute_available_account_payment_method_ids(self):
AccountPaymentMethodLine = self.env['account.payment.method.line'].sudo()
for rec in self:
rec.available_account_payment_method_ids = AccountPaymentMethodLine.search([('id', 'in', self.bank_journal_id.outbound_payment_method_line_ids.ids)])
@api.onchange('bank_journal_id')
def _onchange_bank_journal_id(self):
self.account_payment_method_id = False
def action_sheet_move_create(self):
for sheet in self:
if sheet.payment_mode == 'company_account' and not (sheet.bank_journal_id and sheet.account_payment_method_id):
raise UserError(
_("Please enter Bank Journal and Payment Method!")
)
return super(HrExpenseSheetPledge, self).action_sheet_move_create()
# class AchievingBudgetAchievingBudget(models.Model):
# _inherit = "hr.expense"
# action_budget_id = fields.Many2one('account.tax', 'analytic')
# def _create_sheet_from_expenses(self):
# if any(expense.state != 'draft' or expense.sheet_id for expense in self):
# raise UserError(_("You cannot report twice the same line!"))
# if len(self.mapped('employee_id')) != 1:
# raise UserError(_("You cannot report expenses for different employees in the same report."))
# if any(not expense.product_id for expense in self):
# raise UserError(_("You can not create report without product."))
# if len(self.company_id) != 1:
# raise UserError(_("You cannot report expenses for different companies in the same report."))
# todo = self.filtered(lambda x: x.payment_mode=='own_account') or self.filtered(lambda x: x.payment_mode=='company_account')
# sheet = self.env['hr.expense.sheet'].create({
# 'company_id': self.company_id.id,
# 'employee_id': self[0].employee_id.id,
# 'name': todo[0].name if len(todo) == 1 else '',
# 'expense_line_ids': [(6, 0, todo.ids)],
# })
# # sheet.write({
# # 'account_payment_method_id': sheet.bank_journal_id.outbound_payment_method_line_ids[:1]
# # })
# return sheet
# def action_achieving_budget_pledge(self):
# achieving_budget_record = self.env['budget.confirmation'].search(
# [('expense_id', '=', self.id)],
# limit=1
# )
# if achieving_budget_record:
# return {
# 'type': 'ir.actions.act_window',
# 'name': 'Achieving Budget',
# 'res_model': 'budget.confirmation',
# 'res_id': achieving_budget_record.id,
# 'view_mode': 'form',
# 'target': 'current',
# }
class MoveLine(models.Model):
_inherit = 'account.move.line'
@api.model
def _employee_custody_lines_view(self):
employee = self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
if not employee:
raise UserError("There is no employee associated with this user.")
account_id = employee.journal_id.default_account_id.id
if not account_id:
raise UserError("The employee does not have an associated journal or default account.")
action = {
'type': 'ir.actions.act_window',
'name': 'Employee Account Report',
'res_model': 'account.move.line',
'view_mode': 'tree',
'view_id': self.env.ref('employee_custody_request.view_account_move_line_tree_custom').id,
'domain': [('account_id', '=', account_id)],
'context': {
},
'target': 'current',
}
return action

View File

@ -0,0 +1,34 @@
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
class CustodyTypes(models.Model):
_name = 'custody.types'
_description = 'Custody Types'
_rec_name = 'name'
name = fields.Char(
string='Custody Type Name',
required=True,
help='Name of the custody type'
)
journal_id = fields.Many2one(
'account.journal',
string='Journal',
required=True,
domain="[('custody_journal', '=', True)]",
help='Select the journal associated with this type of custody'
)
max_custody_amount = fields.Float(
string='Maximum Custody Amount',
digits=(16, 2),
required=True,
help='The maximum amount allowed for this type of custody'
)
@api.constrains('max_custody_amount')
def _check_max_custody_amount(self):
for record in self:
if record.max_custody_amount <= 0:
raise ValidationError(_('The maximum custody amount must be greater than zero.'))

View File

@ -0,0 +1,15 @@
<odoo>
<!-- <record id="action_report_property_xls" model="ir.actions.server">-->
<!-- <field name="name">General Ledger</field>-->
<!-- <field name="model_id" ref="model_hr_employee"/>-->
<!-- <field name="binding_model_id" ref="model_hr_employee"/>-->
<!-- <field name="binding_view_types">form</field>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">-->
<!-- action = records.action_open_bank_balance_in_gl()-->
<!-- </field>-->
<!-- </record>-->
</odoo>

View File

@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hr_request_pledge_user,access_hr_request_pledge_user,model_hr_request_pledge,,1,1,1,1
access_custody_types_manager,custody.types.manager,model_custody_types,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_hr_request_pledge_user access_hr_request_pledge_user model_hr_request_pledge 1 1 1 1
3 access_custody_types_manager custody.types.manager model_custody_types 1 1 1 1

View File

@ -0,0 +1,56 @@
<odoo>
<record id="group_all_records_access" model="res.groups">
<field name="name">Access All Records</field>
</record>
<record id="sale_order_personal_rule_Records_request" model="ir.rule">
<field name="name">Personal Orders</field>
<field ref="model_hr_request_pledge" name="model_id"/>
<field name="domain_force">[('employee_id.user_id', '=', user.id)]</field>
<field name="groups" eval="[(4, ref('employee_custody_request.group_all_records_access'))]"/>
</record>
<record model="ir.module.category" id="hr_general_ledger">
<field name="name">General Ledger</field>
</record>
<record id="group_general_ledger_manger" model="res.groups">
<field name="name">General Ledger Manager</field>
<field name="category_id" ref="employee_custody_request.hr_general_ledger"/>
</record>
<record model="ir.module.category" id="module_category_general_ledger_custom">
<field name="name">General Ledger</field>
<field name="description">User access level for this module</field>
<field name="sequence">60</field>
</record>
<record id="group_hr_user" model="res.groups">
<field name="name">Officer</field>
<field name="category_id" ref="employee_custody_request.module_category_general_ledger_custom"/>
</record>
<record id="group_loan_manager" model="res.groups">
<field name="name">Loan Manager</field>
<field name="category_id" ref="employee_custody_request.module_category_general_ledger_custom"/>
</record>
<record id="group_hr_manager" model="res.groups">
<field name="name">Administrator</field>
<field name="category_id" ref="employee_custody_request.module_category_general_ledger_custom"/>
</record>
<record id="group_general_manager" model="res.groups">
<field name="name">General Manager</field>
<field name="category_id" ref="employee_custody_request.module_category_general_ledger_custom"/>
</record>
<record id="group_account_manager" model="res.groups">
<field name="name">Accounting Manager</field>
<field name="category_id" ref="employee_custody_request.module_category_general_ledger_custom"/>
</record>
<record id="group_employee_custody_report" model="res.groups">
<field name="name">Employee Custody Report</field>
<field name="category_id" ref="employee_custody_request.module_category_general_ledger_custom"/>
</record>
</odoo>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- وراثة نموذج الدفتر اليومية -->
<record id="view_account_journal_form_inherit" model="ir.ui.view">
<field name="name">account.journal.form.inherit</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.view_account_journal_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='type']" position="after">
<field name="custody_journal"/>
<field name="partner_id"
attrs="{'invisible': [('custody_journal', '=', False)],
'required': [('custody_journal', '=', True)]}"/>
</xpath>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,24 @@
<odoo>
<data>
<!--
<template id="listing">
<ul>
<li t-foreach="objects" t-as="object">
<a t-attf-href="#{ root }/objects/#{ object.id }">
<t t-esc="object.display_name"/>
</a>
</li>
</ul>
</template>
<template id="object">
<h1><t t-esc="object.display_name"/></h1>
<dl>
<t t-foreach="object._fields" t-as="field">
<dt><t t-esc="field"/></dt>
<dd><t t-esc="object[field]"/></dd>
</t>
</dl>
</template>
-->
</data>
</odoo>

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Tree View -->
<record id="custody_types_tree_view" model="ir.ui.view">
<field name="name">custody.types.tree</field>
<field name="model">custody.types</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="journal_id"/>
<field name="max_custody_amount"/>
</tree>
</field>
</record>
<!-- Form View -->
<record id="custody_types_form_view" model="ir.ui.view">
<field name="name">custody.types.form</field>
<field name="model">custody.types</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="name"/>
</group>
<group>
<field name="journal_id"/>
<field name="max_custody_amount"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="custody_types_action" model="ir.actions.act_window">
<field name="name">أنواع العهد</field>
<field name="res_model">custody.types</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
إنشاء نوع عهد جديد
</p>
<p>
قم بإنشاء وإدارة أنواع العهد المختلفة
</p>
</field>
</record>
<menuitem
id="custody_types_menu"
parent="system_dashboard_classic.base_dashboard_root"
name="Custody Types"
action="custody_types_action"
sequence="-6" />
</data>
</odoo>

View File

@ -0,0 +1,193 @@
<odoo>
<data>
<!-- <record id="hr_view_budget_form_inherit" model="ir.ui.view">
<field name="name">hr.expense.budget.form</field>
<field name="model">hr.expense</field>
<field name="inherit_id" ref="hr_expense.hr_expense_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='button_box']" position="inside">
<button name="action_achieving_budget_pledge" type="object" string="Go to budget confirmation"
class="oe_stat_button" icon="fa-bars"
attrs="{'invisible': [('state', '=', 'draft')]}"/>
</xpath>
</field>
</record> -->
<record id="view_hr_expense_sheet_form_inherit_pledge" model="ir.ui.view">
<field name="name">view.hr.expense.sheet.form.inherit.pledge</field>
<field name="model">hr.expense.sheet</field>
<field name="inherit_id" ref="hr_expense.view_hr_expense_sheet_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='other_info']/group/group/field[@name='bank_journal_id']" position="after">
<field name="available_account_payment_method_ids" invisible="1"/>
<field name="account_payment_method_id" domain="[('id', 'in', available_account_payment_method_ids)]"/>
</xpath>
</field>
</record>
<record id="view_employee_journal_form_inherit" model="ir.ui.view">
<field name="name">hr.employee.journal.form.inherit</field>
<field name="model">hr.employee</field>
<field name="inherit_id" ref="hr.view_employee_form"/>
<field name="arch" type="xml">
<xpath expr="//notebook/page[@name='attachments']" position="after">
<page name="journal_information" string="Journal Information">
<group>
<field name="journal_id"/>
</group>
</page>
</xpath>
</field>
</record>
<record id="view_account_payment_form_inherit" model="ir.ui.view">
<field name="name">account.payment.form.inherit</field>
<field name="model">account.payment</field>
<field name="inherit_id" ref="account.view_account_payment_form"/>
<field name="arch" type="xml">
<!-- <xpath expr="//div[@name='button_box']" position="inside">
<button name="action_go_to_hr_request_pledge" type="object" string="Go to HR Request Pledge"
groups="account_budget_custom.group_department_manager_budget"
class="oe_stat_button" icon="fa-bars"
attrs="{'invisible': [('hr_request_pledge', '=', False)]}"/>
</xpath> -->
<xpath expr="//field[@name='payment_type']" position="after">
<field name="hr_request_pledge" invisible="1"/>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="job_request_form_pledge_view">
<field name="name">Employee pledge form</field>
<field name="model">hr.request.pledge</field>
<field name="arch" type="xml">
<form>
<header>
<button name="submit" string="Submit" class="oe_highlight" type="object"
states="draft" groups="employee_custody_request.group_hr_user"/>
<button name="direct_manager" string="Payroll Officer Approve" class="oe_highlight"
type="object" states="submit" groups="employee_custody_request.group_loan_manager"/>
<button name="refused" string="Refuse" states="submit" type="object"
class="oe_highlight" groups="employee_custody_request.group_loan_manager"/>
<button name="hr_manager" string="HR Manager Approve" class="oe_highlight" type="object"
states="direct_manager" groups="employee_custody_request.group_hr_manager"/>
<button name="refused" string="Refuse" states="direct_manager" type="object"
class="oe_highlight" groups="employee_custody_request.group_hr_manager"/>
<button name="executive_manager" string="GM Manager Approve" class="oe_highlight" type="object"
states="hr_manager" groups="employee_custody_request.group_general_manager"/>
<button name="refused" string="Refuse" states="hr_manager" type="object"
class="oe_highlight" groups="employee_custody_request.group_general_manager"/>
<button name="financialApproval" string="Financial Approval"
class="oe_highlight" type="object"
groups="employee_custody_request.group_account_manager"
attrs="{'invisible': ['|',
('is_financial_impact', '!=', True),
('state', '!=', 'executive_manager')]}"/>
<button name="pay" string="Transfer"
class="oe_highlight" type="object"
groups="employee_custody_request.group_account_manager"
attrs="{'invisible': ['|',
('is_financial_impact', '!=', False),
('state', '!=', 'executive_manager')]}"/>
<field name="state" widget="statusbar"
statusbar_visible="draft,submit,direct_manager,hr_manager,executive_manager,pay,financial_approve,refused"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="action_account_payment_budget_pledge" type="object"
string="Go to account payment"
class="oe_stat_button" icon="fa-bars"
attrs="{'invisible': [('state', '!=', 'pay')]}"/>
</div>
<group>
<group>
<field name="is_financial_impact" invisible="1"/>
<field name="code" string="Code" readonly="1"/>
<field name="from_hr_depart" string="Another Employee"
attrs="{'readonly':[('state','!=','draft')]}"/>
<field name="employee_id" string="Employee Name"
attrs="{'readonly':['|',('state','!=','draft'),('from_hr_depart','=',False)],'required':True}"/>
<field name="date"/>
</group>
<group>
<field name="emp_expect_amount"/>
<field name="custody_type_id"/>
<field name="journal_id" attrs="{'invisible': [('id', '!=', 0)]}"/>
<field name="department_id"/>
<field name="job_id"/>
<field name="description"/>
<field name="spent_amount"/>
<field name="remaining_amount"/>
</group>
</group>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="job_request_tree_view">
<field name="name">job_request_pledge_tree_view</field>
<field name="model">hr.request.pledge</field>
<field name="arch" type="xml">
<tree>
<field name="code"/>
<!-- <field name="from_hr_depart"/>-->
<!-- <field name="date"/>-->
<field name="employee_id"/>
<field name="emp_expect_amount"/>
</tree>
</field>
</record>
<record id="view_account_move_line_tree_custom" model="ir.ui.view">
<field name="name">account.move.line.tree.custom</field>
<field name="model">account.move.line</field>
<field name="arch" type="xml">
<tree string="Account Move Lines" create="false">
<field name="date"/>
<field name="name"/>
<field name="debit" sum="Total"/>
<field name="credit" sum="Total"/>
<field name="balance" sum="Total"/>
</tree>
</field>
</record>
<record id="action_employee_custody_report" model="ir.actions.server">
<field name="name">Employee Account</field>
<field name="model_id" ref="model_account_move_line"/>
<field name="state">code</field>
<field name="code">action = env['account.move.line']._employee_custody_lines_view()</field>
</record>
<record model="ir.actions.act_window" id="job_request_action_pledge">
<field name="name">Job Request pledge</field>
<field name="res_model">hr.request.pledge</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="job_request_pledge" name="Request pledge"
action="job_request_action_pledge" parent="hr_expense.menu_hr_expense_my_expenses" sequence="10"
groups="employee_custody_request.group_general_ledger_manger"/>
<menuitem id="employee_custody_report_menu" name="Employee Account Report"
action="action_employee_custody_report" parent="hr_expense.menu_hr_expense_report" sequence="20"
groups="employee_custody_request.group_employee_custody_report"/>
</data>
</odoo>

View File

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

View File

@ -0,0 +1,185 @@
from odoo import models, fields, api,_
import logging
_logger = logging.getLogger(__name__)
from odoo.exceptions import UserError
class AccountPaymentRegister(models.TransientModel):
_inherit = 'account.payment.register'
is_custody_journal = fields.Boolean(
string="Is Custody Journal",
compute="_compute_is_custody_journal"
)
custody_partner_id = fields.Many2one(
'res.partner',
string="Custody Partner"
)
@api.onchange('journal_id')
def _compute_is_custody_journal(self):
for rec in self:
rec.is_custody_journal = rec.journal_id.custody_journal if rec.journal_id else False
if not rec.is_custody_journal:
rec.custody_partner_id = False
return {
'domain': {
'custody_partner_id': rec._get_custody_partner_domain()
}
}
def _get_custody_partner_domain(self):
"""Create domain for partners based on the selected journal and positive remaining_amount"""
if not self.journal_id or not self.is_custody_journal:
return [('id', '=', False)]
pledge_requests = self.env['hr.request.pledge'].search([
('journal_id', '=', self.journal_id.id),
('remaining_amount', '>', 0),
])
employee_ids = pledge_requests.mapped('employee_id')
partner_ids = []
for employee in employee_ids:
if employee.user_id and employee.user_id.partner_id:
partner_ids.append(employee.user_id.partner_id.id)
return [('id', 'in', partner_ids)] if partner_ids else [('id', '=', False)]
@api.onchange('custody_partner_id')
def _onchange_custody_partner_id(self):
if self.custody_partner_id and self.journal_id:
valid_partners = self._get_custody_partner_domain()
if valid_partners and ('id', 'in', valid_partners[0][2]) and self.custody_partner_id.id not in \
valid_partners[0][2]:
return {
'warning': {
'title': _('Warning'),
'message': _('The selected partner is not linked to any employee using this journal.')
}
}
# def _create_payments(self):
# payments = super()._create_payments()
# print("منؤبء")
# if self.is_custody_journal and self.custody_partner_id:
# for payment in payments:
# for line in payment.move_id.line_ids:
# _logger.info("Line account: %s, destination account: %s", line.account_id.id,
# payment.destination_account_id.id)
# if line.account_id.id == payment.destination_account_id.id:
# _logger.info("Updating partner_id of line %s to %s", line.id, self.custody_partner_id.id)
# line.write({'partner_id': self.custody_partner_id.id})
# return payments
def _create_payments(self):
self.ensure_one()
active_ids = self.env.context.get('active_ids')
if active_ids:
invoice_payment = self.env['account.payment'].search([('state', '=', 'draft')]).filtered(
lambda r: set(active_ids) & set(r.invoice_rec_ids.ids))
if invoice_payment:
raise UserError(
_('You can not create payment for this invoice because there is a draft payment for it'))
batches = self._get_batches()
edit_mode = self.can_edit_wizard and (len(batches[0]['lines']) == 1 or self.group_payment)
to_process = []
if edit_mode:
payment_vals = self._create_payment_vals_from_wizard()
to_process.append({
'create_vals': payment_vals,
'to_reconcile': batches[0]['lines'],
'batch': batches[0],
})
else:
if not self.group_payment:
new_batches = []
for batch_result in batches:
for line in batch_result['lines']:
new_batches.append({
**batch_result,
'lines': line,
})
batches = new_batches
for batch_result in batches:
to_process.append({
'create_vals': self._create_payment_vals_from_batch(batch_result),
'to_reconcile': batch_result['lines'],
'batch': batch_result,
})
payments = self._init_payments(to_process, edit_mode=edit_mode)
process_final = [item for item in to_process if item['create_vals']['payment_type'] != 'outbound']
self._post_payments(process_final, edit_mode=edit_mode)
self._reconcile_payments(process_final, edit_mode=edit_mode)
for payment in payments:
if payment.payment_type == 'outbound':
payment.invoice_rec_ids = [(4, active_id) for active_id in active_ids]
payment.action_cancel()
payment.action_draft()
for line in payment.move_id.line_ids:
if payment.is_internal_transfer:
if payment.payment_type == 'outbound':
liquidity_line_name = _('Transfer from %s', payment.journal_id.name)
else:
liquidity_line_name = _('Transfer to %s', payment.journal_id.name)
else:
liquidity_line_name = payment.payment_reference
payment_display_name = payment._prepare_payment_display_name()
default_line_name = self._get_payment_line_name(
_("Internal Transfer") if payment.is_internal_transfer else payment_display_name[
'%s-%s' % (payment.payment_type, payment.partner_type)],
payment.amount,
payment.currency_id,
payment.date,
partner_or_name=payment.invoice_purpose or payment.partner_id,
)
if line.account_id.id in [payment.destination_account_id.id]:
line.name = liquidity_line_name or default_line_name
if hasattr(self, 'is_custody_journal') and self.is_custody_journal and hasattr(self,
'custody_partner_id') and self.custody_partner_id:
print(f"تطبيق منطق العهد للدفع {payment.name}")
for line in payment.move_id.line_ids:
if (line.account_id.user_type_id.type == 'receivable' and line.debit > 0):
print(f"تحديث الشريك للخط {line.id} إلى {self.custody_partner_id.name}")
line.write({'partner_id': self.custody_partner_id.id})
return payments
def action_create_payments(self):
# Call the original method to create payments
payments = self._create_payments()
# Update `move_id` values to include `takaful_sponsorship_id`
if self.is_refund_sponsorship:
for payment in payments:
if payment.move_id: # Ensure the payment has a move_id
payment.move_id.takaful_sponsorship_id = self.takaful_sponsorship_id.id
# Prepare the action for redirection
action = {
'name': _('Payments'),
'type': 'ir.actions.act_window',
'res_model': 'account.payment',
'context': {'create': False},
}
if len(payments) == 1:
action.update({
'view_mode': 'form',
'res_id': payments.id,
})
else:
action.update({
'view_mode': 'tree,form',
'domain': [('id', 'in', payments.ids)],
})
return action

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_account_payment_register_form_pledge" model="ir.ui.view">
<field name="name">account.payment.register.form</field>
<field name="model">account.payment.register</field>
<field name="inherit_id" ref="account.view_account_payment_register_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='journal_id']" position="after">
<field name="is_custody_journal" invisible="1"/>
<field name="custody_partner_id" attrs="{'invisible': [('is_custody_journal', '=', False)]}"/>
</xpath>
</field>
</record>
</data>
</odoo>