[ADD] odex25_takaful: Add new branch
This commit is contained in:
parent
e5e21ddc65
commit
c64c7556e1
|
|
@ -0,0 +1 @@
|
|||
from . import models
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
'name': 'Ensan Sale Management Takaful',
|
||||
'version': '1.0',
|
||||
'description': 'Bridging Takaful and Sale Management',
|
||||
'summary': 'Bridging Takaful and Sale Management',
|
||||
'author': 'Expert Co. Ltd.',
|
||||
'website': 'http://www.exp-sa.com',
|
||||
'license': 'LGPL-3',
|
||||
'category': 'Odex25-Ens',
|
||||
'depends': [
|
||||
'ensan_sale_management',
|
||||
'odex_takaful',
|
||||
],
|
||||
'data': [
|
||||
'views/product_template_views.xml',
|
||||
],
|
||||
'auto_install': True,
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
from . import product
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
from odoo import models
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
def _compute_fixed_value(self):
|
||||
for rec in self:
|
||||
rec.fixed_value = rec.donation_type == 'Fixed Amount'
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="product_template_inherit_form">
|
||||
<field name="name">product.template.form.inherit</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="ensan_sale_management.product_template_inherit_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="donation_type" position="after">
|
||||
<field name="donation_category" />
|
||||
<field name="sponsorship_duration" attrs="{'invisible': [('donation_category','!=','sponsorship')], 'required': [('donation_category','=','sponsorship')]}" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,354 @@
|
|||
# مراجعة شاملة لموديول Odex Takaful System
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
**اسم الموديول:** Odex Takaful System
|
||||
**الإصدار:** 11.0
|
||||
**الفئة:** Odex25-Takaful/Odex25-Takaful
|
||||
**المؤلف:** Expert Co. Ltd.
|
||||
**الموقع:** http://www.exp-sa.com
|
||||
**الملخص:** موديول لإدارة نظام التكافل (الكفالة والمساهمات والتبرعات)
|
||||
|
||||
## الاعتماديات (Dependencies)
|
||||
|
||||
- `base`
|
||||
- `takaful_core`
|
||||
- `odex_takaful_base`
|
||||
- `odex_benefit`
|
||||
- `account`
|
||||
- `phone_validation`
|
||||
|
||||
## الهيكل العام للموديول
|
||||
|
||||
### 1. النماذج (Models) - 26 ملف
|
||||
|
||||
#### النماذج الرئيسية:
|
||||
|
||||
1. **`takaful.sponsorship`** - نموذج الكفالة الرئيسي
|
||||
- إدارة الكفالات (أيتام/أرامل)
|
||||
- أنواع الكفالة: فردية/جماعية، مؤقتة/دائمة
|
||||
- حالات الكفالة: draft, confirmed, wait_pay, paid, canceled, closed, etc.
|
||||
- إدارة المدفوعات والاسترداد
|
||||
- ربط مع الحسابات المالية
|
||||
|
||||
2. **`donations.details.lines`** - تفاصيل التبرعات والكفالات
|
||||
- إدارة بنود التبرعات والكفالات
|
||||
- دعم التبرعات المباشرة (Direct Debit)
|
||||
- جدولة المدفوعات الشهرية
|
||||
- إدارة الاستبدال والتمديد
|
||||
|
||||
3. **`payment.details.lines`** - تفاصيل المدفوعات
|
||||
- تسجيل المدفوعات
|
||||
- ربط مع الحسابات المالية
|
||||
- دعم طرق الدفع المختلفة (نقد، تحويل بنكي، سحب مباشر)
|
||||
|
||||
4. **`sponsorship.scheduling.line`** - جدولة المدفوعات
|
||||
- جدولة المدفوعات الشهرية
|
||||
- معالجة المدفوعات التلقائية
|
||||
- تتبع حالة كل دفعة
|
||||
|
||||
5. **`month.payment`** - المدفوعات الشهرية للمستفيدين
|
||||
- تجميع المدفوعات الشهرية
|
||||
- إنشاء قيود مالية للمستفيدين
|
||||
|
||||
6. **`takaful.sponsor.operation`** - عمليات الكافل
|
||||
- تتبع عمليات الكافل (كفالة، مساهمة، هدية)
|
||||
|
||||
7. **`sponsorship.payment`** - مدفوعات الكفالة
|
||||
- إدارة مدفوعات الكفالة
|
||||
- ربط مع الفواتير
|
||||
|
||||
8. **`sponsorship.cancellation`** - إلغاء الكفالة
|
||||
- إدارة عمليات الإلغاء
|
||||
- حساب المتأخرات
|
||||
|
||||
9. **`replacement.process`** - عملية الاستبدال
|
||||
- استبدال المستفيدين
|
||||
- تتبع عمليات الاستبدال
|
||||
|
||||
10. **`takaful.contribution`** - المساهمات المالية
|
||||
- إدارة المساهمات المالية
|
||||
- ربط مع الحاجات
|
||||
|
||||
11. **`takaful.grant.benefit`** - تمديد نموذج المستفيدين
|
||||
- حساب قيمة الكفالة
|
||||
- تتبع الكفالات النشطة
|
||||
|
||||
12. **`takaful.push.notification`** - الإشعارات
|
||||
- إرسال الإشعارات (SMS, Email, WhatsApp)
|
||||
|
||||
13. **`takaful.notification`** - إعدادات الإشعارات
|
||||
- أنواع الإشعارات المختلفة
|
||||
- ربط مع حالات الكفالة
|
||||
|
||||
14. **`takaful.payment.method`** - طرق الدفع
|
||||
- إدارة طرق الدفع المختلفة
|
||||
|
||||
15. **`donation.extension.history`** - سجل التمديدات
|
||||
- تتبع تمديدات التبرعات
|
||||
|
||||
16. **`donation.replacement.log`** - سجل الاستبدالات
|
||||
- تتبع استبدالات المستفيدين
|
||||
|
||||
17. **`refund.details.lines`** - تفاصيل الاسترداد
|
||||
- إدارة عمليات الاسترداد
|
||||
|
||||
18. **`sponsorship.benefit.arrears`** - المتأخرات
|
||||
- حساب المتأخرات للمستفيدين
|
||||
|
||||
#### النماذج المساعدة:
|
||||
|
||||
- `replacement.reasons` - أسباب الاستبدال
|
||||
- `sponsorship.reason.stop` - أسباب إيقاف الكفالة
|
||||
- `refund.reasons` - أسباب الاسترداد
|
||||
- `sponsorship.states` - حالات الكفالة
|
||||
- `preferred.communication` - طرق التواصل المفضلة
|
||||
- `takaful.conf` - إعدادات التكافل
|
||||
- `donations.items` - عناصر التبرعات
|
||||
- `points.of.sale.custom` - نقاط البيع
|
||||
|
||||
### 2. الويزاردات (Wizards) - 10 ملفات
|
||||
|
||||
1. **`account.payment.register`** - تسجيل المدفوعات
|
||||
2. **`add.details.wiz`** - إضافة التفاصيل
|
||||
3. **`benefit.month.payment.wiz`** - مدفوعات المستفيدين الشهرية
|
||||
4. **`donation.extension.wizard`** - تمديد التبرعات
|
||||
5. **`orphan.replacement.wizard`** - استبدال الأيتام
|
||||
6. **`refund.wiz`** - استرداد المدفوعات
|
||||
7. **`replace.sponsor.wizard`** - استبدال الكافل
|
||||
8. **`takaful.reports.wizards`** - تقارير التكافل
|
||||
9. **`transfer.deduction.wizard`** - تحويل الخصومات
|
||||
|
||||
### 3. التقارير (Reports) - 7 ملفات
|
||||
|
||||
1. **`month_payment_report.py`** - تقرير المدفوعات الشهرية
|
||||
2. **`payment_details_lines_reports.xml`** - تقارير تفاصيل المدفوعات
|
||||
3. **`takaful_reports.py`** - تقارير التكافل العامة
|
||||
4. **`transfer_deduction_report.xml`** - تقرير تحويل الخصومات
|
||||
|
||||
### 4. البيانات (Data) - 7 ملفات
|
||||
|
||||
1. **`sequence_data.xml`** - التسلسلات
|
||||
2. **`scheduled_actions.xml`** - الإجراءات المجدولة
|
||||
3. **`takaful_notification_mail_template.xml`** - قوالب البريد الإلكتروني
|
||||
4. **`sponsorship_states_data.xml`** - حالات الكفالة
|
||||
5. **`sponsorship_notification_data.xml`** - إعدادات الإشعارات
|
||||
6. **`message_template_data.xml`** - قوالب الرسائل
|
||||
7. **`server_actions.xml`** - إجراءات الخادم
|
||||
|
||||
### 5. الأمان (Security)
|
||||
|
||||
- **`security_data.xml`** - مجموعات الأمان
|
||||
- **`ir.model.access.csv`** - صلاحيات الوصول
|
||||
|
||||
### 6. الواجهات (Views) - 33 ملف
|
||||
|
||||
- واجهات الكفالات
|
||||
- واجهات المدفوعات
|
||||
- واجهات التبرعات
|
||||
- واجهات التقارير
|
||||
- واجهات الإشعارات
|
||||
|
||||
### 7. الإجراءات المجدولة (Scheduled Actions)
|
||||
|
||||
1. **فحص تاريخ انتهاء الكفالة وإرسال رسائل WhatsApp**
|
||||
- التكرار: يومي
|
||||
- الوقت: 04:00
|
||||
|
||||
2. **إدارة سير عمل الكفالة يومياً**
|
||||
- التكرار: يومي
|
||||
- الوقت: 04:00
|
||||
|
||||
3. **إنشاء فواتير الكفالات شهرياً**
|
||||
- التكرار: شهري
|
||||
- الوقت: 02:00 في اليوم الأول من الشهر
|
||||
|
||||
4. **معالجة المدفوعات المجدولة يومياً**
|
||||
- التكرار: يومي
|
||||
- الوقت: 03:00
|
||||
|
||||
5. **إرسال تذكيرات SMS لانتهاء السحب المباشر**
|
||||
- التكرار: يومي
|
||||
- الوقت: 05:00
|
||||
|
||||
## الوظائف الرئيسية
|
||||
|
||||
### 1. إدارة الكفالات
|
||||
|
||||
#### إنشاء كفالة جديدة:
|
||||
- اختيار الكافل (مسجل، جديد، غير معروف)
|
||||
- اختيار المستفيد (فردي/جماعي)
|
||||
- اختيار نوع المستفيد (أيتام/أرامل)
|
||||
- تحديد مدة الكفالة (مؤقتة/دائمة)
|
||||
- إضافة بنود التبرعات/الكفالات
|
||||
- تحديد طريقة الدفع
|
||||
|
||||
#### حالات الكفالة:
|
||||
- **draft**: مسودة
|
||||
- **confirmed**: مؤكدة
|
||||
- **wait_pay**: انتظار الدفع
|
||||
- **paid**: مدفوعة
|
||||
- **partial_refund**: استرداد جزئي
|
||||
- **fully_refund**: استرداد كامل
|
||||
- **approve_refund**: موافقة على الاسترداد
|
||||
- **under_refund**: تحت إجراءات الاسترداد
|
||||
- **under_replacement**: تحت الاستبدال
|
||||
- **replacement_done**: تم الاستبدال
|
||||
- **canceled**: ملغاة
|
||||
- **closed**: مغلقة
|
||||
|
||||
### 2. إدارة المدفوعات
|
||||
|
||||
#### أنواع المدفوعات:
|
||||
- نقد (Cash)
|
||||
- بطاقة (Card)
|
||||
- شيك (Check)
|
||||
- تحويل بنكي (Bank Transfer)
|
||||
- سحب مباشر (Direct Debit)
|
||||
|
||||
#### تسجيل المدفوعات:
|
||||
- ربط مع الفواتير
|
||||
- إنشاء قيود مالية تلقائياً
|
||||
- تتبع حالة الدفع
|
||||
|
||||
### 3. جدولة المدفوعات
|
||||
|
||||
- جدولة المدفوعات الشهرية للكفالات المؤقتة
|
||||
- معالجة تلقائية للمدفوعات المجدولة
|
||||
- تتبع حالة كل دفعة
|
||||
|
||||
### 4. الاستبدال
|
||||
|
||||
- استبدال المستفيدين
|
||||
- تتبع عمليات الاستبدال
|
||||
- إرسال إشعارات للكافل
|
||||
|
||||
### 5. التمديد
|
||||
|
||||
- تمديد التبرعات/الكفالات
|
||||
- تتبع تاريخ التمديدات
|
||||
- إرسال تذكيرات قبل الانتهاء
|
||||
|
||||
### 6. الاسترداد
|
||||
|
||||
- استرداد كامل أو جزئي
|
||||
- إنشاء فواتير استرداد
|
||||
- تتبع عمليات الاسترداد
|
||||
|
||||
### 7. الإشعارات
|
||||
|
||||
#### أنواع الإشعارات:
|
||||
- إنشاء كفالة
|
||||
- قبل انتهاء الكفالة
|
||||
- بعد انتهاء الكفالة
|
||||
- إلغاء الكفالة
|
||||
- استرداد كامل/جزئي
|
||||
- استبدال يتيم/أرملة
|
||||
- دفع كامل/جزئي
|
||||
- قبل الإلغاء
|
||||
|
||||
#### قنوات الإشعارات:
|
||||
- SMS
|
||||
- Email
|
||||
- WhatsApp (عبر Twilio)
|
||||
- Push Notifications
|
||||
|
||||
### 8. التقارير
|
||||
|
||||
- تقارير المدفوعات الشهرية
|
||||
- تقارير تفاصيل المدفوعات
|
||||
- تقارير التكافل العامة
|
||||
- تقارير تحويل الخصومات
|
||||
|
||||
## التكامل مع الموديولات الأخرى
|
||||
|
||||
### 1. odex_benefit
|
||||
- ربط مع المستفيدين (family.member)
|
||||
- ربط مع العائلات (grant.benefit)
|
||||
- استخدام حالات المستفيدين
|
||||
|
||||
### 2. account
|
||||
- إنشاء الفواتير تلقائياً
|
||||
- إنشاء قيود المدفوعات
|
||||
- ربط مع الحسابات المالية
|
||||
|
||||
### 3. takaful_core
|
||||
- استخدام الإعدادات الأساسية
|
||||
- استخدام الحسابات المالية
|
||||
|
||||
### 4. odex_takaful_base
|
||||
- استخدام الإعدادات الأساسية
|
||||
- استخدام الإشعارات
|
||||
|
||||
## البيانات في النظام
|
||||
|
||||
بناءً على فحص البيانات في Odoo:
|
||||
- **الكفالات (takaful.sponsorship):** 0 سجل
|
||||
- **تفاصيل التبرعات (donations.details.lines):** 0 سجل
|
||||
- **تفاصيل المدفوعات (payment.details.lines):** 197 سجل
|
||||
- **المدفوعات الشهرية (month.payment):** 0 سجل
|
||||
- **جدولة المدفوعات (sponsorship.scheduling.line):** 0 سجل
|
||||
|
||||
## الميزات المتقدمة
|
||||
|
||||
### 1. السحب المباشر (Direct Debit)
|
||||
- جدولة المدفوعات الشهرية تلقائياً
|
||||
- معالجة المدفوعات في التاريخ المحدد
|
||||
- إرسال تذكيرات قبل الانتهاء
|
||||
|
||||
### 2. آلية التبرع
|
||||
- **مع شروط (With Conditions):** ربط مع مستفيدين محددين
|
||||
- **بدون شروط (Without Conditions):** تبرع عام
|
||||
|
||||
### 3. حساب المتأخرات
|
||||
- حساب المتأخرات تلقائياً
|
||||
- إرسال إشعارات للمتأخرات
|
||||
- إلغاء تلقائي بعد فترة محددة
|
||||
|
||||
### 4. الاستبدال التلقائي
|
||||
- استبدال تلقائي عند تغيير حالة المستفيد
|
||||
- إرسال إشعارات للكافل
|
||||
|
||||
### 5. التكامل مع Twilio
|
||||
- إرسال رسائل WhatsApp
|
||||
- إرسال SMS
|
||||
- استخدام قوالب الرسائل
|
||||
|
||||
## الأمان والصلاحيات
|
||||
|
||||
### مجموعات الأمان:
|
||||
- `group_kufula_user` - مستخدم التكافل
|
||||
- `group_donations_coordinator` - منسق التبرعات
|
||||
- `group_sponsorship_coordinator` - منسق الكفالات
|
||||
- `group_orphan_replacement` - استبدال الأيتام
|
||||
- `group_replace_sponsor` - استبدال الكافل
|
||||
- `donation_officer_group` - موظف التبرعات
|
||||
- `sponsorship_officer_group` - موظف الكفالات
|
||||
|
||||
## نقاط القوة
|
||||
|
||||
1. **شمولية النظام:** يغطي جميع جوانب إدارة الكفالات والتبرعات
|
||||
2. **التكامل الجيد:** تكامل ممتاز مع الموديولات الأخرى
|
||||
3. **الإشعارات المتقدمة:** دعم قنوات إشعارات متعددة
|
||||
4. **الأتمتة:** معالجة تلقائية للعديد من العمليات
|
||||
5. **المرونة:** دعم أنواع مختلفة من الكفالات والتبرعات
|
||||
6. **التقارير:** تقارير شاملة للعمليات
|
||||
|
||||
## نقاط التحسين المحتملة
|
||||
|
||||
1. **الأداء:** قد يحتاج تحسين للأداء مع كمية كبيرة من البيانات
|
||||
2. **التوثيق:** يمكن تحسين التوثيق الداخلي للكود
|
||||
3. **الاختبارات:** إضافة المزيد من الاختبارات الآلية
|
||||
4. **التعليقات:** بعض الأكواد تحتاج تعليقات أوضح
|
||||
5. **معالجة الأخطاء:** تحسين معالجة الأخطاء في بعض الأماكن
|
||||
|
||||
## الخلاصة
|
||||
|
||||
موديول **Odex Takaful System** هو نظام شامل ومتكامل لإدارة الكفالات والتبرعات. يوفر ميزات متقدمة مثل السحب المباشر، الاستبدال التلقائي، والإشعارات المتعددة القنوات. النظام متكامل جيداً مع الموديولات الأخرى ويوفر واجهات سهلة الاستخدام.
|
||||
|
||||
النظام جاهز للاستخدام في بيئة الإنتاج مع بعض التحسينات المحتملة للأداء والتوثيق.
|
||||
|
||||
---
|
||||
|
||||
**تاريخ المراجعة:** 2025-01-27
|
||||
**المراجع:** AI Assistant
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
from . import models
|
||||
from . import controllers
|
||||
from . import reports
|
||||
from . import wizards
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
{
|
||||
'name': 'Odex Takaful System',
|
||||
'version': '11.0',
|
||||
'category': 'Odex25-Takaful/Odex25-Takaful',
|
||||
'author': "Expert Co. Ltd.",
|
||||
'website': "http://www.exp-sa.com",
|
||||
'summary': 'This module for Takaful project',
|
||||
'depends': [
|
||||
'base',
|
||||
'takaful_core',
|
||||
'odex_takaful_base',
|
||||
'odex_benefit',
|
||||
'account',
|
||||
'phone_validation',
|
||||
# 'analytic_account',
|
||||
],
|
||||
'data': [
|
||||
'security/security_data.xml',
|
||||
'security/ir.model.access.csv',
|
||||
|
||||
'data/sequence_data.xml',
|
||||
'data/scheduled_actions.xml',
|
||||
'data/takaful_notification_mail_template.xml',
|
||||
'data/sponsorship_states_data.xml',
|
||||
'data/sponsorship_notification_data.xml',
|
||||
|
||||
'views/takaful_sponsor_view.xml',
|
||||
'views/takaful_sponsor_operation_views.xml',
|
||||
'reports/payment_details_lines_reports.xml',
|
||||
'views/assets.xml',
|
||||
'views/res_config_settings.xml',
|
||||
'wizards/orphan_replacement_wizard.xml',
|
||||
'views/takaful_sponorship_view.xml',
|
||||
'views/donation_item_views.xml',
|
||||
'views/replacement_reasons_views.xml',
|
||||
'views/replacement_process_views.xml',
|
||||
'views/benefit_views.xml',
|
||||
'views/family_member.xml',
|
||||
|
||||
'views/takaful_contribution_view.xml',
|
||||
'views/sponsorship_payment_view.xml',
|
||||
'views/sponsorship_cancellation_view.xml',
|
||||
'views/payment_details_lines_views.xml',
|
||||
'wizards/account_payment_register.xml',
|
||||
'views/res_partner_bank.xml',
|
||||
'views/res_users_inherit.xml',
|
||||
|
||||
'views/takaful_push_notification_view.xml',
|
||||
'views/takaful_grant_benefit_view.xml',
|
||||
'views/takaful_month_payment_view.xml',
|
||||
'wizards/benefit_month_payment_wiz_view.xml',
|
||||
'views/takaful_conf.xml',
|
||||
'views/sponsorship_states.xml',
|
||||
'views/takaful_notification.xml',
|
||||
'views/reports_paperformats.xml',
|
||||
'views/reports_templates.xml',
|
||||
'views/reports_actions.xml',
|
||||
'reports/month_payment_template.xml',
|
||||
'wizards/takaful_reports_wizards.xml',
|
||||
'wizards/refund_payment_wizard.xml',
|
||||
'wizards/add_details_wizard.xml',
|
||||
'wizards/donation_extension_wizard.xml',
|
||||
'wizards/replace_sponsor_wizard.xml',
|
||||
'wizards/add_benefit_wizard.xml',
|
||||
'views/donations_details_lines.xml',
|
||||
'views/donation_extension_history_views.xml',
|
||||
'views/donation_replacement_log_views.xml',
|
||||
'views/sponsorship_scheduling_line.xml',
|
||||
'views/takaful_menus_actions.xml',
|
||||
'views/preferred_communication.xml',
|
||||
'views/takaful_payment_method.xml',
|
||||
'views/product_views.xml',
|
||||
'data/message_template_data.xml',
|
||||
'data/server_actions.xml',
|
||||
|
||||
'wizards/transfer_deduction_wizard_views.xml',
|
||||
'reports/transfer_deduction_report.xml',
|
||||
'reports/transfer_deduction_report_templates.xml',
|
||||
],
|
||||
'icon': 'static/description/icon.png',
|
||||
# 'installable': True,
|
||||
# 'application': True,
|
||||
# 'auto_install': False,
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from . import _cart_change
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
from odoo import http
|
||||
import json
|
||||
|
||||
|
||||
class QtyChangeSO(http.Controller):
|
||||
|
||||
@http.route(['/qtyupdatecart_so'], type='http', auth='user', website=True)
|
||||
def QtyUpdateSO(self, **post):
|
||||
# _sol_obj = http.request.env["takaful.sponsorship"]
|
||||
# _sol_obj.user_input_qty_sol(
|
||||
# float(post.get("quantity")), int(post.get("donation_name")), int(post.get("sponsorship_id")))
|
||||
# return json.dumps({"message": True})
|
||||
try:
|
||||
env = http.request.env
|
||||
sponsorship_model = env["takaful.sponsorship"].sudo()
|
||||
# Support both 'donation_name' and 'product_id' parameters for backwards compatibility
|
||||
product_id = int(post.get("donation_name") or post.get("product_id"))
|
||||
quantity = float(post.get("quantity"))
|
||||
sponsorship_id = int(post.get("sponsorship_id"))
|
||||
sponsorship_model.user_input_qty_sol(quantity, product_id, sponsorship_id)
|
||||
return json.dumps({"message": True})
|
||||
except Exception as e:
|
||||
# Return a structured error so the frontend can display/log details
|
||||
return http.Response(
|
||||
json.dumps({"message": False, "error": str(e)}),
|
||||
status=500,
|
||||
mimetype='application/json'
|
||||
)
|
||||
|
||||
# @http.route(['/getuom_so'], type='http', auth='user', website=True)
|
||||
# def UOMGetSO(self, **post):
|
||||
# product = http.request.env['product.product'].search([('id', '=', post["product_id"])])
|
||||
# uom_category = product.product_tmpl_id.uom_id.category_id.name
|
||||
# return json.dumps({"uom_category": uom_category.lower()})
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- On Sponsorship Creation -->
|
||||
<record model="takaful.message.template" id="sponsorship_creation_template">
|
||||
<field name="title">إنشاء كفالة</field>
|
||||
<field name="body">تم إنشاء كفالة</field>
|
||||
<field name="template_name">sponsorship_creation</field>
|
||||
</record>
|
||||
|
||||
<!-- On paid sponsorship -->
|
||||
<record model="takaful.message.template" id="sponsorship_paid_template">
|
||||
<field name="title">إشعار سداد</field>
|
||||
<field name="body">تم سداد كفالة</field>
|
||||
<field name="template_name">sponsorship_paid</field>
|
||||
</record>
|
||||
|
||||
<!-- On canceled sponsorship -->
|
||||
<record model="takaful.message.template" id="sponsorship_canceled_template">
|
||||
<field name="title">إلغاء كفالة</field>
|
||||
<field name="body">لقد تم إلغاء الكفالة</field>
|
||||
<field name="template_name">sponsorship_canceled</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- On Sponsorship About to cancel -->
|
||||
<record model="takaful.message.template" id="sponsorship_to_cancel_template">
|
||||
<field name="title">علي وشك الإلغاء</field>
|
||||
<field name="body">الكفالة علي وشك الإلغاء</field>
|
||||
<field name="template_name">sponsorship_to_cancel</field>
|
||||
</record>
|
||||
|
||||
<!-- On Sponsorship Close -->
|
||||
<record model="takaful.message.template" id="sponsorship_close_template">
|
||||
<field name="title">إنهاء كفالة</field>
|
||||
<field name="body">تم إنهاء الكفالة</field>
|
||||
<field name="template_name">sponsorship_close</field>
|
||||
</record>
|
||||
|
||||
<!-- On Sponsorship to Close -->
|
||||
<record model="takaful.message.template" id="sponsorship_to_close_template">
|
||||
<field name="title">علي وشك الإنتهاء</field>
|
||||
<field name="body">الكفالة علي وشك النهاية</field>
|
||||
<field name="template_name">sponsorship_to_close</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
|
||||
<!-- Scheduler for Check sponsorship End Date daily and Sending Whatsapp message before specific duration -->
|
||||
<record id="scheduler_check_sponsorship_end_date_send_whatsapp_action" forcecreate='True' model="ir.cron">
|
||||
<field name="name">Check Sponsorship End Date To Send Wahtsapp Message to Sponsor</field>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="nextcall" eval="(DateTime.now() + timedelta(days=1)).strftime('%Y-%m-%d 04:00:00')"/>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field name="doall" eval="False"/>
|
||||
<field name="model_id" ref="model_donations_details_lines"/>
|
||||
<field name="code">model.run_check_all_end_dates()</field>
|
||||
<field name="state">code</field>
|
||||
<field name="priority" eval="2"/>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
<!-- Scheduler for Managing Sponsorship Workflow Every Day -->
|
||||
<record id="scheduler_sponsorship_workflow_action" forcecreate='True' model="ir.cron">
|
||||
<field name="name">Daily Manage Sponsorship Workflow Scheduler</field>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="nextcall" eval="(DateTime.now() + timedelta(days=1)).strftime('%Y-%m-%d 04:00:00')"/>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field name="doall" eval="False"/>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="code">model.process_sponsorship_workflow_scheduler()</field>
|
||||
<field name="state">code</field>
|
||||
<field name="priority" eval="5"/>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<!-- Scheduler for Creating Sponsorships Invoices once a month -->
|
||||
<record id="scheduler_monthly_create_sponsorship_invoice_action" forcecreate='True' model="ir.cron">
|
||||
<field name="name">Create Sponsorships Invoices Scheduler</field>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">months</field>
|
||||
<field name="nextcall" eval="(DateTime.now() + timedelta(days=28)).strftime('%Y-%m-01 02:00:00')"/>
|
||||
<field name="numbercall">-1</field>
|
||||
<field name="doall" eval="True"/>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.monthly_create_sponsorship_invoice_scheduler()</field>
|
||||
<field name="priority" eval="1"/>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<!-- Scheduler for Processing Scheduled Payments Daily -->
|
||||
<record id="scheduler_process_scheduled_payments_action" forcecreate='True' model="ir.cron">
|
||||
<field name="name">Process Scheduled Payments Daily</field>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="nextcall" eval="(DateTime.now() + timedelta(days=1)).strftime('%Y-%m-%d 03:00:00')"/>
|
||||
<field name="numbercall">-1</field>
|
||||
<field name="doall" eval="False"/>
|
||||
<field name="model_id" ref="model_sponsorship_scheduling_line"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.with_context(from_cron=True).cron_process_scheduled_payments()</field>
|
||||
<field name="priority" eval="3"/>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<!-- Scheduler for Sending SMS Reminders for Direct Debit End Dates -->
|
||||
<record id="scheduler_direct_debit_end_date_reminders" forcecreate='True' model="ir.cron">
|
||||
<field name="name">Send Direct Debit End Date Reminders</field>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="nextcall" eval="(DateTime.now() + timedelta(days=1)).strftime('%Y-%m-%d 05:00:00')"/>
|
||||
<field name="numbercall">-1</field>
|
||||
<field name="doall" eval="False"/>
|
||||
<field name="model_id" ref="model_donations_details_lines"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.cron_send_direct_debit_end_date_reminders()</field>
|
||||
<field name="priority" eval="4"/>
|
||||
<field name="active" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="ir_cron_family_member_restriction" model="ir.cron">
|
||||
<field name="name">Family Member Restriction</field>
|
||||
<field name="model_id" ref="odex_benefit.model_family_member"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model._cron_family_member_restriction()</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field name="active">False</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<data noupdate="1">
|
||||
<record id="sequence_sponsorship" model="ir.sequence">
|
||||
<field name="name">Sponsorship Sequence</field>
|
||||
<field name="code">sponsorship.sequence</field>
|
||||
<field name="prefix">SPSHIP/</field>
|
||||
<field eval="1" name="number_next"/>
|
||||
<field eval="1" name="number_increment"/>
|
||||
<field eval="True" name="use_date_range"/>
|
||||
<field eval="False" name="company_id"/>
|
||||
<field name="padding">4</field>
|
||||
</record>
|
||||
|
||||
<record id="sequence_replacement_process" model="ir.sequence">
|
||||
<field name="name">Replacement Process Sequence</field>
|
||||
<field name="code">replacement.process.sequence</field>
|
||||
<field name="prefix">OR-RE/</field>
|
||||
<field eval="1" name="number_next"/>
|
||||
<field eval="1" name="number_increment"/>
|
||||
<field eval="True" name="use_date_range"/>
|
||||
<field eval="False" name="company_id"/>
|
||||
<field name="padding">4</field>
|
||||
</record>
|
||||
|
||||
<record id="sequence_sponsorship_orphan" model="ir.sequence">
|
||||
<field name="name">Sponsorship Orphan Sequence</field>
|
||||
<field name="code">sponsorship.orphan.sequence</field>
|
||||
<!-- <field name="prefix">OR/</field> -->
|
||||
<field eval="1" name="number_next"/>
|
||||
<field eval="1" name="number_increment"/>
|
||||
<field eval="True" name="use_date_range"/>
|
||||
<field eval="False" name="company_id"/>
|
||||
<field name="padding">1</field>
|
||||
</record>
|
||||
|
||||
<record id="sequence_sponsorship_widow" model="ir.sequence">
|
||||
<field name="name">Sponsorship Widow Sequence</field>
|
||||
<field name="code">sponsorship.widow.sequence</field>
|
||||
<!-- <field name="prefix">WI/</field> -->
|
||||
<field eval="1" name="number_next"/>
|
||||
<field eval="1" name="number_increment"/>
|
||||
<field eval="True" name="use_date_range"/>
|
||||
<field eval="False" name="company_id"/>
|
||||
<field name="padding">1</field>
|
||||
</record>
|
||||
|
||||
<record id="sequence_benefit_month_payment" model="ir.sequence">
|
||||
<field name="name">Month Payment Sequence</field>
|
||||
<field name="code">month.payment.sequence</field>
|
||||
<field name="prefix">PAY/</field>
|
||||
<field eval="1" name="number_next"/>
|
||||
<field eval="1" name="number_increment"/>
|
||||
<field eval="True" name="use_date_range"/>
|
||||
<field eval="False" name="company_id"/>
|
||||
<field name="padding">4</field>
|
||||
</record>
|
||||
<record id="sequence_point_of_sales_custom" model="ir.sequence">
|
||||
<field name="name">Point Of Sale Sequence</field>
|
||||
<field name="code">point.of.sale.sequence</field>
|
||||
<field name="prefix">PO/</field>
|
||||
<field eval="1" name="number_next"/>
|
||||
<field eval="1" name="number_increment"/>
|
||||
<field eval="True" name="use_date_range"/>
|
||||
<field eval="False" name="company_id"/>
|
||||
<field name="padding">4</field>
|
||||
</record>
|
||||
<record id="payment_details" model="ir.sequence">
|
||||
<field name="name">Payment Details Sequence</field>
|
||||
<field name="code">payment.details.sequence</field>
|
||||
<field name="prefix">Payment/</field>
|
||||
<field eval="1" name="number_next"/>
|
||||
<field eval="1" name="number_increment"/>
|
||||
<field eval="True" name="use_date_range"/>
|
||||
<field eval="False" name="company_id"/>
|
||||
<field name="padding">4</field>
|
||||
</record>
|
||||
|
||||
<record id="donation_details_sequence" model="ir.sequence">
|
||||
<field name="name">Donations Details Sequence</field>
|
||||
<field name="code">donations.details.lines.sequence</field>
|
||||
<field name="prefix">SPSH/</field>
|
||||
<field name="padding">4</field>
|
||||
<field name="number_next">1</field>
|
||||
<field name="number_increment">1</field>
|
||||
<field eval="False" name="company_id"/>
|
||||
</record>
|
||||
<record id="sponsorship_scheduling_line_sequence" model="ir.sequence">
|
||||
<field name="name">Sponsorship Scheduling Line Sequence</field>
|
||||
<field name="code">sponsorship.scheduling.line.sequence</field>
|
||||
<field name="prefix">SSL/</field>
|
||||
<field name="padding">5</field>
|
||||
<field name="number_next">1</field>
|
||||
<field name="number_increment">1</field>
|
||||
<field eval="False" name="company_id"/>
|
||||
</record>
|
||||
<record id="account_move_accrsp_sequence" model="ir.sequence">
|
||||
<field name="name">ACCRSP Journal Entries Sequence</field>
|
||||
<field name="code">account.move.accrsp</field>
|
||||
<field name="prefix">ACCRSP/%(year)s/%(month)s/</field>
|
||||
<field name="padding">4</field>
|
||||
<field name="number_next">1</field>
|
||||
<field name="number_increment">1</field>
|
||||
<field eval="False" name="company_id"/>
|
||||
<field name="use_date_range">True</field>
|
||||
</record>
|
||||
<record id="account_move_payment_details_sequence" model="ir.sequence">
|
||||
<field name="name">SP Journal Entries Sequence</field>
|
||||
<field name="code">account.move.payment.details.sequence</field>
|
||||
<field name="prefix">SP/%(year)s/%(month)s/</field>
|
||||
<field name="padding">4</field>
|
||||
<field name="number_next">1</field>
|
||||
<field name="number_increment">1</field>
|
||||
<field eval="False" name="company_id"/>
|
||||
<field name="use_date_range">True</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- <record id="server_action_unlink_sponsor_and_related" model="ir.actions.server">
|
||||
<field name="name">Sponsor Unlink And Its Relations</field>
|
||||
<field name="model_id" ref="odex_takaful.model_takaful_sponsor"/>
|
||||
<field name="binding_model_id" ref="odex_takaful.model_takaful_sponsor"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">
|
||||
action = records.action_unlink_sponsor_and_related()
|
||||
</field>
|
||||
</record> -->
|
||||
|
||||
<record id="action_extend_donation" model="ir.actions.server">
|
||||
<field name="name">Extend Donation</field>
|
||||
<field name="model_id" ref="odex_takaful.model_donations_details_lines"/>
|
||||
<field name="binding_model_id" ref="odex_takaful.model_donations_details_lines"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">action = records.action_extend_sponsorship()</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="takaful.notification" id="sponsorship_confirm_whatsapp_message">
|
||||
<field name="name">ارسال رسالة واتساب مباشرة بعد اجراء الconfirm على الكفالة </field>
|
||||
<field name="duration">0</field>
|
||||
<field name="notification_type">create_kafala</field>
|
||||
<field name="message_type_ids" eval="[(4, ref('odex_takaful.whatsapp_message_type'))]"/>
|
||||
<field name="notification_state_ids"
|
||||
eval="[(4, ref('odex_takaful.sponsorship_state_draft')), (4, ref('odex_takaful.sponsorship_state_confirmed'))]"/>
|
||||
<field name="message">هنيئًا لك .. يا من اعطيت وبادرت لتُسعد يتيمًا، نشكركم على كفالتكم بمبلغ ( [Amount] ) ر.س بلغكم الله مرافقة النبي ﷺ في الجنة رابط التقييم : https://forms.gle/pRrNWohAnLPoFwb38
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="takaful.notification" id="sponsorship_before_finish_30_whatsapp_message">
|
||||
<field name="name"> تذكير اول بأنتهاء الكفالة: يتم ارسال رسالة واتساب قبل تاريخ انتهاء الكفالة المخطط له اخر بند مجدول بشهر</field>
|
||||
<field name="duration">30</field>
|
||||
<field name="notification_type">before_finish</field>
|
||||
<field name="message_type_ids" eval="[(4, ref('odex_takaful.whatsapp_message_type'))]"/>
|
||||
<field name="notification_state_ids"
|
||||
eval="[(4, ref('odex_takaful.sponsorship_state_confirmed')), (4, ref('odex_takaful.sponsorship_state_wait_pay'))]"/>
|
||||
<field name="message"> عزيزي الكافل / ـة : كفالتك السنوية عطاء يتجدد في كل عام، وثواب يُخلد لمرافقة خير الأنام ﷺ نود تذكيركم بموعد تجديد كفالتكم قبل تاريخ [ExpiryDate]
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="takaful.notification" id="sponsorship_before_finish_16_whatsapp_message">
|
||||
<field name="name">تذكير ثاني بأنتهاء الكفالة: = يتم ارسال رسالة واتساب قبل تاريخ انتهاء الكفالة المخطط له اخر بند مجدول ب16 يوم</field>
|
||||
<field name="duration">16</field>
|
||||
<field name="notification_type">before_finish</field>
|
||||
<field name="message_type_ids" eval="[(4, ref('odex_takaful.whatsapp_message_type'))]"/>
|
||||
<field name="notification_state_ids"
|
||||
eval="[(4, ref('odex_takaful.sponsorship_state_confirmed'), 4, ref('odex_takaful.sponsorship_state_wait_pay'))]"/>
|
||||
<field name="message">عزيزي الكافل / ـة : كفالتك السنوية عطاء يتجدد في كل عام، وثواب يُخلد لمرافقة خير الأنام ﷺ نود تذكيركم بموعد تجديد كفالتكم المتبقي عليها 15 يوماَ
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="takaful.notification" id="sponsorship_before_finish_4_whatsapp_message">
|
||||
<field name="name"> تذكير ثالث بأنتهاء الكفالة: يتم ارسال رسالة واتساب قبل تاريخ انتهاء الكفالة المخطط له اخر بند مجدول ب4 يوم</field>
|
||||
<field name="duration">4</field>
|
||||
<field name="notification_type">before_finish</field>
|
||||
<field name="message_type_ids" eval="[(4, ref('odex_takaful.whatsapp_message_type'))]"/>
|
||||
<field name="notification_state_ids"
|
||||
eval="[(4, ref('odex_takaful.sponsorship_state_confirmed')), (4, ref('odex_takaful.sponsorship_state_wait_pay'))]"/>
|
||||
<field name="message">عزيزي الكافل / ـة : ثلاثة أيام فقط على إنتهاء كفالتكم السنوية. كنتم سندًا لليتيم، ويسعدنا استمرار كفالتكم التي تنتهي تلقائياَ بتاريخ [ExpiryDate]</field>
|
||||
</record>
|
||||
|
||||
<record model="takaful.notification" id="sponsorship_before_finish_payment_whatsapp_message">
|
||||
<field name="name"> ارسال رسالة واتساب بعد كل اجراء دفع يتم على بنود جدولة الكفالات </field>
|
||||
<field name="duration">0</field>
|
||||
<field name="notification_type">partial_payment</field>
|
||||
<field name="notification_state_ids"
|
||||
eval="[(4, ref('odex_takaful.sponsorship_state_paid')), (4, ref('odex_takaful.sponsorship_state_wait_pay'))]"/>
|
||||
<field name="message_type_ids" eval="[(4, ref('odex_takaful.whatsapp_message_type'))]"/>
|
||||
<field name="message">هنيئًا لك .. يا من اعطيت وبادرت لتُسعد يتيمًا وأسرته، تم استلام تبرعكم بمبلغ ( [Amount] ) ر س بلغكم الله مرافقة النبي ﷺ في الجنة. رابط التقييم: https://forms.gle/pRrNWohAnLPoFwb38</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_draft">
|
||||
<field name="name">draft</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_confirmed">
|
||||
<field name="name">confirmed</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_wait_pay">
|
||||
<field name="name">wait_pay</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_paid">
|
||||
<field name="name">paid</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_partial_refund">
|
||||
<field name="name">partial_refund</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_fully_refund">
|
||||
<field name="name">fully_refund</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_approve_refund">
|
||||
<field name="name">approve_refund</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_under_refund">
|
||||
<field name="name">under_refund</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_under_replacement">
|
||||
<field name="name">under_replacement</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_replacement_done">
|
||||
<field name="name">replacement_done</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_canceled">
|
||||
<field name="name">canceled</field>
|
||||
</record>
|
||||
|
||||
<record model="sponsorship.states" id="sponsorship_state_closed">
|
||||
<field name="name">closed</field>
|
||||
</record>
|
||||
|
||||
<record model="takaful.message.type" id="whatsapp_message_type">
|
||||
<field name="name">Whatsapp</field>
|
||||
<field name="tool_type">app</field>
|
||||
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="push_notification_email_template" model="mail.template">
|
||||
<field name="name">Notification Email</field>
|
||||
<field name="email_from">${ctx.get('email_from')} or ''}</field>
|
||||
<field name="email_to">${ctx.get('email_to')}</field>
|
||||
<field name="subject">${ctx.get('company_name')} - ${ctx.get('title')}</field>
|
||||
<field name="partner_to">False</field>
|
||||
|
||||
<field name="model_id" ref="odex_takaful.model_takaful_push_notification"/>
|
||||
<field name="auto_delete" eval="True"></field>
|
||||
<!-- <field name="user_signature" eval="False"></field>-->
|
||||
<field name="lang">ar_001</field>
|
||||
<field name="body_html"><![CDATA[
|
||||
<p>
|
||||
Dear ${ctx.get('partner_name')},
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>${ctx.get('body')}</strong>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Thank you,
|
||||
</p>
|
||||
|
||||
<p>
|
||||
From ${ctx.get('company_name')}.
|
||||
</p>
|
||||
]]></field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import takaful_grant_benefit_model
|
||||
from . import takaful_sponorship_model
|
||||
from . import takaful_sponsorship_cancellation_model
|
||||
from . import takaful_sponsorship_payment_model
|
||||
|
||||
from . import takaful_sponsor_operation
|
||||
|
||||
from . import takaful_push_notification
|
||||
from . import takaful_contribution_model
|
||||
from . import takaful_month_payment
|
||||
from . import takaful_conf
|
||||
from . import sponsorship_states
|
||||
from . import replacement_reasons
|
||||
from . import replacement_process
|
||||
from . import takaful_notification
|
||||
from . import account_move
|
||||
from . import account_payment
|
||||
from . import res_partner
|
||||
|
||||
from . import preferred_communication
|
||||
from . import takaful_payment_method
|
||||
from . import res_config_settings
|
||||
from . import product
|
||||
from . import donation_details_lines
|
||||
from . import donation_extension_history
|
||||
from . import family_member
|
||||
from . import sponsorship_scheduling_line
|
||||
from . import donation_replacement_log
|
||||
|
|
@ -0,0 +1,253 @@
|
|||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import float_compare
|
||||
from odoo.tools.misc import format_date, get_lang
|
||||
from collections import defaultdict
|
||||
|
||||
class AccountMove(models.Model):
|
||||
_inherit = 'account.move'
|
||||
|
||||
takaful_sponsorship_id = fields.Many2one('takaful.sponsorship', compute='_compute_takaful_sponsorship_id', store=True)
|
||||
is_refund_sponsorship = fields.Boolean(string='Is Refund Sponsorship', default=False)
|
||||
sponsorship_scheduling_line = fields.Many2one('sponsorship.scheduling.line')
|
||||
payment_details_line = fields.Many2one('payment.details.lines')
|
||||
sponsorship_id = fields.Many2one('takaful.sponsorship', string='Sponsorship', readonly=True, )
|
||||
payment_id = fields.Many2one('account.payment', string='Payment', copy=False)
|
||||
|
||||
@api.depends('state')
|
||||
def _compute_takaful_sponsorship_id(self):
|
||||
for move in self:
|
||||
if not move.takaful_sponsorship_id and move.move_type == 'entry':
|
||||
partials = move.line_ids.matched_debit_ids | move.line_ids.matched_credit_ids
|
||||
takaful_sponsorship_ids = (partials.debit_move_id.move_id.takaful_sponsorship_id | partials.credit_move_id.move_id.takaful_sponsorship_id)
|
||||
move.takaful_sponsorship_id = takaful_sponsorship_ids[-1] if takaful_sponsorship_ids else False
|
||||
else:
|
||||
move.takaful_sponsorship_id = move.takaful_sponsorship_id
|
||||
|
||||
def action_move_line_create(self):
|
||||
'''
|
||||
Confirm the vouchers given in ids and create the journal entries for each of them
|
||||
'''
|
||||
res = super(AccountMove, self).action_move_line_create()
|
||||
if res:
|
||||
self.write({'payment_id': self.move_id.line_ids.mapped('payment_id').id})
|
||||
|
||||
@api.onchange('payment_journal_id')
|
||||
def on_change_payment_journal_id(self):
|
||||
for rec in self:
|
||||
rec.account_id = rec.payment_journal_id.default_debit_account_id
|
||||
|
||||
def action_register_payment(self):
|
||||
''' Override the payment registration behavior. '''
|
||||
# Perform any custom logic before calling the original method
|
||||
# Call the original method to preserve the default behavior
|
||||
action = super(AccountMove, self).action_register_payment()
|
||||
for move in self:
|
||||
if move.is_refund_sponsorship: # Check if it's a refund
|
||||
# Add any additional custom logic after calling the original method
|
||||
action['context'].update({
|
||||
'default_takaful_sponsorship_id': move.takaful_sponsorship_id.id,
|
||||
'default_journal_id': move.payment_details_line.journal_id.id,
|
||||
'default_is_refund_sponsorship': True,
|
||||
|
||||
})
|
||||
|
||||
return action
|
||||
|
||||
@api.depends(
|
||||
'line_ids.matched_debit_ids.debit_move_id.move_id.payment_id.is_matched',
|
||||
'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual',
|
||||
'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual_currency',
|
||||
'line_ids.matched_credit_ids.credit_move_id.move_id.payment_id.is_matched',
|
||||
'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual',
|
||||
'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual_currency',
|
||||
'line_ids.debit',
|
||||
'line_ids.credit',
|
||||
'line_ids.currency_id',
|
||||
'line_ids.amount_currency',
|
||||
'line_ids.amount_residual',
|
||||
'line_ids.amount_residual_currency',
|
||||
'line_ids.payment_id.state',
|
||||
'line_ids.full_reconcile_id',
|
||||
'sponsorship_scheduling_line.status'
|
||||
)
|
||||
def _compute_amount(self):
|
||||
# Call the original method to preserve Odoo's logic
|
||||
super(AccountMove, self)._compute_amount()
|
||||
for move in self.filtered("takaful_sponsorship_id"):
|
||||
scheduling_amount = move.sponsorship_scheduling_line.amount
|
||||
if move.payment_state == 'paid':
|
||||
# refund_amount = move.invoice_line_ids.price_unit
|
||||
refund_amount = sum(move.invoice_line_ids.mapped("price_unit"))
|
||||
refunded_scheduling_amount = move.sponsorship_scheduling_line.refunded_amount
|
||||
total_refunded_amount = refund_amount + refunded_scheduling_amount
|
||||
|
||||
if refunded_scheduling_amount == scheduling_amount:
|
||||
move.sponsorship_scheduling_line.status = 'fully_refund'
|
||||
move.sponsorship_scheduling_line.refunded_amount = scheduling_amount
|
||||
move.payment_details_line.is_fully_refund = True
|
||||
|
||||
elif refunded_scheduling_amount < scheduling_amount:
|
||||
move.sponsorship_scheduling_line.status = 'partial_refund'
|
||||
move.sponsorship_scheduling_line.refunded_amount += refund_amount
|
||||
move.payment_details_line.is_partial_refund = True
|
||||
|
||||
else:
|
||||
if not isinstance(scheduling_amount, (int, float)):
|
||||
raise UserError(
|
||||
_("Total amount should be less or equal %s") % scheduling_amount
|
||||
)
|
||||
|
||||
has_partial_refund = False
|
||||
has_fully_refund = False
|
||||
has_paid = False
|
||||
has_unpaid = False
|
||||
for line in move.takaful_sponsorship_id.sponsorship_scheduling_line_ids:
|
||||
if line.status == "partial_refund":
|
||||
has_partial_refund = True
|
||||
elif line.status == "fully_refund":
|
||||
has_fully_refund = True
|
||||
elif line.status == "paid":
|
||||
has_paid = True
|
||||
elif line.status == "unpaid":
|
||||
has_unpaid = True
|
||||
if has_partial_refund:
|
||||
move.takaful_sponsorship_id.state = 'partial_refund'
|
||||
elif has_fully_refund and not (has_partial_refund and has_paid and has_unpaid):
|
||||
move.takaful_sponsorship_id.state = 'fully_refund'
|
||||
elif has_fully_refund and (has_partial_refund or has_paid or has_unpaid):
|
||||
move.takaful_sponsorship_id.state = 'partial_refund'
|
||||
|
||||
def _post(self, soft=True):
|
||||
"""Post/Validate the documents.
|
||||
|
||||
Posting the documents will give it a number, and check that the document is
|
||||
complete (some fields might not be required if not posted but are required
|
||||
otherwise).
|
||||
If the journal is locked with a hash table, it will be impossible to change
|
||||
some fields afterwards.
|
||||
|
||||
:param soft (bool): if True, future documents are not immediately posted,
|
||||
but are set to be auto posted automatically at the set accounting date.
|
||||
Nothing will be performed on those documents before the accounting date.
|
||||
:return Model<account.move>: the documents that have been posted
|
||||
"""
|
||||
if soft:
|
||||
future_moves = self.filtered(lambda move: move.date > fields.Date.context_today(self))
|
||||
future_moves.auto_post = True
|
||||
for move in future_moves:
|
||||
msg = _('This move will be posted at the accounting date: %(date)s',
|
||||
date=format_date(self.env, move.date))
|
||||
move.message_post(body=msg)
|
||||
to_post = self - future_moves
|
||||
else:
|
||||
to_post = self
|
||||
|
||||
# `user_has_group` won't be bypassed by `sudo()` since it doesn't change the user anymore.
|
||||
# if not self.env.su and not self.env.user.has_group('account.group_account_invoice'):
|
||||
# raise AccessError(_("You don't have the access rights to post an invoice."))
|
||||
for move in to_post:
|
||||
if move.partner_bank_id and not move.partner_bank_id.active:
|
||||
raise UserError(
|
||||
_("The recipient bank account link to this invoice is archived.\nSo you cannot confirm the invoice."))
|
||||
if move.state == 'posted':
|
||||
raise UserError(_('The entry %s (id %s) is already posted.') % (move.name, move.id))
|
||||
if not move.line_ids.filtered(lambda line: not line.display_type):
|
||||
raise UserError(_('You need to add a line before posting.'))
|
||||
if move.auto_post and move.date > fields.Date.context_today(self):
|
||||
date_msg = move.date.strftime(get_lang(self.env).date_format)
|
||||
raise UserError(_("This move is configured to be auto-posted on %s", date_msg))
|
||||
|
||||
if not move.partner_id:
|
||||
if move.is_sale_document():
|
||||
raise UserError(
|
||||
_("The field 'Customer' is required, please complete it to validate the Customer Invoice."))
|
||||
elif move.is_purchase_document():
|
||||
raise UserError(
|
||||
_("The field 'Vendor' is required, please complete it to validate the Vendor Bill."))
|
||||
|
||||
if move.is_invoice(include_receipts=True) and float_compare(move.amount_total, 0.0,
|
||||
precision_rounding=move.currency_id.rounding) < 0:
|
||||
raise UserError(
|
||||
_("You cannot validate an invoice with a negative total amount. You should create a credit note instead. Use the action menu to transform it into a credit note or refund."))
|
||||
|
||||
if move.line_ids.account_id.filtered(lambda account: account.deprecated):
|
||||
raise UserError(_("A line of this move is using a deprecated account, you cannot post it."))
|
||||
|
||||
# Handle case when the invoice_date is not set. In that case, the invoice_date is set at today and then,
|
||||
# lines are recomputed accordingly.
|
||||
# /!\ 'check_move_validity' must be there since the dynamic lines will be recomputed outside the 'onchange'
|
||||
# environment.
|
||||
if not move.invoice_date:
|
||||
if move.is_sale_document(include_receipts=True):
|
||||
move.invoice_date = fields.Date.context_today(self)
|
||||
move.with_context(check_move_validity=False)._onchange_invoice_date()
|
||||
elif move.is_purchase_document(include_receipts=True):
|
||||
raise UserError(_("The Bill/Refund date is required to validate this document."))
|
||||
|
||||
# When the accounting date is prior to the tax lock date, move it automatically to the next available date.
|
||||
# /!\ 'check_move_validity' must be there since the dynamic lines will be recomputed outside the 'onchange'
|
||||
# environment.
|
||||
if (move.company_id.tax_lock_date and move.date <= move.company_id.tax_lock_date) and (
|
||||
move.line_ids.tax_ids or move.line_ids.tax_tag_ids):
|
||||
move.date = move._get_accounting_date(move.invoice_date or move.date, True)
|
||||
move.with_context(check_move_validity=False)._onchange_currency()
|
||||
|
||||
for move in to_post:
|
||||
# Fix inconsistencies that may occure if the OCR has been editing the invoice at the same time of a user. We force the
|
||||
# partner on the lines to be the same as the one on the move, because that's the only one the user can see/edit.
|
||||
wrong_lines = move.is_invoice() and move.line_ids.filtered(
|
||||
lambda aml: aml.partner_id != move.commercial_partner_id and not aml.display_type)
|
||||
if wrong_lines:
|
||||
wrong_lines.partner_id = move.commercial_partner_id.id
|
||||
|
||||
# Create the analytic lines in batch is faster as it leads to less cache invalidation.
|
||||
to_post.mapped('line_ids').create_analytic_lines()
|
||||
to_post.write({
|
||||
'state': 'posted',
|
||||
'posted_before': True,
|
||||
})
|
||||
|
||||
for move in to_post:
|
||||
move.message_subscribe([p.id for p in [move.partner_id] if p not in move.sudo().message_partner_ids])
|
||||
|
||||
for move in to_post:
|
||||
if move.is_sale_document() \
|
||||
and move.journal_id.sale_activity_type_id \
|
||||
and (move.journal_id.sale_activity_user_id or move.invoice_user_id).id not in (
|
||||
self.env.ref('base.user_root').id, False):
|
||||
move.activity_schedule(
|
||||
date_deadline=min((date for date in move.line_ids.mapped('date_maturity') if date),
|
||||
default=move.date),
|
||||
activity_type_id=move.journal_id.sale_activity_type_id.id,
|
||||
summary=move.journal_id.sale_activity_note,
|
||||
user_id=move.journal_id.sale_activity_user_id.id or move.invoice_user_id.id,
|
||||
)
|
||||
|
||||
customer_count, supplier_count = defaultdict(int), defaultdict(int)
|
||||
for move in to_post:
|
||||
if move.is_sale_document():
|
||||
customer_count[move.partner_id] += 1
|
||||
elif move.is_purchase_document():
|
||||
supplier_count[move.partner_id] += 1
|
||||
for partner, count in customer_count.items():
|
||||
(partner | partner.commercial_partner_id)._increase_rank('customer_rank', count)
|
||||
for partner, count in supplier_count.items():
|
||||
(partner | partner.commercial_partner_id)._increase_rank('supplier_rank', count)
|
||||
|
||||
# Trigger action for paid invoices in amount is zero
|
||||
to_post.filtered(
|
||||
lambda m: m.is_invoice(include_receipts=True) and m.currency_id.is_zero(m.amount_total)
|
||||
).action_invoice_paid()
|
||||
|
||||
# Force balance check since nothing prevents another module to create an incorrect entry.
|
||||
# This is performed at the very end to avoid flushing fields before the whole processing.
|
||||
to_post._check_balanced()
|
||||
return to_post
|
||||
|
||||
|
||||
class AccountMoveLines(models.Model):
|
||||
_inherit = 'account.move.line'
|
||||
|
||||
takaful_sponsorship_id = fields.Many2one('takaful.sponsorship', related='move_id.takaful_sponsorship_id', store=True)
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
from odoo import models, fields
|
||||
|
||||
|
||||
class AccountPayment(models.Model):
|
||||
_inherit = 'account.payment'
|
||||
|
||||
takaful_sponsorship_id = fields.Many2one(related="move_id.takaful_sponsorship_id")
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,118 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class DonationExtensionHistory(models.Model):
|
||||
_name = 'donation.extension.history'
|
||||
_description = 'Donation Extension History'
|
||||
_order = 'extension_date desc'
|
||||
_rec_name = 'extension_ref'
|
||||
|
||||
extension_ref = fields.Char(
|
||||
string='Extension Reference',
|
||||
readonly=True,
|
||||
compute='_compute_extension_ref',
|
||||
store=True
|
||||
)
|
||||
|
||||
donation_detail_id = fields.Many2one(
|
||||
'donations.details.lines',
|
||||
string='Donation Detail',
|
||||
required=True,
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
sponsor_id = fields.Many2one(
|
||||
'res.partner',
|
||||
string='Sponsor',
|
||||
related='donation_detail_id.sponsor_id',
|
||||
store=True,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
sponsorship_id = fields.Many2one(
|
||||
'takaful.sponsorship',
|
||||
string='Sponsorship',
|
||||
related='donation_detail_id.sponsorship_id',
|
||||
store=True,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
product_template_id = fields.Many2one(
|
||||
'product.template',
|
||||
string='Donation Item',
|
||||
related='donation_detail_id.product_template_id',
|
||||
store=True,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
extension_amount = fields.Float(
|
||||
string='Extension Amount',
|
||||
required=True,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
extension_months = fields.Integer(
|
||||
string='Extension Months',
|
||||
required=True,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
old_end_date = fields.Date(
|
||||
string='Old End Date',
|
||||
required=True,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
new_end_date = fields.Date(
|
||||
string='New End Date',
|
||||
required=True,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
extension_date = fields.Datetime(
|
||||
string='Extension Date',
|
||||
default=fields.Datetime.now,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
user_id = fields.Many2one(
|
||||
'res.users',
|
||||
string='Extended By',
|
||||
default=lambda self: self.env.user,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
invoice_id = fields.Many2one(
|
||||
'account.move',
|
||||
string='Extension Invoice',
|
||||
readonly=True,
|
||||
help='Invoice created for this extension'
|
||||
)
|
||||
|
||||
notes = fields.Text(
|
||||
string='Notes'
|
||||
)
|
||||
|
||||
old_direct_debit = fields.Boolean(
|
||||
string='Old Direct Debit',
|
||||
readonly=True
|
||||
)
|
||||
|
||||
new_direct_debit = fields.Boolean(
|
||||
string='New Direct Debit',
|
||||
readonly=True
|
||||
)
|
||||
|
||||
@api.depends('donation_detail_id', 'extension_date')
|
||||
def _compute_extension_ref(self):
|
||||
for rec in self:
|
||||
if rec.donation_detail_id and rec.extension_date:
|
||||
rec.extension_ref = _('Extension - %s - %s') % (
|
||||
rec.donation_detail_id.sequence_no or 'N/A',
|
||||
rec.extension_date.strftime('%Y-%m-%d %H:%M')
|
||||
)
|
||||
else:
|
||||
rec.extension_ref = _('Extension')
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class DonationReplacementLog(models.Model):
|
||||
_name = 'donation.replacement.log'
|
||||
_description = 'Donation Replacement Log'
|
||||
_order = 'replacement_date desc'
|
||||
_rec_name = 'replacement_ref'
|
||||
|
||||
replacement_ref = fields.Char(
|
||||
string='replacement Reference',
|
||||
readonly=True,
|
||||
compute='_compute_replacement_ref',
|
||||
store=True
|
||||
)
|
||||
|
||||
donation_detail_id = fields.Many2one(
|
||||
'donations.details.lines',
|
||||
string='Donation Detail',
|
||||
required=True,
|
||||
ondelete='cascade',
|
||||
index=True
|
||||
)
|
||||
|
||||
sponsor_id = fields.Many2one(
|
||||
'res.partner',
|
||||
string='Sponsor',
|
||||
related='donation_detail_id.sponsor_id',
|
||||
store=True,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
sponsorship_id = fields.Many2one(
|
||||
'takaful.sponsorship',
|
||||
string='Sponsorship',
|
||||
related='donation_detail_id.sponsorship_id',
|
||||
store=True,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
replacement_date = fields.Datetime(
|
||||
string='Replacement Date',
|
||||
default=fields.Datetime.now,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
user_id = fields.Many2one(
|
||||
'res.users',
|
||||
string='Replaced By',
|
||||
default=lambda self: self.env.user,
|
||||
readonly=True
|
||||
)
|
||||
|
||||
new_benefit = fields.Char(string="New Benefit", copy=False, readonly=True)
|
||||
old_benefit = fields.Char(string="old Benefit", copy=False, readonly=True)
|
||||
record_type = fields.Selection([('sponsorship', 'Sponsorship'),('donation', 'Donation')], string="Record Type", readonly=True)
|
||||
replacement_reason_id = fields.Many2one('replacement.reasons', string="Replacement Reason", readonly=True)
|
||||
|
||||
@api.depends('donation_detail_id', 'replacement_date')
|
||||
def _compute_replacement_ref(self):
|
||||
for rec in self:
|
||||
if rec.donation_detail_id and rec.replacement_date:
|
||||
rec.replacement_ref = _('Replacement - %s - %s') % (
|
||||
rec.donation_detail_id.sequence_no or 'N/A',
|
||||
rec.replacement_date.strftime('%Y-%m-%d %H:%M')
|
||||
)
|
||||
else:
|
||||
rec.replacement_ref = _('Replacement')
|
||||
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
from odoo import models, fields, api, _
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
class GrantBenefit(models.Model):
|
||||
_inherit = 'grant.benefit'
|
||||
|
||||
def action_second_accepted(self):
|
||||
super(GrantBenefit, self).action_second_accepted()
|
||||
for member in self.member_ids:
|
||||
sponsorships_main = self.env['donations.details.lines'].search([
|
||||
('benefit_id', '=', member.id,),('state', '=', 'active')
|
||||
])
|
||||
sponsorships_multi = self.env['donations.details.lines'].search([
|
||||
('benefit_ids', 'in', member.id),('state', '=', 'active')
|
||||
])
|
||||
sponsorships = sponsorships_main | sponsorships_multi
|
||||
if sponsorships:
|
||||
for sponsorship in sponsorships:
|
||||
if member.member_status and member.member_status == 'non_benefit' and sponsorship.record_type == 'sponsorship':
|
||||
sponsorship.sudo().write({'state': 'replace'})
|
||||
|
||||
|
||||
|
||||
class FamilyMember(models.Model):
|
||||
_inherit = 'family.member'
|
||||
|
||||
donation_details_count = fields.Integer(
|
||||
string='Donation Details',
|
||||
compute='_compute_donation_details_count'
|
||||
)
|
||||
sponsor_id = fields.Many2one('res.partner', string='Sponsor Partner', domain="[('is_sponsor_portal', '=', True)]")
|
||||
sponsor_related_id = fields.Many2one('res.partner', string='Sponsor')
|
||||
sponsorship_id = fields.Many2one('takaful.sponsorship', string='Sponsorship')
|
||||
sponsorship_end_date = fields.Date(string='Sponsorship End Date')
|
||||
is_restricted = fields.Boolean(string="Is Restricted ?", default=False, readonly=True)
|
||||
general_restriction = fields.Boolean(string="General Restriction", default=False, readonly=True)
|
||||
kafala_status = fields.Selection(
|
||||
[('have_kafala', 'Have Kafala'), ('have_not_kafala', 'Have not Kafala')],
|
||||
string='Kafala Status', compute='_compute_kafala_status', store=True, readonly=True)
|
||||
|
||||
@api.depends('sponsor_related_id')
|
||||
def _compute_kafala_status(self):
|
||||
for rec in self:
|
||||
rec.kafala_status = 'have_kafala' if rec.sponsor_related_id else 'have_not_kafala'
|
||||
|
||||
def _compute_donation_details_count(self):
|
||||
for rec in self:
|
||||
rec.donation_details_count = self.env['donations.details.lines'].search_count([
|
||||
'|',
|
||||
('benefit_id', '=', rec.id),
|
||||
('benefit_ids', 'in', rec.ids)
|
||||
])
|
||||
|
||||
def action_open_donation_detail(self):
|
||||
self.ensure_one()
|
||||
|
||||
return {
|
||||
'name': _('Donation Details Lines'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'donations.details.lines',
|
||||
'view_mode': 'tree,form',
|
||||
'domain': ['|', ('benefit_id', '=', self.id), ('benefit_ids', 'in', self.ids)],
|
||||
'context': {'create': False, 'delete': False},
|
||||
}
|
||||
|
||||
def action_not_available_for_sponsorship(self):
|
||||
for rec in self:
|
||||
rec.general_restriction = True
|
||||
|
||||
def action_available_for_sponsorship(self):
|
||||
for rec in self:
|
||||
rec.general_restriction = False
|
||||
|
||||
@api.model
|
||||
def _cron_family_member_restriction(self):
|
||||
benefit_ids = self.env["family.member"].sudo().search([("is_restricted", "=", True)])
|
||||
today = fields.Date.today()
|
||||
restriction_period = self.env['ir.config_parameter'].sudo().get_param('odex_takaful.restriction_period')
|
||||
for benefit in benefit_ids:
|
||||
create_date = benefit.create_date.date()
|
||||
benefit_date = create_date + timedelta(days=int(restriction_period) or 0)
|
||||
if benefit_date >= today:
|
||||
benefit.is_restricted = False
|
||||
|
||||
def create(self, vals):
|
||||
res = super(FamilyMember, self).create(vals)
|
||||
self.is_restricted = True
|
||||
return res
|
||||
|
||||
# @api.model
|
||||
# def write(self, vals):
|
||||
# res = super(FamilyMember, self).write(vals)
|
||||
# if 'member_status' in vals:
|
||||
# for member in self:
|
||||
# sponsorships_main = self.env['donations.details.lines'].search([
|
||||
# ('benefit_id', '=', member.id)
|
||||
# ])
|
||||
# sponsorships_multi = self.env['donations.details.lines'].search([
|
||||
# ('benefit_ids', 'in', member.id)
|
||||
# ])
|
||||
# sponsorships = sponsorships_main | sponsorships_multi
|
||||
#
|
||||
# if sponsorships:
|
||||
# if member.member_status and member.member_status == 'non_benefit' and sponsorships.sponsorship_id.record_type == 'sponsorship':
|
||||
# sponsorships.write({'state': 'replace'})
|
||||
# return res
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class PreferredCommunication(models.Model):
|
||||
_name = 'preferred.communication'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
donation_category = fields.Selection(
|
||||
[('donation', 'Donation'), ('sponsorship', 'Sponsorship'), ('endowment', 'Endowment')],
|
||||
string='Donation Category')
|
||||
fixed_value = fields.Boolean(string='Is Fixed Value?', compute='_compute_fixed_value')
|
||||
sponsorship_duration = fields.Selection([('temporary', 'Temporary'), ('permanent', 'Permanent')],
|
||||
string='Sponsorship Duration Type')
|
||||
_quantity = fields.Float(default=0, store=True)
|
||||
payment_method_id = fields.Many2one('takaful.payment.method', string="Payment Method")
|
||||
|
||||
def _compute_fixed_value(self):
|
||||
for rec in self:
|
||||
rec.fixed_value = False
|
||||
|
||||
def link_to_sponsorship(self):
|
||||
sponsorship_id = self.env.context.get('sponsorship_id')
|
||||
if not sponsorship_id:
|
||||
return
|
||||
|
||||
sponsorship = self.env['takaful.sponsorship'].browse(sponsorship_id)
|
||||
vals = []
|
||||
for rec in self:
|
||||
vals.append((0, 0, {
|
||||
'product_template_id': rec.id,
|
||||
'sponsorship_id': sponsorship_id,
|
||||
'donation_types': 'donation',
|
||||
'donation_mechanism': 'without_conditions',
|
||||
}))
|
||||
|
||||
# Append to existing lines instead of replacing them
|
||||
sponsorship.write({
|
||||
'donations_details_lines': vals
|
||||
})
|
||||
|
||||
def utilizable_cart_details(self):
|
||||
"""
|
||||
Utilizable Cart Details For Remove , Add And Update Operations
|
||||
For Cart To Product Catelog Module To Object addcart.sales.products
|
||||
"""
|
||||
|
||||
context = self._context.copy() or {}
|
||||
cart_object = self.env["donations.details.lines"]
|
||||
cart_details = dict()
|
||||
total_count = cart_object.search_count(
|
||||
[('product_template_id', '=', self.id),
|
||||
('sponsorship_id', '=', context.get('sponsorship_id'))]) # , ("cart_flag", "=", True)
|
||||
cart_details["total_count"] = total_count
|
||||
cart_data = cart_object.search(
|
||||
[('product_template_id', '=', self.id),
|
||||
('sponsorship_id', '=', context.get('sponsorship_id'))]) # , ("cart_flag", "=", True)
|
||||
cart_details["cart_data"] = cart_data
|
||||
return cart_details
|
||||
|
||||
def initiate_sol(self, operation, sponsorship_id):
|
||||
"""
|
||||
Initiate Sale Order Line By Cart Functionality.
|
||||
"""
|
||||
|
||||
ts_object = self.env["takaful.sponsorship"]
|
||||
sponsorship_object = ts_object.search([("id", "=", sponsorship_id)])
|
||||
if operation == "add":
|
||||
ts_object.sol_by_cart(operation, self, sponsorship_object)
|
||||
elif operation == "remove":
|
||||
ts_object.sol_by_cart(operation, self, sponsorship_object)
|
||||
elif operation == "update":
|
||||
ts_object.sol_by_cart(operation, self, sponsorship_object)
|
||||
|
||||
def set_quantity_so(self, quantity, operation=None):
|
||||
context = self._context.copy() or {}
|
||||
cart_details = self.utilizable_cart_details()
|
||||
if operation == "remove":
|
||||
self._quantity -= quantity
|
||||
if cart_details.get("total_count") != 0:
|
||||
self.initiate_sol("remove", context.get("sponsorship_id"))
|
||||
else:
|
||||
self._quantity += quantity
|
||||
if cart_details.get("total_count") != 0:
|
||||
self.initiate_sol("update", context.get("sponsorship_id"))
|
||||
else:
|
||||
self.initiate_sol("add", context.get("sponsorship_id"))
|
||||
|
||||
def remove_quantity_button_so(self):
|
||||
if self._quantity == 0:
|
||||
self._quantity = 0
|
||||
return
|
||||
return self.set_quantity_so(1, operation="remove")
|
||||
|
||||
def add_quantity_button_so(self):
|
||||
# return self.set_quantity_so(1, operation="add")
|
||||
self.set_quantity_so(1, operation="add")
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _, exceptions
|
||||
from odoo.exceptions import ValidationError, UserError, Warning
|
||||
import requests
|
||||
import re
|
||||
|
||||
class ReplacementProcess(models.Model):
|
||||
_name = 'replacement.process'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
_description = "Replacement Process"
|
||||
_rec_name = 'code'
|
||||
|
||||
code = fields.Char(string="Replacement Reference",copy=False,readonly=True)
|
||||
user_id = fields.Many2one('res.users', string="Create User")
|
||||
sponsorship_id = fields.Many2one('takaful.sponsorship',string='Sponsorship')
|
||||
branch_id = fields.Many2one('branch.settings', string="Branch")
|
||||
branch_ids = fields.Many2many('branch.settings', string="Branch")
|
||||
sponsor_donor_type = fields.Selection(string='Sponsor / Donor Type',selection=[('registered', 'Registered'), ('new_sponsor', 'New Sponsor')])
|
||||
record_type = fields.Selection([('sponsorship', 'Sponsorship'),('donation', 'Donation')], string="Record Type")
|
||||
sponsor_id = fields.Many2one('res.partner',string='Sponsor Name')
|
||||
replacement_reason_id = fields.Many2one('replacement.reasons', string="Replacement Reason")
|
||||
benefit_ids = fields.Many2many('family.member',string='Benefits')
|
||||
replaced = fields.Boolean('Replaced')
|
||||
family_ids = fields.Many2many('grant.benefit',string='Family')
|
||||
registered_type = fields.Selection(string='Registered Type',selection=[('sponsor', 'Sponsor'),('member', 'Member')])
|
||||
replacement_line_ids = fields.One2many('replacement.process.line', 'process_id', string="Replacement Lines", tracking=True)
|
||||
state = fields.Selection([('draft', 'Draft'),('replaced', 'Replaced')],string='State', default='draft', tracking=True)
|
||||
|
||||
|
||||
|
||||
|
||||
# Model Operations
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if vals.get('code', 'New') == 'New':
|
||||
vals['code'] = self.env['ir.sequence'].sudo().next_by_code('replacement.process.sequence')
|
||||
|
||||
res = super(ReplacementProcess, self).create(vals)
|
||||
return res
|
||||
|
||||
|
||||
|
||||
def unlink(self):
|
||||
raise UserError(_('You cannot delete this record'))
|
||||
return super(ReplacementProcess, self).unlink()
|
||||
|
||||
|
||||
def confirm_replacement(self):
|
||||
for rec in self:
|
||||
rec.benefit_ids.sudo().write({'replaced': True})
|
||||
rec.sponsorship_id.sudo().write({'state': 'replacement_done'})
|
||||
rec.sponsorship_id.sudo().write({'branch_custom_id': self.branch_id.id})
|
||||
if rec.replacement_line_ids:
|
||||
for benefit in rec.replacement_line_ids:
|
||||
all_donation_lines = (
|
||||
(rec.sponsorship_id.donations_details_lines if rec.sponsorship_id.donations_details_lines else self.env[
|
||||
'donations.details.lines']) |
|
||||
(
|
||||
rec.sponsorship_id.donations_details_lines_mechanism_ids if rec.sponsorship_id.donations_details_lines_mechanism_ids else
|
||||
self.env['donations.details.lines'])
|
||||
)
|
||||
|
||||
for donation_line in all_donation_lines:
|
||||
if donation_line.sponsorship_type in ['person',benefit.sponsorship_type] and donation_line.benefit_id and benefit.to_benefit_id and donation_line.benefit_id == benefit.from_benefit_id:
|
||||
donation_line.benefit_id.sudo().write({'replaced': True})
|
||||
rec.family_ids = [(6, 0, [donation_line.benefit_id.benefit_id.id])]
|
||||
donation_line.sudo().write({'benefit_id': benefit.to_benefit_id.id})
|
||||
|
||||
elif donation_line.sponsorship_type in ['group',benefit.sponsorship_type] and donation_line.benefit_ids and benefit.to_benefit_ids and donation_line.benefit_ids == benefit.from_benefit_ids:
|
||||
rec.family_ids = [(6, 0, [donation_line.benefit_ids.mapped('benefit_id.id')[0]])]
|
||||
donation_line.sudo().write({'benefit_ids': benefit.to_benefit_ids.ids})
|
||||
donation_line.sudo().write({'benefit_id': benefit.to_benefit_ids.ids[0]})
|
||||
donation_line.benefit_ids.sudo().write({'replaced': True})
|
||||
rec.state = 'replaced'
|
||||
rec.replaced = True
|
||||
rec.action_send_whatsapp()
|
||||
|
||||
|
||||
|
||||
|
||||
def action_send_whatsapp(self):
|
||||
config = self.env['ir.config_parameter'].sudo()
|
||||
account_sid = config.get_param('odex_takaful.twilio_account_sid')
|
||||
auth_token = config.get_param('odex_takaful.twilio_auth_token')
|
||||
from_whatsapp = config.get_param('odex_takaful.twilio_from_whatsapp')
|
||||
|
||||
if not account_sid or not auth_token or not from_whatsapp:
|
||||
raise ValidationError(_("Twilio configuration is missing. Please configure Twilio SID, Auth Token, and WhatsApp number in General Configurations."))
|
||||
|
||||
from_cleaned_mobile = re.sub(r'[^\d+]', '', from_whatsapp)
|
||||
from_whatsapp_number = f'whatsapp:{from_cleaned_mobile}'
|
||||
message = "نشعركم بإستبدال أبنائكم المكفول/ة بآخر مستحق وذلك لإستبعاده من الجمعية نظامياً، للحصول على تقرير اليتيم الجديد يسعدنا تواصلكم مع الفرع، بلغكم الله مرافقة النبى صلى الله عليه وسلم فى الجنة"
|
||||
|
||||
for partner in self:
|
||||
mobile = partner.sponsor_id.mobile if partner.sponsor_id else partner.sponsorship_id.member_id.mobile
|
||||
if mobile:
|
||||
# Clean the number (keep + and digits only)
|
||||
cleaned_mobile = re.sub(r'[^\d+]', '', mobile)
|
||||
to_whatsapp_number = f'whatsapp:{cleaned_mobile}'
|
||||
url = f"https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Messages.json"
|
||||
|
||||
payload = {
|
||||
'From': from_whatsapp_number,
|
||||
'To': to_whatsapp_number,
|
||||
'Body': message,
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
url,
|
||||
data=payload,
|
||||
auth=(account_sid, auth_token)
|
||||
)
|
||||
|
||||
if response.status_code != 201:
|
||||
raise ValidationError(_("Failed to send WhatsApp message: %s") % response.text)
|
||||
|
||||
|
||||
class FamilyMember(models.Model):
|
||||
_inherit = 'family.member'
|
||||
|
||||
replaced = fields.Boolean('Replaced')
|
||||
|
||||
def write(self, vals):
|
||||
res = super(FamilyMember, self).write(vals)
|
||||
sponsorship_states = ['confirmed', 'wait_pay', 'under_refund', 'under_replacement', 'replacement_done']
|
||||
|
||||
for record in self:
|
||||
if any(key in vals for key in ['is_work', 'is_married', 'member_location_conf']):
|
||||
if vals.get('is_work') or vals.get('is_married') or vals.get('member_location_conf') is False:
|
||||
# Search in donations.details.lines where this member is either benefit_id or in benefit_ids
|
||||
lines = self.env['donations.details.lines'].sudo().search([
|
||||
'|',
|
||||
('benefit_id', '=', record.id),
|
||||
('benefit_ids', 'in', [record.id])
|
||||
])
|
||||
|
||||
for line in lines:
|
||||
# Get related sponsorship
|
||||
sponsorship = line.sponsorship_mechanism_id or line.sponsorship_id
|
||||
if sponsorship and sponsorship.state in sponsorship_states:
|
||||
sponsor = sponsorship.sponsor_id or sponsorship.member_id
|
||||
mobile = sponsor.mobile if sponsor else None
|
||||
|
||||
if mobile:
|
||||
self.send_whatsapp_message(mobile, record.name)
|
||||
break
|
||||
|
||||
return res
|
||||
|
||||
def send_whatsapp_message(self, mobile, member_name):
|
||||
config = self.env['ir.config_parameter'].sudo()
|
||||
account_sid = config.get_param('odex_takaful.twilio_account_sid')
|
||||
auth_token = config.get_param('odex_takaful.twilio_auth_token')
|
||||
from_whatsapp = config.get_param('odex_takaful.twilio_from_whatsapp')
|
||||
|
||||
|
||||
if not account_sid or not auth_token or not from_whatsapp:
|
||||
raise ValidationError(_("Twilio configuration is missing. Please configure Twilio SID, Auth Token, and WhatsApp number in General Configurations."))
|
||||
|
||||
from_cleaned_mobile = re.sub(r'[^\d+]', '', from_whatsapp)
|
||||
from_whatsapp_number = f'whatsapp:{from_cleaned_mobile}'
|
||||
message = "تنبيه: اليتيم الحالي [NAME] أصبح غير مستحق لأسباب محددة ويجب الاستبدال بيتيم اخر."
|
||||
message = message.replace("[NAME]", member_name) # Clean the number (keep + and digits only)
|
||||
cleaned_mobile = re.sub(r'[^\d+]', '', mobile)
|
||||
to_whatsapp_number = f'whatsapp:{cleaned_mobile}'
|
||||
|
||||
url = f"https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Messages.json"
|
||||
|
||||
payload = {
|
||||
'From': from_whatsapp_number,
|
||||
'To': to_whatsapp_number,
|
||||
'Body': message,
|
||||
}
|
||||
|
||||
response = requests.post(url, data=payload, auth=(account_sid, auth_token))
|
||||
|
||||
if response.status_code != 201:
|
||||
raise ValidationError(_("Failed to send WhatsApp message: %s") % response.text)
|
||||
|
||||
class ReplacementProcessLine(models.Model):
|
||||
_name = 'replacement.process.line'
|
||||
_description = 'Replacement ProcessLine'
|
||||
|
||||
members_domain_ids = fields.Many2many(comodel_name='family.member')
|
||||
from_benefit_id = fields.Many2one('family.member', string="From Benefit")
|
||||
to_benefit_id = fields.Many2one('family.member', string="To Benefit", domain = "[('id', 'in',members_domain_ids)]")
|
||||
from_benefit_ids = fields.Many2many('family.member', 'replacement_process_from_benefit_wiz_rel', 'line_id', 'benefit_id', string="From Benefits (Group)")
|
||||
to_benefit_ids = fields.Many2many('family.member', 'replacement_process_to_benefitwiz__rel', 'line_id', 'benefit_id', string="To Benefits (Group)", domain = "[('id', 'in',members_domain_ids)]")
|
||||
sponsorship_type = fields.Selection([('person', 'Individual'),('group', 'Group')],string='Sponsorship Type')
|
||||
process_id = fields.Many2one('replacement.process', string="Wizard")
|
||||
|
||||
@api.constrains('from_benefit_ids', 'to_benefit_ids')
|
||||
def onchange_from_to_constrain(self):
|
||||
for rec in self:
|
||||
if len(self.from_benefit_ids) != len(self.to_benefit_ids):
|
||||
raise ValidationError(
|
||||
_("You must select the same number of beneficiaries in the from benefits group (%s) to the to benefits group (%s)" % (
|
||||
", ".join(self.from_benefit_ids.mapped('name')),
|
||||
", ".join(self.to_benefit_ids.mapped('name')))))
|
||||
|
||||
|
||||
|
||||
|
||||
class GrantBenefit(models.Model):
|
||||
_inherit = 'grant.benefit'
|
||||
|
||||
replaced = fields.Boolean('Replaced')
|
||||
|
||||
def action_open_replacements(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Replacement Process',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'replacement.process',
|
||||
'domain': [('family_ids', 'in', [self.id])],
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
from odoo import api, fields, models, _
|
||||
|
||||
class ReplacementReasons(models.Model):
|
||||
_name = "replacement.reasons"
|
||||
_description = "Replacement Reasons"
|
||||
|
||||
name = fields.Char(string="Name")
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
from odoo import models, fields, api, _
|
||||
|
||||
class TakafulConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
cancel_refund = fields.Integer(string='Cancel Refund Time')
|
||||
twilio_account_sid = fields.Char(string="Twilio Account SID", config_parameter="odex_takaful.twilio_account_sid")
|
||||
twilio_auth_token = fields.Char(string="Twilio Auth Token", config_parameter="odex_takaful.twilio_auth_token")
|
||||
twilio_from_whatsapp = fields.Char(string="From WhatsApp Number",help="Enter a valid phone number including country code. Example: +14155238886",
|
||||
config_parameter="odex_takaful.twilio_from_whatsapp")
|
||||
|
||||
donation_extension_reminder_sms_template_id = fields.Many2one('sms.template', string="Donation Extension Reminder SMS Template", related='company_id.donation_extension_reminder_sms_template_id', readonly=False)
|
||||
donation_ended_sms_template_id = fields.Many2one('sms.template', string="Donation Ended SMS Template", related='company_id.donation_ended_sms_template_id', readonly=False)
|
||||
restriction_period = fields.Integer(string='Restriction Period')
|
||||
faal_kheer_partner_id = fields.Many2one("res.partner", string="Faal Kheer Partner", related='company_id.faal_kheer_partner_id', readonly=False)
|
||||
|
||||
def set_values(self):
|
||||
super(TakafulConfigSettings, self).set_values()
|
||||
sudoConf = self.env['ir.config_parameter'].sudo()
|
||||
|
||||
sudoConf.set_param('odex_takaful.cancel_refund', self.cancel_refund)
|
||||
sudoConf.set_param('odex_takaful.restriction_period', self.restriction_period)
|
||||
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(TakafulConfigSettings, self).get_values()
|
||||
sudoConf = self.env['ir.config_parameter'].sudo()
|
||||
|
||||
cancel_refund = sudoConf.get_param('odex_takaful.cancel_refund')
|
||||
restriction_period = sudoConf.get_param('odex_takaful.restriction_period')
|
||||
res.update(
|
||||
{
|
||||
'cancel_refund': int(cancel_refund),
|
||||
'restriction_period': int(restriction_period),
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
return res
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
donation_extension_reminder_sms_template_id = fields.Many2one('sms.template', string="Donation Extension Reminder SMS Template")
|
||||
donation_ended_sms_template_id = fields.Many2one('sms.template', string="Donation Ended SMS Template")
|
||||
faal_kheer_partner_id = fields.Many2one("res.partner", string="Faal Kheer Partner")
|
||||
|
|
@ -0,0 +1,455 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import UserError, ValidationError, Warning
|
||||
from dateutil.parser import parse
|
||||
import re
|
||||
from odoo.osv import expression
|
||||
SAUDI_MOBILE_PATTERN = r"^(\+?966)?0?5[013456789][0-9]{7}$"
|
||||
|
||||
class IrActionsServer(models.Model):
|
||||
_inherit = 'ir.actions.server'
|
||||
|
||||
groups_id = fields.Many2many('res.groups', 'res_groups_server_rel', 'uid', 'gid', string='Groups')
|
||||
|
||||
|
||||
class sponsor(models.Model):
|
||||
_name = 'takaful.sponsor'
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_name = 'res.partner'
|
||||
_inherit = ['res.partner', 'mail.thread']
|
||||
|
||||
|
||||
account_number = fields.Char(string="Account Number")
|
||||
bank_entity_name = fields.Char(string="Bank Entity Name")
|
||||
name = fields.Char(string="Name", compute='get_partner_name', store=True, readonly=False)
|
||||
|
||||
#Location
|
||||
branch_custom_id = fields.Many2one('branch.settings', string="Branch")
|
||||
district_id = fields.Many2one('res.districts', string="District", domain="[('branch_custom_id','=',branch_custom_id)]")
|
||||
|
||||
# New Added
|
||||
notify_by_app = fields.Boolean(string='Notify By App', default=True)
|
||||
notify_by_sms = fields.Boolean(string='Notify By SMS', default=True)
|
||||
notify_for_pay = fields.Boolean(string='Paying Notify By App', default=True)
|
||||
notify_pay_by_app = fields.Boolean(string='Paying Notify By App', default=True)
|
||||
notify_pay_by_sms = fields.Boolean(string='Paying Notify By SMS', default=True)
|
||||
|
||||
name_in_certificate = fields.Boolean(string='Beneficiaries Names In Certificate', default=True)
|
||||
type_in_certificate = fields.Boolean(string='Beneficiaries Type In Certificate', default=True)
|
||||
duration_in_certificate = fields.Boolean(string='Sponsorship Duration In Certificate', default=True)
|
||||
|
||||
notify_month_day = fields.Integer(string="Notify Month Day", default=1)
|
||||
wait_cancel_day = fields.Integer(string="Waiting For Cancellation", default=2)
|
||||
# operation_ids = fields.One2many('takaful.sponsor.operation', 'sponsor_id', string="Operations Records")
|
||||
benefit_ids = fields.One2many('family.member', 'sponsor_related_id', string="Benefits Records")
|
||||
related_benefits_count = fields.Integer(compute="_compute_related_benefits_count")
|
||||
kafel_id = fields.Many2one('res.users')
|
||||
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('verified', 'Verified')
|
||||
], string='State',default='draft', tracking=True)
|
||||
|
||||
def _get_default_preferred_communication(self):
|
||||
"""Get first preferred communication method as default"""
|
||||
first_comm = self.env['preferred.communication'].search([], limit=1, order='id asc')
|
||||
return first_comm if first_comm else False
|
||||
|
||||
preferred_communication = fields.Many2one('preferred.communication', string="Preferred Communication", default=_get_default_preferred_communication)
|
||||
serial_code = fields.Char(string="Serial Code", readonly=True, copy=False)
|
||||
|
||||
responsible_user_ids = fields.Many2many(
|
||||
'res.users',
|
||||
'takaful_sponsor_user_rel',
|
||||
'sponsor_id',
|
||||
'user_id',
|
||||
string='Responsible Employees'
|
||||
)
|
||||
|
||||
operation_count = fields.Integer(
|
||||
compute='_compute_operation_count',
|
||||
string="# Of Operations",
|
||||
readonly=True
|
||||
)
|
||||
|
||||
kafalat_count = fields.Integer(
|
||||
compute='_compute_kafalat_count',
|
||||
string="# of Kafalat",
|
||||
readonly=True
|
||||
)
|
||||
contribution_count = fields.Integer(
|
||||
compute='_compute_contribution_count',
|
||||
string="# of Contributions",
|
||||
readonly=True
|
||||
)
|
||||
|
||||
active_counts = fields.Integer(
|
||||
string="Active Sponsors Count",
|
||||
)
|
||||
active = fields.Boolean(default=True)
|
||||
|
||||
gift_count = fields.Integer(
|
||||
compute='_compute_gift_count',
|
||||
string="# of Gifts",
|
||||
readonly=True
|
||||
)
|
||||
|
||||
|
||||
_sql_constraints = [
|
||||
('id_number_uniq', 'unique (id_number)', 'The ID Number Already Exist!'),
|
||||
]
|
||||
|
||||
|
||||
def view_sponsorship_payment_action(self):
|
||||
"""Enable The Sponsor To Pay Sponsorships Entries"""
|
||||
sponsorship_id = self.env['takaful.sponsorship'].sudo().search([('sponsor_id', '=', self.id), ('has_delay', '=', True)], limit=1)
|
||||
|
||||
context = dict(self.env.context or {})
|
||||
context['default_sponsor_id'] = self.id or False
|
||||
context['default_sponsorship_id'] = sponsorship_id.id or False
|
||||
return {
|
||||
'name': _('Sponsorship Payment'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'views': [(self.env.ref(
|
||||
'odex_takaful.takaful_sponsorship_payment_tree').id, 'tree'),
|
||||
(self.env.ref('odex_takaful.takaful_sponsorship_payment_form').id, 'form')],
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'sponsorship.payment',
|
||||
'domain': "[('sponsor_id','=',%s)]" % (self.id or False),
|
||||
'target': 'current',
|
||||
'context': context,
|
||||
}
|
||||
|
||||
|
||||
@api.constrains('is_family', 'is_benefit', 'is_donor', 'is_sponsor_portal')
|
||||
def _check_family_beneficiary_exclusivity(self):
|
||||
for rec in self:
|
||||
is_family_or_beneficiary = rec.is_family or rec.is_benefit
|
||||
|
||||
is_donor_vendor_sponsor = rec.is_donor or rec.is_sponsor_portal or rec.is_vendor
|
||||
|
||||
if is_family_or_beneficiary and is_donor_vendor_sponsor:
|
||||
raise ValidationError(_("A contact cannot be both Family/Beneficiary and Donor/Member/Sponsor at the same time!"))
|
||||
|
||||
@api.model
|
||||
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
|
||||
if not args:
|
||||
args = []
|
||||
domain = ['|', '|', ('name', operator, name),('id_number', operator, name),('mobile', operator, name)]
|
||||
domain = expression.AND([domain, args])
|
||||
parent_record_ids = self.search(domain).ids
|
||||
domain = expression.OR([domain, [('parent_id', 'in', parent_record_ids)]])
|
||||
return self._search(domain, limit=limit, access_rights_uid=name_get_uid)
|
||||
|
||||
def _compute_related_benefits_count(self):
|
||||
for record in self:
|
||||
record.related_benefits_count = self.env['family.member'].search_count([
|
||||
('sponsor_related_id', '=', record.id)
|
||||
])
|
||||
def action_open_benefit_records(self):
|
||||
"""Open related account.move records."""
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Related Benefits',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'family.member',
|
||||
'domain': [('id', 'in', self.benefit_ids.ids)],
|
||||
'context': {'create': False},
|
||||
}
|
||||
|
||||
def _compute_operation_count(self):
|
||||
# Get operation_count
|
||||
operation_count = self.env['takaful.sponsor.operation'].sudo().search_count([('sponsor_id', '=', self.id)])
|
||||
|
||||
if operation_count >0:
|
||||
self.operation_count = operation_count
|
||||
else:
|
||||
self.operation_count = 0
|
||||
|
||||
|
||||
def _compute_kafalat_count(self):
|
||||
# Get kafalat
|
||||
kafalat_count = self.env['takaful.sponsorship'].sudo().search_count([('sponsor_id', '=', self.id)])
|
||||
|
||||
if kafalat_count >0:
|
||||
self.kafalat_count = kafalat_count
|
||||
else:
|
||||
self.kafalat_count = 0
|
||||
|
||||
def _compute_contribution_count(self):
|
||||
# The current user may not have access rights for contributions.
|
||||
for partner in self:
|
||||
try:
|
||||
partner.contribution_count = len(partner.id) * 2
|
||||
except Exception:
|
||||
partner.contribution_count = 50
|
||||
|
||||
def _compute_gift_count(self):
|
||||
# The current user may not have access rights for gifts.
|
||||
for partner in self:
|
||||
try:
|
||||
partner.gift_count = len(partner.id) * 3
|
||||
except Exception:
|
||||
partner.gift_count = 75
|
||||
|
||||
#Validition here
|
||||
def check_bank_info_value(self):
|
||||
# all values true
|
||||
bank_info = [self.account_number,
|
||||
self.iban,
|
||||
self.bank_id,
|
||||
self.bank_entity_name,
|
||||
]
|
||||
|
||||
res = all(bank_info)
|
||||
return res
|
||||
|
||||
def unlink(self):
|
||||
related_contact = self.env['res.partner'].search([('parent_id', 'in', self.ids)])
|
||||
sponsorships = self.env['takaful.sponsorship'].search([('sponsor_id', 'in', self.ids)])
|
||||
if sponsorships or related_contact:
|
||||
raise UserError(_('Contacts are associated with sponsorships') )
|
||||
self.user_id.sudo().write({
|
||||
"active": False
|
||||
})
|
||||
return super(ResPartner, self).unlink()
|
||||
|
||||
def on_activate_sponsor_multi(self):
|
||||
for record in self:
|
||||
if not record.active:
|
||||
if record.user_id:
|
||||
record.user_id.sudo().write({
|
||||
"active": True
|
||||
})
|
||||
record.active = True
|
||||
else:
|
||||
raise UserError(_('Sponsor is already active'))
|
||||
|
||||
def action_save_and_close(self):
|
||||
"""Save and close the form wizard - used when creating new sponsor from sponsorship form"""
|
||||
self.ensure_one()
|
||||
# The form will close automatically and return to parent form
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
@api.model
|
||||
def create(self, values):
|
||||
mobile_number = values.get('mobile', False)
|
||||
context = self.env.context
|
||||
|
||||
if mobile_number:
|
||||
self._check_phone_numbers(values['mobile'])
|
||||
validated_mobile_number = self.phone_format(mobile_number)
|
||||
values.update({'mobile': validated_mobile_number})
|
||||
|
||||
if context.get('sponsor_contact'):
|
||||
values.update({'lang': 'ar_001'})
|
||||
values.update({'tz': 'Asia/Riyadh'})
|
||||
# values.update({'account_type':'sponsor'})
|
||||
values.update({'is_sponsor_portal': True})
|
||||
if not values.get('serial_code'):
|
||||
values['serial_code'] = self.env['ir.sequence'].next_by_code('takaful.sponsor.sequence') or 'S/0000'
|
||||
|
||||
res = super(ResPartner, self).create(values)
|
||||
|
||||
if context.get('sponsor_contact'):
|
||||
if context.get('parent_model') == 'takaful.sponsorship' and context.get('parent_id'):
|
||||
parent_record = self.env[context['parent_model']].browse(context['parent_id'])
|
||||
parent_record.sponsor_id = res.id
|
||||
|
||||
|
||||
if 'is_sponsor_portal' in values or 'is_donor' in values:
|
||||
if values['is_sponsor_portal'] == True or values['is_donor'] == True :
|
||||
if res.mobile != False:
|
||||
kafeel = self.env['res.users'].with_user(2).create({
|
||||
'name' : values['name'],
|
||||
'branch_custom_id':values['branch_custom_id'],
|
||||
'sel_groups_1_9_10' : 9,
|
||||
'partner_id' : res.id,
|
||||
'login' : values['mobile'],
|
||||
'otp_mobile_phone' : values['mobile'],
|
||||
'otp_enabled' : True,
|
||||
})
|
||||
res.kafel_id = kafeel
|
||||
|
||||
return res
|
||||
|
||||
def write(self, vals):
|
||||
if 'mobile' in vals:
|
||||
self._check_phone_numbers(vals['mobile'])
|
||||
vals['mobile'] = self.phone_format(vals['mobile'])
|
||||
if 'name' in vals :
|
||||
if self.kafel_id:
|
||||
self.kafel_id.name = vals['name']
|
||||
|
||||
if 'mobile' in vals :
|
||||
if self.kafel_id:
|
||||
self.kafel_id.login = vals['mobile']
|
||||
|
||||
res = super(ResPartner, self).write(vals)
|
||||
return res
|
||||
|
||||
def create_user(self):
|
||||
for follower in self.message_follower_ids:
|
||||
follower.sudo().unlink()
|
||||
# If you add 'no_reset_password' to the context to True, it won't send an email.
|
||||
# You can then set the password manually (and find a way to let the user know it).
|
||||
user = self.env['res.users'].sudo().with_context(no_reset_password=False).create({
|
||||
'name': self.name,
|
||||
'login': self.mobile,
|
||||
'phone': self.mobile,
|
||||
'mobile': self.mobile,
|
||||
'partner_id': self.id,
|
||||
'active': True,
|
||||
'city': self.city_id.name if self.city_id else False,
|
||||
'lang':'ar_001',
|
||||
'tz': 'Asia/Riyadh',
|
||||
})
|
||||
|
||||
# Add groups to the user as sponsor
|
||||
user.sudo().write({'groups_id': [
|
||||
# in odoo relation field accept a list of commands
|
||||
# command 4 means add the id in the second position must be an integer
|
||||
# ref return an object so we return the id
|
||||
(4, self.env.ref('odex_takaful.takaful_group_user_sponsor').id),
|
||||
(3, self.env.ref('base.group_user', False).id),
|
||||
(4, self.env.ref('base.group_portal', False).id)]
|
||||
})
|
||||
self.user_id = user.id
|
||||
return self
|
||||
|
||||
|
||||
def action_open_sponsor_operation(self):
|
||||
"""Open Operations History for a Sponsor"""
|
||||
domain = [('sponsor_id', '=', self.id or False)]
|
||||
context = dict(self.env.context or {})
|
||||
context['default_sponsor_id'] = self.id or False
|
||||
|
||||
return {
|
||||
'name': _('Sponsor Operations'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'view_id': False,
|
||||
'res_model': 'takaful.sponsor.operation',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'current',
|
||||
'domain': domain,
|
||||
'context': context,
|
||||
}
|
||||
|
||||
|
||||
def view_sponsorship_action(self):
|
||||
"""List Sponsorships For The Sponsor"""
|
||||
domain = [('sponsor_id', '=', self.id or False)]
|
||||
context = dict(self.env.context or {})
|
||||
context['default_sponsor_id'] = self.id or False
|
||||
|
||||
# view = self.env.ref('odex_takaful.takaful_sponsorship_tree')
|
||||
return {
|
||||
'name': _('Sponsorships'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'view_id': False,
|
||||
'res_model': 'takaful.sponsorship',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'current',
|
||||
'domain': domain,
|
||||
'context': context,
|
||||
}
|
||||
|
||||
@api.model
|
||||
def get_active_sponsors_users(self):
|
||||
sponsors_users = self.env['res.users'].sudo().search([
|
||||
("active", "=", True),
|
||||
("groups_id", "=", self.env.ref("odex_takaful.takaful_group_user_sponsor").id)])#self.env['res.users'].sudo().search([])
|
||||
|
||||
count = len(sponsors_users) or 0
|
||||
sponsors = self.env['res.partner'].sudo().search([])
|
||||
for rec in sponsors:
|
||||
rec.update({
|
||||
"active_counts": count,
|
||||
})
|
||||
|
||||
def show_active_sponsor_report_report(self):
|
||||
self.sudo().get_active_sponsors_users()
|
||||
ctx = self.env.context.copy()
|
||||
return {
|
||||
'name': _('Active Sponsors Count Report'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'res.partner',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'pivot',
|
||||
'view_id': self.env.ref('odex_takaful.active_sponsor_report_pivot_view').id,
|
||||
'target': 'main',
|
||||
'context': ctx,
|
||||
}
|
||||
|
||||
def _check_phone_numbers(self, mobile_number):
|
||||
for rec in self:
|
||||
mobile = str(mobile_number).strip().replace(" ", "").replace("-", "")
|
||||
if not re.fullmatch(SAUDI_MOBILE_PATTERN, mobile):
|
||||
raise ValidationError(_('Enter a valid Saudi mobile number'))
|
||||
|
||||
def action_unlink_sponsor_and_related(self):
|
||||
member_ids = self.env["family.member"].sudo().search([("sponsor_related_id", "in", self.ids)])
|
||||
if member_ids:
|
||||
member_ids.sudo().write({"sponsor_related_id": False})
|
||||
grant_partner_ids = self.env['grant.benefit'].sudo().search([
|
||||
('partner_id', 'in', self.ids),
|
||||
('state', 'not in', ['draft', 'new'])
|
||||
]).partner_id
|
||||
if grant_partner_ids:
|
||||
partner_ids = self.filtered(lambda p: p.id not in grant_partner_ids)
|
||||
partner_ids.sudo().write({'active': False})
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
for sponsor in self:
|
||||
name = sponsor.name
|
||||
if sponsor.mobile:
|
||||
name = sponsor.name + " - " + str(sponsor.mobile)
|
||||
result.append((sponsor.id, name))
|
||||
return result
|
||||
|
||||
@api.depends('company_type',
|
||||
'first_name',
|
||||
'second_name',
|
||||
'middle_name',
|
||||
'family_name',
|
||||
'sponsor_title',
|
||||
'suffix_title_id')
|
||||
def get_partner_name(self):
|
||||
for rec in self:
|
||||
names = []
|
||||
if rec.sponsor_title:
|
||||
names.append(f"{rec.sponsor_title.shortcut if rec.sponsor_title.shortcut else rec.sponsor_title.name}/")
|
||||
if rec.first_name:
|
||||
names.append(rec.first_name)
|
||||
if rec.second_name:
|
||||
names.append(rec.second_name)
|
||||
if rec.middle_name:
|
||||
names.append(rec.middle_name)
|
||||
if rec.family_name:
|
||||
names.append(rec.family_name)
|
||||
if rec.suffix_title_id:
|
||||
names.append(f"({rec.suffix_title_id.shortcut if rec.suffix_title_id.shortcut else rec.suffix_title_id.name})")
|
||||
if names:
|
||||
rec.name = " ".join(names)
|
||||
else:
|
||||
rec.name = " "
|
||||
|
||||
class ResPartnerBank(models.Model):
|
||||
_inherit = 'res.partner.bank'
|
||||
|
||||
def name_get(self):
|
||||
result = []
|
||||
for bank in self:
|
||||
if bank.bank_id:
|
||||
name = f"{bank.acc_number} - {bank.bank_id.name}"
|
||||
else:
|
||||
name = f"{bank.acc_number}"
|
||||
result.append((bank.id, name))
|
||||
return result
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class SchedulingLine(models.Model):
|
||||
_name = 'sponsorship.scheduling.line'
|
||||
|
||||
sponsorship_id = fields.Many2one('takaful.sponsorship')
|
||||
sponsorship_state = fields.Selection(related='sponsorship_id.state')
|
||||
donation_detail_linked_id = fields.Many2one('donations.details.lines')
|
||||
sequence_no = fields.Char(default='/', readonly=True, copy=False)
|
||||
beneficiary_id = fields.Many2one('family.member')
|
||||
month_year = fields.Char()
|
||||
scheduled_date = fields.Date(string='Scheduled Date', help='Date when the payment should be automatically processed')
|
||||
amount = fields.Float()
|
||||
refunded_amount = fields.Float(string='Refunded Amount')
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
default=lambda self: self.env.company.currency_id, readonly=True)
|
||||
status = fields.Selection([
|
||||
('unpaid', 'Unpaid'),
|
||||
('paid', 'Paid'),
|
||||
('approve_refund', 'Approve Refund'),
|
||||
('under_refund', 'Under Refund'),
|
||||
('partial_refund', 'Partial Refund'),
|
||||
('fully_refund', 'Fully Refund'),
|
||||
], copy=False, default='unpaid')
|
||||
sponsor_id = fields.Many2one('res.partner')
|
||||
direct_debit = fields.Boolean(string='Direct Debit', related='donation_detail_linked_id.direct_debit')
|
||||
cancel_refund = fields.Boolean(string='Cancel Refund Time', compute="compute_days_after_payment")
|
||||
|
||||
def compute_days_after_payment(self):
|
||||
"""Check if the number of hours passed after payment is within the configured limit"""
|
||||
for record in self:
|
||||
days_passed = 0
|
||||
config_param = record.env['ir.config_parameter'].sudo()
|
||||
max_hours = int(config_param.get_param('odex_takaful.cancel_refund', default=0))
|
||||
|
||||
payment_record = record.env['payment.details.lines'].search([
|
||||
'|',
|
||||
('sponsorship_scheduling_line_id', '=', record.id),
|
||||
('sponsorship_scheduling_line_ids', 'in', record.id),
|
||||
('sponsorship_id', '=', record.sponsorship_id.id)
|
||||
|
||||
], order="payment_date desc", limit=1)
|
||||
|
||||
if payment_record and payment_record.payment_date:
|
||||
now = fields.Datetime.now()
|
||||
payment_datetime = fields.Datetime.to_datetime(payment_record.payment_date)
|
||||
hours_passed = (now - payment_datetime).total_seconds() / 3600 # Convert seconds to hours
|
||||
record.cancel_refund = hours_passed >= max_hours
|
||||
else:
|
||||
record.cancel_refund = False
|
||||
|
||||
|
||||
def action_register_payment(self):
|
||||
invoice_id = self.env['account.move'].sudo().search([
|
||||
('takaful_sponsorship_id', '=', self.sponsorship_id.id),
|
||||
('move_type', '=', 'out_invoice'),
|
||||
('state', '=', 'posted'),
|
||||
('payment_state', 'in', ['not_paid', 'partial'])], limit=1, order='id')
|
||||
if not invoice_id:
|
||||
raise ValidationError(_("No invoice found for this sponsorship."))
|
||||
return {
|
||||
'name': _('Register Payment'),
|
||||
'res_model': 'account.payment.register',
|
||||
'view_mode': 'form',
|
||||
'context': {
|
||||
'active_model': 'account.move',
|
||||
'active_ids': invoice_id.ids,
|
||||
'dont_redirect_to_payments': True,
|
||||
'sponsorship_line_ids': self.donation_detail_linked_id.ids,
|
||||
'default_amount': self.amount,
|
||||
'default_journal_id': self.env.company.sponsorship_direct_debit_journal_id.id,
|
||||
'schedule_line_payment': True,
|
||||
'schedule_line_id': self.id,
|
||||
'force_sponsorship_line_partner_id': self.donation_detail_linked_id.sponsor_id.id,
|
||||
},
|
||||
'target': 'new',
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
# Check if sequence_no is not already set
|
||||
if vals.get('sequence_no', '/') == '/':
|
||||
# Assign the next sequence number
|
||||
vals['sequence_no'] = self.env['ir.sequence'].next_by_code('sponsorship.scheduling.line.sequence') or '/'
|
||||
return super(SchedulingLine, self).create(vals)
|
||||
|
||||
@api.model
|
||||
def cron_process_scheduled_payments(self):
|
||||
today = fields.Date.today()
|
||||
|
||||
scheduled_lines = self.search([
|
||||
('scheduled_date', '<=', today),
|
||||
('status', '=', 'unpaid'),
|
||||
])
|
||||
|
||||
_logger.info(f"Found {len(scheduled_lines)} scheduling lines scheduled for {today}")
|
||||
|
||||
for line in scheduled_lines:
|
||||
donation_line = line.donation_detail_linked_id
|
||||
sponsorship = donation_line.sponsorship_id or donation_line.sponsorship_mechanism_id
|
||||
|
||||
try:
|
||||
if line.donation_detail_linked_id.direct_debit:
|
||||
invoice_id = self.env['account.move'].sudo().search([
|
||||
('takaful_sponsorship_id', '=', sponsorship.id),
|
||||
('move_type', '=', 'out_invoice'),
|
||||
('state', '=', 'posted'),
|
||||
('payment_state', 'in', ['not_paid', 'partial'])
|
||||
], limit=1)
|
||||
|
||||
if not invoice_id:
|
||||
_logger.warning(f"No unpaid invoice found for sponsorship {line.sponsorship_id.code}, skipping line {line.sequence_no}")
|
||||
continue
|
||||
|
||||
journal_id = self.env.company.sponsorship_direct_debit_journal_id
|
||||
if not journal_id:
|
||||
_logger.warning(f"No journal found for payment method of line {line.sequence_no}")
|
||||
continue
|
||||
|
||||
payment_register_vals = {
|
||||
'payment_date': fields.Date.today(),
|
||||
'amount': line.amount,
|
||||
'journal_id': journal_id.id,
|
||||
'partner_bank_id': donation_line.direct_debit_partner_bank_id.id,
|
||||
'communication': f"{line.sponsorship_id.code} - {line.sequence_no}",
|
||||
'transaction_file_attachment': donation_line.debit_payment_file_attachment,
|
||||
}
|
||||
|
||||
payment_register = self.env['account.payment.register'].sudo().with_context(
|
||||
active_model='account.move',
|
||||
active_ids=invoice_id.ids,
|
||||
schedule_line_payment=True,
|
||||
dont_redirect_to_payments=True,
|
||||
schedule_line_id=line.id,
|
||||
is_direct_debit=True,
|
||||
sponsorship_id=sponsorship.id,
|
||||
sponsorship_line_ids=line.donation_detail_linked_id.ids,
|
||||
from_cron=True,
|
||||
force_sponsorship_line_partner_id=line.donation_detail_linked_id.sponsor_id.id,
|
||||
).create(payment_register_vals)
|
||||
|
||||
payment_register.action_create_payments()
|
||||
line.sudo().write({'status': 'paid'})
|
||||
if line.donation_detail_linked_id.state == 'waiting' or (not line.donation_detail_linked_id.benefit_id and line.donation_detail_linked_id.record_type == 'sponsorship'):
|
||||
line.donation_detail_linked_id.sudo().write({'state': 'waiting'})
|
||||
elif line.donation_detail_linked_id.record_type == 'donation':
|
||||
line.donation_detail_linked_id.sudo().write({'state': 'paid'})
|
||||
elif line.donation_detail_linked_id.state != 'waiting' and line.donation_detail_linked_id.record_type != 'donation' and line.donation_detail_linked_id.record_type == 'sponsorship':
|
||||
line.donation_detail_linked_id.sudo().write({'state': 'active'})
|
||||
line.donation_detail_linked_id.sponsorship_id.sudo().write({'state': 'wait_pay'})
|
||||
|
||||
|
||||
_logger.info(f"Successfully processed scheduled payment for line {line.sequence_no}")
|
||||
else:
|
||||
_logger.warning(f"Scheduling line {line.sequence_no} payment method is not direct debit, skipping auto-payment")
|
||||
|
||||
except Exception as e:
|
||||
_logger.error(f"Error processing scheduled payment for line {line.sequence_no}: {str(e)}")
|
||||
continue
|
||||
|
||||
return True
|
||||
|
||||
def action_refund(self):
|
||||
refund_amount = self.amount - self.refunded_amount
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Refund Wizard',
|
||||
'res_model': 'refund.wiz',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {'default_refund_amount': refund_amount}
|
||||
}
|
||||
|
||||
|
||||
def approve_refund(self):
|
||||
self.final_refund()
|
||||
self.sponsorship_id.state = 'under_refund'
|
||||
|
||||
|
||||
def final_refund(self):
|
||||
invoice_lines = []
|
||||
unpaid_invoice_exists = self.env['account.move'].search(
|
||||
[('takaful_sponsorship_id', '=', self.sponsorship_id.id), ('move_type', '=', 'out_refund'),
|
||||
('payment_state', '!=', 'paid')])
|
||||
refund_amount = self.sponsorship_id.refund_details_lines_ids.filtered(
|
||||
lambda r: r.sponsorship_scheduling_line.id == self.id or self.id in r.sponsorship_scheduling_line_ids.ids and r.invoiced == False).mapped('refund_amount')[0] if self.sponsorship_id.refund_details_lines_ids else 0.0
|
||||
sponsor_id = self.sponsorship_id.sponsor_id
|
||||
payment_details_line = self.sponsorship_id.refund_details_lines_ids.filtered(
|
||||
lambda r: r.sponsorship_scheduling_line.id == self.id or self.id in r.sponsorship_scheduling_line_ids.ids).mapped('payment_details_line')
|
||||
|
||||
if unpaid_invoice_exists:
|
||||
raise ValidationError(_("You have Refund invoice not paid"))
|
||||
|
||||
# Check if product exists from donation item
|
||||
product_template = self.donation_detail_linked_id.product_template_id
|
||||
product = self.donation_detail_linked_id.product_id # Directly linked product
|
||||
|
||||
if not product:
|
||||
# If no product_id exists in product_template, check if a product with the same name exists
|
||||
product = self.env['product.product'].search([('name', '=', product_template.name)], limit=1)
|
||||
|
||||
if not product:
|
||||
# Create new product if it doesn't exist
|
||||
product = self.env['product.product'].create({
|
||||
'name': product_template.name,
|
||||
'type': 'service' # Setting type to service
|
||||
})
|
||||
|
||||
invoice_lines.append((0, 0, {
|
||||
'product_id': product.id,
|
||||
'account_id': self.donation_detail_linked_id.product_template_id.property_account_income_id.id,
|
||||
# The same account for all lines
|
||||
'quantity': 1, # Qty is 1
|
||||
# The same analytic account
|
||||
'takaful_sponsorship_id': self.sponsorship_id.id,
|
||||
'price_unit': refund_amount,
|
||||
'analytic_account_id': self.sponsorship_id.branch_custom_id.branch.analytic_account_id.id
|
||||
}))
|
||||
Partner = self.env['res.partner'].sudo()
|
||||
partner_id = sponsor_id or Partner.search([('name', '=', 'Cash Customer')], limit=1)
|
||||
if not partner_id:
|
||||
partner_id = Partner.create({
|
||||
'company_type': 'person',
|
||||
'name': 'Cash Customer'
|
||||
})
|
||||
|
||||
invoice = self.env['account.move'].create({
|
||||
'move_type': 'out_refund', # Refund Invoice
|
||||
'partner_id': partner_id.id,
|
||||
'invoice_date': fields.Date.today(),
|
||||
'invoice_line_ids': invoice_lines,
|
||||
'takaful_sponsorship_id': self.sponsorship_id.id,
|
||||
'is_refund_sponsorship': True,
|
||||
'sponsorship_scheduling_line': self.id,
|
||||
'payment_details_line': payment_details_line,
|
||||
})
|
||||
invoice.action_post()
|
||||
self.sponsorship_id.refund_details_lines_ids.write({'invoiced': True})
|
||||
return invoice
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
from odoo.exceptions import UserError , ValidationError
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
class SponsorshipStates(models.Model):
|
||||
_name = "sponsorship.states"
|
||||
_description = "SponsorshipS States"
|
||||
_rec_name = 'display_name'
|
||||
|
||||
name = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('confirmed', 'Confirmed'),
|
||||
('wait_pay', 'Enter Payment Details'),
|
||||
('paid', 'Paid'),
|
||||
('partial_refund', 'Partial Refund'),
|
||||
('fully_refund', 'Fully Refund'),
|
||||
('approve_refund', 'Approve Refund'),
|
||||
('under_refund', 'Under Refund Procedure'),
|
||||
('under_replacement', 'Under Replacement'),
|
||||
('replacement_done', 'Replacement Done'),
|
||||
('canceled', 'Canceled'),
|
||||
('closed', 'Closed'),
|
||||
], string='State', default='draft', required=True)
|
||||
|
||||
display_name = fields.Char(string="Display Name", compute='_compute_display_name')
|
||||
|
||||
@api.depends('name')
|
||||
def _compute_display_name(self):
|
||||
selection_dict = dict(self._fields['name'].selection)
|
||||
for rec in self:
|
||||
rec.display_name = _(selection_dict.get(rec.name, rec.name))
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
from odoo.exceptions import UserError , ValidationError
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
class DonationsItems(models.Model):
|
||||
_name = "donations.items"
|
||||
_description = "Donation Items"
|
||||
|
||||
name = fields.Char(string="Donation Name")
|
||||
donation_type = fields.Selection([('donation', 'Donation'),('waqf', 'Waqf'),('sponsorship', 'Sponsorship'),], string='Donation Type')
|
||||
branch_custom_id = fields.Many2one('branch.settings', string="Branch")
|
||||
show_donation_item = fields.Boolean(string='Show Donation Item')
|
||||
fixed_value = fields.Boolean(string='Is Fixed Value?')
|
||||
fixed_donation_amount = fields.Float(string='Donation Amount')
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
default=lambda self: self.env.company.currency_id, readonly=True)
|
||||
account_id = fields.Many2one('account.account', string="Account",domain="[('user_type_id.id','=',13)]")
|
||||
product_id = fields.Many2one('product.product', string="Product", domain="[('type', '=', 'service')]")
|
||||
_quantity = fields.Float(default=0, store=True)
|
||||
donation_types = fields.Selection([('donation', 'Donation'), ('waqf', 'Waqf')],string='Donation Type')
|
||||
payment_method_id = fields.Many2one('takaful.payment.method', string="Payment Method")
|
||||
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
"""Automatically create a product when a donation item is created"""
|
||||
donation_item = super(DonationsItems, self).create(vals)
|
||||
|
||||
# Create a related product
|
||||
product = self.env['product.product'].create({
|
||||
'name': donation_item.name,
|
||||
'type': 'service',
|
||||
})
|
||||
|
||||
# Link the created product to the donation item
|
||||
donation_item.product_id = product.id
|
||||
|
||||
return donation_item
|
||||
|
||||
@api.onchange('name')
|
||||
def _onchange_name(self):
|
||||
"""Update the related product name when the donation item name changes"""
|
||||
if self.product_id:
|
||||
self.product_id.name = self.name
|
||||
|
||||
def add_payment_method(self):
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _('Add Details Wizard'),
|
||||
'res_model': 'add.details.wiz',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
def utilizable_cart_details(self):
|
||||
"""
|
||||
Utilizable Cart Details For Remove , Add And Update Operations
|
||||
For Cart To Product Catelog Module To Object addcart.sales.products
|
||||
"""
|
||||
|
||||
context = self._context.copy() or {}
|
||||
cart_object = self.env["donations.details.lines"]
|
||||
cart_details = dict()
|
||||
total_count = cart_object.search_count(
|
||||
[('donation_name', '=', self.id), ('sponsorship_id', '=', context.get('sponsorship_id'))]) # , ("cart_flag", "=", True)
|
||||
cart_details["total_count"] = total_count
|
||||
cart_data = cart_object.search(
|
||||
[('donation_name', '=', self.id), ('sponsorship_id', '=', context.get('sponsorship_id'))]) # , ("cart_flag", "=", True)
|
||||
cart_details["cart_data"] = cart_data
|
||||
return cart_details
|
||||
|
||||
def initiate_sol(self, operation, sponsorship_id):
|
||||
"""
|
||||
Initiate Donation Details Lines By Cart Functionality.
|
||||
"""
|
||||
|
||||
so_object = self.env["takaful.sponsorship"]
|
||||
sale_object = so_object.search([("id", "=", sponsorship_id)])
|
||||
if operation == "add":
|
||||
so_object.sol_by_cart(operation, self, sale_object)
|
||||
elif operation == "remove":
|
||||
so_object.sol_by_cart(operation, self, sale_object)
|
||||
elif operation == "update":
|
||||
so_object.sol_by_cart(operation, self, sale_object)
|
||||
|
||||
def set_quantity_so(self, quantity, operation=None):
|
||||
context = self._context.copy() or {}
|
||||
cart_details = self.utilizable_cart_details()
|
||||
if operation == "remove":
|
||||
self._quantity -= quantity
|
||||
if cart_details.get("total_count") != 0:
|
||||
self.initiate_sol("remove", context.get("sponsorship_id"))
|
||||
else:
|
||||
if self._quantity == 0:
|
||||
self._quantity += quantity
|
||||
if cart_details.get("total_count") != 0:
|
||||
self.initiate_sol("update", context.get("sponsorship_id"))
|
||||
else:
|
||||
self.initiate_sol("add", context.get("sponsorship_id"))
|
||||
|
||||
def remove_quantity_button_so(self):
|
||||
if self._quantity == 0:
|
||||
self._quantity = 0
|
||||
return
|
||||
return self.set_quantity_so(1, operation="remove")
|
||||
|
||||
def add_quantity_button_so(self):
|
||||
return self.set_quantity_so(1, operation="add")
|
||||
|
||||
|
||||
|
||||
|
||||
class PointsOfSaleCustom(models.Model):
|
||||
_name = "points.of.sale.custom"
|
||||
_description = "Points Of Sale Custom"
|
||||
|
||||
name = fields.Char(string="Sequence/Point Name",readonly=True)
|
||||
department_name = fields.Selection([('men', 'Men'),('women', 'Women')], string='Department Name')
|
||||
branch_custom_ids = fields.Many2many('branch.settings',relation='points_sale_branch_settings_rel',column1='points_sale_id', column2='branch_id',string="Branch")
|
||||
journal_id = fields.Many2one('account.journal', string="Journal",domain="[('type','=','bank')]")
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
res = super(PointsOfSaleCustom, self).create(vals)
|
||||
if not res.name or res.name == _('New'):
|
||||
res.name = self.env['ir.sequence'].sudo().next_by_code('point.of.sale.sequence') or _('New')
|
||||
return res
|
||||
|
||||
class RefundReason(models.Model):
|
||||
_name = "refund.reasons"
|
||||
_description = "Refund Reason"
|
||||
|
||||
name = fields.Char(string="Name")
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo.exceptions import UserError , ValidationError
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TakafulContribution(models.Model):
|
||||
_name = "takaful.contribution"
|
||||
_description = "Financial Contribution"
|
||||
|
||||
name = fields.Char(string="Operation Name")
|
||||
sponsor_id = fields.Many2one(
|
||||
'res.partner',
|
||||
string='The Sponsor',
|
||||
ondelete='set null'
|
||||
)
|
||||
need_id = fields.Many2one('benefits.needs')
|
||||
benefit_id = fields.Many2one(
|
||||
'grant.benefit',
|
||||
string='Beneficiary',
|
||||
ondelete='set null'
|
||||
)
|
||||
benefit_ids = fields.Many2many(
|
||||
'grant.benefit',
|
||||
string='Beneficiaries'
|
||||
)
|
||||
benefit_type = fields.Selection([
|
||||
('orphan', 'Orphans'),
|
||||
('widow', 'Widows'),
|
||||
('general', 'General')],
|
||||
string='Beneficiaries Type',
|
||||
compute='_compute_benefit_type_values',
|
||||
related=False,
|
||||
readonly=True,
|
||||
)
|
||||
operation_type = fields.Selection([
|
||||
('contribution', 'Needs Contribution'),
|
||||
('gift', 'Financial Gift')],
|
||||
string='Operation Type',
|
||||
)
|
||||
amount = fields.Float(string="Amount")
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
default=lambda self: self.env.company.currency_id, readonly=True)
|
||||
note = fields.Text(string='Note/Message')
|
||||
date = fields.Datetime(string="Date", default=fields.Datetime.now)
|
||||
entry_id = fields.Many2one('account.move', string="Entry")
|
||||
is_confirmed = fields.Boolean(default=False)
|
||||
|
||||
def _compute_benefit_type_values(self):
|
||||
for rec in self:
|
||||
b_type = []
|
||||
if rec.benefit_ids:
|
||||
for i in rec.benefit_ids:
|
||||
b_type.append(i.benefit_type)
|
||||
if rec.benefit_id:
|
||||
b_type.append(rec.benefit_id.benefit_type)
|
||||
if 'orphan' in b_type and 'widow' not in b_type:
|
||||
rec.benefit_type = 'orphan'
|
||||
if 'widow' in b_type and 'orphan' not in b_type:
|
||||
rec.benefit_type = 'widow'
|
||||
if 'widow' in b_type and 'orphan' in b_type:
|
||||
rec.benefit_type = 'general'
|
||||
if b_type == []:
|
||||
rec.benefit_type = ''
|
||||
|
||||
def create_entry(self):
|
||||
sudoConf = self.env['ir.config_parameter'].sudo()
|
||||
journal_id = sudoConf.get_param('odex_takaful_base.kafala_journal_id', default=False)
|
||||
if not journal_id:
|
||||
# Raise an error
|
||||
raise ValidationError(
|
||||
_(u'No Journal for Sponsorships, Please configure it'))
|
||||
|
||||
need_inv = self.env['needs.payment.line'].sudo().create({
|
||||
"need_id" : self.need_id.id,
|
||||
"invoice_id" : inv.id,
|
||||
})
|
||||
|
||||
product_id = self.env['product.product'].search([('default_code', '=', 'financial_gift')], limit=1)
|
||||
partner_id = self.sponsor_id
|
||||
|
||||
product_id.sudo().write({
|
||||
"list_price": self.amount,
|
||||
})
|
||||
|
||||
# Do your staf ..
|
||||
this_products_line = [[0, 0, {'product_id': product_id.id,
|
||||
'tax_id': False,
|
||||
}]
|
||||
]
|
||||
|
||||
so_id = self.env['sale.order'].create({
|
||||
'partner_id': partner_id.id,
|
||||
'partner_invoice_id': partner_id.id,
|
||||
'partner_shipping_id': partner_id.id,
|
||||
'client_order_ref': u'مساهمة مالية',
|
||||
'note': u'مساهمة مالية لصالح:' + '\n' + (self.benefit_id.name if self.benefit_id else ""),
|
||||
'order_line': this_products_line
|
||||
})
|
||||
|
||||
# Invoicing
|
||||
so_id.action_confirm()
|
||||
inv_id = so_id.action_invoice_create()
|
||||
inv = self.env['account.move'].browse(inv_id)
|
||||
inv.journal_id = int(journal_id)
|
||||
|
||||
move_name = u'مساهمة مالية بالأمر %s' % inv.origin
|
||||
ctx = self.env.context.copy()
|
||||
ctx.update({'sponsorship' : {
|
||||
'name': move_name,
|
||||
'ref': inv.origin,
|
||||
}
|
||||
})
|
||||
inv.with_context(ctx).action_invoice_open()
|
||||
|
||||
self.entry_id = inv.move_id.id
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,372 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from datetime import datetime, date, timedelta
|
||||
from datetime import timedelta
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from dateutil.parser import parse
|
||||
from odoo.exceptions import UserError, ValidationError, Warning
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TakafulGrantBenefit(models.Model):
|
||||
_inherit = "grant.benefit"
|
||||
|
||||
is_active_sponsorship = fields.Boolean(
|
||||
string="Currently Has Sponsorship?", compute='_get_sponsorship_ids')
|
||||
|
||||
sponsorship_ids = fields.Many2many(
|
||||
'takaful.sponsorship', string='Sponsorships', compute='_get_sponsorship_ids')
|
||||
has_kafala_delay = fields.Boolean(
|
||||
string='Has Kafala Delay?', compute='_get_sponsorship_ids')
|
||||
overdue_kafalat_amount = fields.Float(
|
||||
string="Current Overdue Kafalat Amount", compute='_get_sponsorship_ids')
|
||||
|
||||
# These fields work to calculate the value of the need and its percentage
|
||||
total_kafala_value = fields.Integer(
|
||||
string='Total Kafala Value', compute='_needs_value')
|
||||
benefit_needs_value = fields.Float(compute='_needs_value')
|
||||
benefit_needs_percent = fields.Float(compute='_needs_value')
|
||||
|
||||
# Monthly sponsorship Payments
|
||||
# sponsorship_payment_ids = fields.One2many(
|
||||
# 'benefit.sponsorship.payment.line',
|
||||
# 'benefit_id', 'Sponsorship Monthly Payments')
|
||||
|
||||
# @api.onchange('arrears_ids')
|
||||
# def _compute_sponsorships_arrears(self):
|
||||
# for rec in self:
|
||||
# rec.benefit_arrears_value = sum(rec.arrears_ids.mapped('arrears_total'))
|
||||
|
||||
@api.onchange('total_expenses', 'total_income')
|
||||
def _needs_value(self):
|
||||
for rec in self:
|
||||
rec.total_kafala_value = rec.total_expenses
|
||||
kafala_income = 0.0
|
||||
for kafala in rec.sponsorship_ids:
|
||||
# if kafala.state not in ['draft', 'canceled', 'closed']: #todo
|
||||
kafala_income += kafala.contribution_value
|
||||
rec.benefit_needs_value = abs(
|
||||
rec.total_expenses - rec.total_income - kafala_income) # todo
|
||||
try:
|
||||
rec.benefit_needs_percent = 100 - \
|
||||
(((rec.total_income + kafala_income) / rec.total_kafala_value) * 100)
|
||||
except:
|
||||
rec.benefit_needs_percent = 0.0
|
||||
pass
|
||||
|
||||
def _get_sponsorship_ids(self):
|
||||
""" Get Sponsorships of Benefit"""
|
||||
for rec in self:
|
||||
sponsorships = self.env['takaful.sponsorship'].sudo().search(
|
||||
[('benefit_id', '=', rec.id), ('state', 'in', ['wait_pay', 'progress', 'to_cancel'])])
|
||||
overdue_kafala = 0
|
||||
ls_ids = []
|
||||
|
||||
today = datetime.today().date().replace(day=1)
|
||||
for spon in sponsorships:
|
||||
spon._compute_next_due_date()
|
||||
ls_ids.append(spon.id)
|
||||
if spon.has_delay:
|
||||
start_date = parse(str(spon.start_date)).date().replace(day=1)
|
||||
if spon.paid_month_count > 0:
|
||||
last_pay_date = start_date + \
|
||||
relativedelta(months=spon.paid_month_count)
|
||||
else:
|
||||
spon._compute_next_due_date()
|
||||
last_pay_date = (spon.next_due_date or start_date +
|
||||
relativedelta(months=spon.paid_month_count))
|
||||
|
||||
if spon.paid_month_count == 0:
|
||||
num_months = 1
|
||||
else:
|
||||
num_months = (today.year - last_pay_date.year) * \
|
||||
12 + (today.month - last_pay_date.month)
|
||||
|
||||
overdue_kafala += (num_months * spon.contribution_value)
|
||||
|
||||
if ls_ids:
|
||||
rec.sponsorship_ids = [(6, 0, ls_ids)]
|
||||
rec.is_active_sponsorship = True
|
||||
else:
|
||||
rec.sponsorship_ids = [(6, 0, [])]
|
||||
rec.is_active_sponsorship = False
|
||||
|
||||
if overdue_kafala > 0:
|
||||
rec.has_kafala_delay = True
|
||||
rec.overdue_kafalat_amount = overdue_kafala
|
||||
else:
|
||||
rec.has_kafala_delay = False
|
||||
rec.overdue_kafalat_amount = 0
|
||||
|
||||
|
||||
class GrantBenefitInvoice(models.Model):
|
||||
_name = "grant.benefit.invoice"
|
||||
_description = 'Invoice for Beneficiaries'
|
||||
# _rec_name = 'code'
|
||||
|
||||
benefit_ids = fields.Many2many('grant.benefit', string='Beneficiaries')
|
||||
operation_invoice_id = fields.Many2one('account.move',
|
||||
string="Invoice", ondelete='set null', readonly=True)
|
||||
operation_code = fields.Char(string='Operation Code', readonly=True)
|
||||
operation_type = fields.Selection([
|
||||
('sponsorship', 'Sponsorship'),
|
||||
('financial_gift', 'Financial Gift'),
|
||||
('need_contribution', 'Needs Contribution')],
|
||||
string='Operation Type',
|
||||
)
|
||||
operation_id = fields.Integer(readonly=True)
|
||||
benefit_type = fields.Selection([
|
||||
('orphan', 'Orphans'),
|
||||
('widow', 'Widows')],
|
||||
string='Beneficiaries Type',
|
||||
)
|
||||
benefit_target = fields.Selection([
|
||||
('person', 'Individual'),
|
||||
('group', 'Group')],
|
||||
string='Target of Beneficiaries',
|
||||
)
|
||||
paid_amount = fields.Float(string='Paid Amount', readonly=True)
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
default=lambda self: self.env.company.currency_id, readonly=True)
|
||||
partner_id = fields.Many2one('res.partner', string='From',
|
||||
store=True,
|
||||
related='operation_invoice_id.partner_id')
|
||||
journal_id = fields.Many2one('account.journal', string='Journal',
|
||||
store=True,
|
||||
related='operation_invoice_id.journal_id')
|
||||
due_date = fields.Date(string='Due Date', store=True,
|
||||
related='operation_invoice_id.invoice_date')
|
||||
due_code = fields.Char(string='Due Code', store=True,
|
||||
compute='_get_due_code', )
|
||||
payment_date = fields.Date(string='Payment Date', readonly=True)
|
||||
note = fields.Text(string='Note/Message')
|
||||
is_recorded = fields.Boolean(
|
||||
string='Is Recorded In Beneficiaries', default=False)
|
||||
|
||||
def _get_due_code(self):
|
||||
""" Extract due code from due date """
|
||||
for rec in self:
|
||||
if rec.due_date:
|
||||
date = parse(str(rec.due_date)).date()
|
||||
rec.due_code = date.strftime("%Y_%m")
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
_inherit = "account.move"
|
||||
|
||||
benefit_invoice_ids = fields.One2many('grant.benefit.invoice', 'operation_invoice_id',
|
||||
string='The Beneficiaries', ondelete='restrict')
|
||||
|
||||
|
||||
class AccountPayment(models.Model):
|
||||
_inherit = "account.payment"
|
||||
|
||||
direct_debit = fields.Boolean(string='Direct Debit', default=False)
|
||||
is_benefit_registered = fields.Boolean(
|
||||
string='Is Registered To Beneficiary', default=False)
|
||||
|
||||
def sponsorship_validate_invoice_payment(self, invoice):
|
||||
|
||||
sponsorship_obj = self.env['takaful.sponsorship'].sudo().browse(
|
||||
invoice.operation_id)
|
||||
# Create an invoice for benefits.
|
||||
benefit_invoice = self.env['grant.benefit.invoice'].sudo().create({
|
||||
'operation_invoice_id': invoice.id,
|
||||
'operation_type': 'sponsorship',
|
||||
'operation_id': sponsorship_obj.id,
|
||||
'operation_code': sponsorship_obj.code,
|
||||
'benefit_type': sponsorship_obj.benefit_type,
|
||||
'benefit_target': sponsorship_obj.sponsorship_type,
|
||||
'paid_amount': self.amount,
|
||||
'payment_date': self.payment_date,
|
||||
})
|
||||
|
||||
if sponsorship_obj.sponsorship_type == 'person':
|
||||
benefit_invoice.write(
|
||||
{'benefit_ids': [(4, sponsorship_obj.benefit_id.id)]})
|
||||
else:
|
||||
for benefit in sponsorship_obj.benefit_ids:
|
||||
benefit_invoice.write({'benefit_ids': [(4, benefit.id)]})
|
||||
|
||||
if invoice.state == 'paid':
|
||||
self.is_benefit_registered = True
|
||||
|
||||
# Change State
|
||||
if not sponsorship_obj.has_delay:
|
||||
sponsorship_obj.state = "progress"
|
||||
|
||||
# Send SMS and Email Notifications
|
||||
paid_template = self.env['takaful.message.template'].search(
|
||||
[('template_name', '=', 'sponsorship_paid')], limit=1)
|
||||
|
||||
subject = paid_template.title
|
||||
message = paid_template.body + '\n' + _('Sponsorship: ') + '{}'.format(sponsorship_obj.code) + '\n' + _(
|
||||
'Paid Value: ') + '{}'.format(self.amount) + '\n' + _('Invoice Ref: ') + '{}'.format(invoice.number)
|
||||
user_id = sponsorship_obj.sponsor_id.user_id
|
||||
|
||||
push = self.env['takaful.push.notification'].sudo().create({
|
||||
'user_id': user_id.id,
|
||||
'title': subject,
|
||||
'body': message,
|
||||
})
|
||||
|
||||
push.sudo().send_sms_notification()
|
||||
push.sudo().send_email_notification()
|
||||
|
||||
def action_validate_invoice_payment(self):
|
||||
res = super(AccountPayment, self).action_validate_invoice_payment()
|
||||
# Handle payment for every invoice
|
||||
for invoice in self.invoice_ids:
|
||||
# move = invoice.invoice_id
|
||||
if invoice.operation_type == 'sponsorship':
|
||||
self.sudo().sponsorship_validate_invoice_payment(invoice)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
class TakafulGrantBenefit(models.Model):
|
||||
_inherit = "grant.benefit"
|
||||
|
||||
@api.model
|
||||
def create(self, values):
|
||||
name = values.get('name', False)
|
||||
if name is False:
|
||||
first_name = values.get('first_name')
|
||||
second_name = values.get('second_name')
|
||||
middle_name = values.get('middle_name')
|
||||
family_name = values.get('family_name')
|
||||
name = ''
|
||||
if all([second_name,first_name,middle_name,family_name]):
|
||||
name = first_name + " " + second_name + " " + middle_name + " " + family_name
|
||||
values.update({'name': name})
|
||||
values.update({'lang': 'ar_001'})
|
||||
values.update({'tz': 'Asia/Riyadh'})
|
||||
return super(TakafulGrantBenefit, self).create(values)
|
||||
|
||||
arrears_ids = fields.One2many(
|
||||
'sponsorship.benefit.arrears', 'sponsor_id', string="Sponsorships Arrears")
|
||||
benefit_arrears_value = fields.Float(
|
||||
string='Total Sponsorships Arrears', compute='_compute_sponsorships_arrears', store=True)
|
||||
has_arrears = fields.Boolean(
|
||||
string='Has Arrears', compute='_compute_sponsorships_arrears', store=True)
|
||||
# analytic_account_id = fields.Many2one(
|
||||
# 'account.analytic.account', 'Cost Center')
|
||||
|
||||
def finish_complete_data(self):
|
||||
for rec in self:
|
||||
res = super(TakafulGrantBenefit, self).finish_complete_data()
|
||||
# main_analytic_account_id = ""
|
||||
# self.ensure_one()
|
||||
# sudoConf = self.env['ir.config_parameter'].sudo()
|
||||
# main_widows_analytic_account_id = sudoConf.get_param(
|
||||
# 'odex_benefit.main_widows_analytic_account_id', default=False)
|
||||
# main_orphan_analytic_account_id = sudoConf.get_param(
|
||||
# 'odex_benefit.main_orphan_analytic_account_id', default=False)
|
||||
# if rec.benefit_type == "orphan":
|
||||
# if not main_orphan_analytic_account_id:
|
||||
# raise ValidationError(
|
||||
# _(''' Please set orphan restricted income account in settings '''))
|
||||
# main_analytic_account_id = main_orphan_analytic_account_id
|
||||
# elif rec.benefit_type == "widow":
|
||||
# if not main_widows_analytic_account_id:
|
||||
# raise ValidationError(
|
||||
# _(''' Please set widow restricted income account in settings '''))
|
||||
# main_analytic_account_id = main_widows_analytic_account_id
|
||||
# if main_analytic_account_id and not rec.analytic_account_id:
|
||||
# ID = self.env['account.analytic.account'].create({'parent_id': main_analytic_account_id,'name': rec.name})
|
||||
# rec.write({'analytic_account_id': ID.id})
|
||||
def action_accepted(self):
|
||||
for rec in self:
|
||||
res = super(TakafulGrantBenefit, self).action_accepted()
|
||||
# main_analytic_account_id = ""
|
||||
# self.ensure_one()
|
||||
# sudoConf = self.env['ir.config_parameter'].sudo()
|
||||
# main_widows_analytic_account_id = sudoConf.get_param(
|
||||
# 'odex_benefit.main_widows_analytic_account_id', default=False)
|
||||
# main_orphan_analytic_account_id = sudoConf.get_param(
|
||||
# 'odex_benefit.main_orphan_analytic_account_id', default=False)
|
||||
# if rec.benefit_type == "orphan":
|
||||
# if not main_orphan_analytic_account_id:
|
||||
# raise ValidationError(
|
||||
# _(''' Please set orphan restricted income account in settings '''))
|
||||
# main_analytic_account_id = main_orphan_analytic_account_id
|
||||
# elif rec.benefit_type == "widow":
|
||||
# if not main_widows_analytic_account_id:
|
||||
# raise ValidationError(
|
||||
# _(''' Please set widow restricted income account in settings '''))
|
||||
# main_analytic_account_id = main_widows_analytic_account_id
|
||||
# if main_analytic_account_id and not rec.analytic_account_id:
|
||||
# ID = self.env['account.analytic.account'].create({'parent_id': main_analytic_account_id,'name': rec.name})
|
||||
# rec.write({'analytic_account_id': ID.id})
|
||||
|
||||
@api.onchange('arrears_ids')
|
||||
def _compute_sponsorships_arrears(self):
|
||||
for rec in self:
|
||||
rec.benefit_arrears_value = sum(
|
||||
rec.arrears_ids.mapped('arrears_total'))
|
||||
if rec.benefit_arrears_value > 0:
|
||||
rec.has_arrears = True
|
||||
else:
|
||||
rec.has_arrears = False
|
||||
|
||||
|
||||
class SponsorshipBenefitArrears(models.Model):
|
||||
_name = "sponsorship.benefit.arrears"
|
||||
_description = 'Sponsorship Arrears for a Beneficiary'
|
||||
_rec_name = 'code'
|
||||
|
||||
benefit_id = fields.Many2one('grant.benefit', string='Beneficiary')
|
||||
benefit_type = fields.Selection(
|
||||
string="Beneficiary Type", related="benefit_id.benefit_type", store=True)
|
||||
sponsorship_id = fields.Many2one(
|
||||
'takaful.sponsorship',
|
||||
string='Sponsorship'
|
||||
)
|
||||
sponsor_id = fields.Many2one(
|
||||
'res.partner',
|
||||
string='The Sponsor',
|
||||
ondelete='set null'
|
||||
)
|
||||
code = fields.Char(string="Sponsorship Number",
|
||||
related="sponsorship_id.code", store=True)
|
||||
month_amount = fields.Float(string="Month Sponsorship Amount",
|
||||
related="sponsorship_id.load_amount", store=True, readonly=True)
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
default=lambda self: self.env.company.currency_id, readonly=True)
|
||||
arrears_month_number = fields.Integer(string="Arrears Months Number")
|
||||
arrears_total = fields.Float(string="Arrears Total")
|
||||
date = fields.Date('Date', readonly=True, default=fields.Date.today())
|
||||
is_paid = fields.Float(string="Is Paid", compute='_get_arrears_amount')
|
||||
paid_amount = fields.Float(
|
||||
string="Paid Amount", compute='_get_arrears_amount', store=True)
|
||||
arrears_amount = fields.Float(
|
||||
string="Remine Arrears Amount", compute='_get_arrears_amount', store=True)
|
||||
invoice_ids = fields.Many2many(
|
||||
'account.move', string='Payment Invoices')
|
||||
|
||||
def _get_arrears_amount(self):
|
||||
""" Compute Arrears Amount, Paid and Remine"""
|
||||
for rec in self:
|
||||
if rec.invoice_ids:
|
||||
paid_amount = 0
|
||||
for inv in rec.invoice_ids:
|
||||
if inv.state == 'paid':
|
||||
paid_amount += inv.amount
|
||||
|
||||
if paid_amount > 0:
|
||||
rec.paid_amount = paid_amount
|
||||
rec.arrears_amount = abs(rec.arrears_total - paid_amount)
|
||||
else:
|
||||
rec.paid_amount = 0
|
||||
rec.arrears_amount = rec.arrears_total
|
||||
|
||||
if paid_amount >= rec.arrears_total:
|
||||
rec.is_paid = True
|
||||
else:
|
||||
rec.is_paid = False
|
||||
else:
|
||||
rec.is_paid = False
|
||||
rec.arrears_amount = rec.arrears_total
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _
|
||||
from datetime import datetime, date, timedelta
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
|
||||
from ..utils import formats
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from dateutil.parser import parse
|
||||
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MonthPayment(models.Model):
|
||||
_name = 'month.payment'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
|
||||
name = fields.Char(string="Name")
|
||||
code = fields.Char(string="Code", copy=False, readonly=True, default=lambda x: _('New'))
|
||||
journal_id = fields.Many2one('account.journal')
|
||||
account_id = fields.Many2one('account.account', )
|
||||
date = fields.Date(string="Date", default=fields.Datetime.now)
|
||||
amount = fields.Float(string="Total Amount", compute='_compute_payment_total', store=True)
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
default=lambda self: self.env.company.currency_id, readonly=True)
|
||||
count = fields.Integer(string="Count", compute='_compute_payment_total', store=True)
|
||||
user_id = fields.Many2one('res.users', string="Issued By", default=lambda self: self.env.user)
|
||||
company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.user.company_id)
|
||||
line_ids = fields.One2many('month.payment.line', 'month_id', string="Lines")
|
||||
due_invoice_ids = fields.Many2many('grant.benefit.invoice', string="Due Payments")
|
||||
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('create', 'Create Lines'),
|
||||
('approve', 'Approved'),
|
||||
('submit', 'Submit To Pay'),
|
||||
('paid', 'Paid'),
|
||||
('refused', 'Refused'),
|
||||
('cancel', 'Cancel'),
|
||||
], string='state', default="draft", tracking=True)
|
||||
|
||||
month_code = fields.Char(string="Month Code", store=True, compute='_compute_payment_month_code')
|
||||
entry_id = fields.Many2one('account.move', string="Entry")
|
||||
|
||||
@api.depends('line_ids')
|
||||
def _compute_payment_total(self):
|
||||
for rec in self:
|
||||
if rec.line_ids:
|
||||
rec.amount = sum(rec.line_ids.mapped('amount'))
|
||||
rec.count = len(rec.line_ids)
|
||||
else:
|
||||
rec.amount = 0
|
||||
rec.count = 0
|
||||
|
||||
@api.onchange('name', 'date')
|
||||
def _compute_payment_name(self):
|
||||
if self.date and not self.name:
|
||||
date = parse(str(self.date)).date()
|
||||
self.name = _('Sponsorship Due Payments') + ' {}'.format(date.strftime("%m-%Y"))
|
||||
|
||||
def _compute_payment_month_code(self):
|
||||
""" Extract month code from date """
|
||||
for rec in self:
|
||||
if rec.date:
|
||||
date = parse(str(rec.date)).date()
|
||||
rec.month_code = date.strftime("%Y_%m")
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
res = super(MonthPayment, self).create(vals)
|
||||
if not res.code or res.code == _('New'):
|
||||
res.code = self.env['ir.sequence'].sudo().next_by_code('month.payment.sequence') or _('New')
|
||||
return res
|
||||
|
||||
def open_payments(self):
|
||||
return {
|
||||
'name': _('Payments'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'views': [(self.env.ref(
|
||||
'odex_takaful.benefit_month_payment_line_tree').id, 'tree'),
|
||||
(self.env.ref('odex_takaful.benefit_month_payment_line_form').id, 'form')],
|
||||
'res_model': 'month.payment.line',
|
||||
'type': 'ir.actions.act_window',
|
||||
'domain': "[('month_id','=',%s)]" % (self.id),
|
||||
'target': 'current',
|
||||
}
|
||||
|
||||
def action_create_lines(self):
|
||||
if not self.line_ids:
|
||||
due_invoices = self.env['grant.benefit.invoice'].sudo().search([
|
||||
('operation_type', '=', 'sponsorship'),
|
||||
('due_code', '=', self.month_code),
|
||||
('is_recorded', '=', False),
|
||||
])
|
||||
|
||||
for rec in due_invoices:
|
||||
if rec.benefit_target == "person" and len(rec.benefit_ids) ==1:
|
||||
line = self.env['month.payment.line'].sudo().create({
|
||||
'month_id': self.id,
|
||||
'sponsorship_id': rec.operation_id,
|
||||
'benefit_id': rec.benefit_ids[0].id,
|
||||
'responsible_id': rec.benefit_ids[0].responsible_id.id if rec.benefit_ids[0].responsible_id else False,
|
||||
'partner_id': rec.benefit_ids[0].responsible_id.partner_id.id if rec.benefit_ids[0].responsible_id else False,
|
||||
'amount': rec.paid_amount,
|
||||
'date': datetime.now(),
|
||||
})
|
||||
else:
|
||||
amount = (rec.paid_amount / len(rec.benefit_ids))
|
||||
now = datetime.now()
|
||||
for ben in rec.benefit_ids:
|
||||
line = self.env['month.payment.line'].sudo().create({
|
||||
'month_id': self.id,
|
||||
'sponsorship_id': rec.operation_id,
|
||||
'benefit_id': ben.id,
|
||||
'responsible_id': ben.responsible_id.id if ben.responsible_id else False,
|
||||
'partner_id': ben.responsible_id.partner_id.id if ben.responsible_id else False,
|
||||
'amount': amount,
|
||||
'date': now,
|
||||
})
|
||||
|
||||
self.write({'due_invoice_ids': [(4, rec.id)]})
|
||||
|
||||
# Now true for rec.is_recorded
|
||||
# rec.is_recorded = True
|
||||
|
||||
self.state = 'create'
|
||||
|
||||
|
||||
def create_entry(self):
|
||||
move_name = self.name + ' - %s' % self.code
|
||||
move_id = self.env['account.move'].sudo().create({
|
||||
'name': move_name,
|
||||
'journal_id': self.company_id.kafala_benefit_journal_id.id,
|
||||
'ref': self.code})
|
||||
move_line = []
|
||||
move_line.append({
|
||||
'debit': self.amount,
|
||||
'credit': 0.0,
|
||||
'account_id': self.company_id.kafala_benefit_account_id.id,
|
||||
})
|
||||
move_line.append({
|
||||
'debit': 0.0,
|
||||
'credit': self.amount,
|
||||
'account_id': self.company_id.kafala_benefit_bank_account_id.id,
|
||||
})
|
||||
|
||||
move_id.write({'line_ids': [(0, 0, line) for line in move_line]})
|
||||
move_id.post()
|
||||
self.entry_id = move_id.id
|
||||
|
||||
for inv in self.due_invoice_ids:
|
||||
inv.is_recorded = True
|
||||
|
||||
def action_notify(self):
|
||||
if self.state == 'submit':
|
||||
payment = self.env['month.payment.line'].search([('month_id', '=', self.id)])
|
||||
for i in payment:
|
||||
if i.responsible_id.email:
|
||||
email_from = self.env.user.company_id.email
|
||||
company_name = self.env.user.company_id.name
|
||||
|
||||
template_id = self.env.ref('odex_takaful.push_notification_email_template').id
|
||||
context = {
|
||||
'email_from': email_from,
|
||||
'email_to': i.responsible_id.email,
|
||||
'partner_name': i.responsible_id.name,
|
||||
'body': _("You have recieved money in tolal of %s in your account.") % str(i.amount),
|
||||
'title': _("Recieving Money"),
|
||||
'company_name': company_name
|
||||
}
|
||||
|
||||
# Start to SEND Email
|
||||
self.env['mail.template'].browse(template_id).with_context(context).send_mail(self.id, force_send=True, raise_exception=False)
|
||||
|
||||
self.state = 'paid'
|
||||
else:
|
||||
raise ValidationError(
|
||||
_(u' No benefits for pay'))
|
||||
|
||||
def action_approve(self):
|
||||
if self.line_ids:
|
||||
self.sudo().create_entry()
|
||||
self.state = 'approve'
|
||||
|
||||
def action_refuse(self):
|
||||
self.state = 'refused'
|
||||
|
||||
def action_submit(self):
|
||||
self.state = 'submit'
|
||||
|
||||
def action_cancel(self):
|
||||
for i in self.line_ids:
|
||||
i.sudo().unlink()
|
||||
self.state = 'cancel'
|
||||
|
||||
|
||||
class MonthPaymentLine(models.Model):
|
||||
_name = 'month.payment.line'
|
||||
_rec_name = 'month_id'
|
||||
|
||||
month_id = fields.Many2one('month.payment')
|
||||
sponsorship_id = fields.Many2one("takaful.sponsorship", string="Sponsorship")
|
||||
s_code = fields.Char(string="Sponsorship Number", related="sponsorship_id.code",store=True)
|
||||
sponsor_id = fields.Many2one(string="The Sponsor", related="sponsorship_id.sponsor_id",store=True)
|
||||
benefit_id = fields.Many2one('grant.benefit', string="Benefit")
|
||||
benefit_type = fields.Selection(string="Benefit Type", related="benefit_id.benefit_type",store=True)
|
||||
responsible_id = fields.Many2one('grant.benefit', string="Responsible Benefit")
|
||||
partner_id = fields.Many2one('res.partner', string="Responsible Partner")
|
||||
date = fields.Date(string="Date")
|
||||
state = fields.Selection(related="month_id.state", store=True)
|
||||
code = fields.Char(related="month_id.code", store=True)
|
||||
amount = fields.Float(string="Amount")
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
default=lambda self: self.env.company.currency_id, readonly=True)
|
||||
|
||||
"""
|
||||
@api.model
|
||||
def payment_cron(self):
|
||||
payment = self.env['month.payment'].search([('state', '=', 'approve'), ('date', '=', str(datetime.now().date())),
|
||||
('line_ids', '=', False)], limit=1)
|
||||
if payment:
|
||||
payment.action_create_lines()
|
||||
|
||||
def create_records(self, benefits, support=False):
|
||||
if benefits:
|
||||
self.sudo().is_benefits = True
|
||||
for p in benefits:
|
||||
p.get_amount_month()
|
||||
amount = float("{:.2f}".format(p.amount * self.amount))
|
||||
if self.is_appendix:
|
||||
payment = self.env['month.payment.line'].search([('month_id', '=', self.parent_id.id)])
|
||||
for i in payment:
|
||||
amount += i.amount
|
||||
line = self.env['month.payment.line'].sudo().create({
|
||||
'month_id': self.id,
|
||||
'benefit_id': p.id,
|
||||
'responsible_id': p.id if not support else p.parent_id.id,
|
||||
'amount': amount,
|
||||
'date': datetime.now(),
|
||||
})
|
||||
if self.is_appendix:
|
||||
|
||||
payment = self.env['month.payment.line'].search([('month_id', '=', self.id)])
|
||||
self.amount = 0.0
|
||||
for pay in payment:
|
||||
self.amount += pay.amount
|
||||
|
||||
def action_create_lines(self):
|
||||
if not self.line_ids:
|
||||
if not self.parent_id:
|
||||
benefit = self.env['grant.benefit'].search([('state', '=', 'approve')])
|
||||
benefits = benefit.filtered(lambda r: r.benefit_type in ['benefit', 'support'])
|
||||
self.create_records(benefits)
|
||||
parent = benefit.filtered(lambda r: r.benefit_type == 'parent')
|
||||
self.get_child(parent)
|
||||
self.get_child(benefits)
|
||||
else:
|
||||
ben = self.parent_id.line_ids.mapped('benefit_id')
|
||||
benefit = self.env['grant.benefit'].search([('state', '=', 'approve')])
|
||||
benefits = benefit.filtered(lambda r: r.benefit_type in ['benefit', 'support'] and r.id not in ben.ids)
|
||||
self.create_records(benefits)
|
||||
parent = benefit.filtered(lambda r: r.benefit_type == 'parent')
|
||||
self.get_child(parent, sub=ben.ids)
|
||||
self.get_child(benefits, sub=ben.ids)
|
||||
self.state = 'create'
|
||||
"""
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class TakafulNotification(models.Model):
|
||||
_inherit = 'takaful.notification'
|
||||
|
||||
name = fields.Char(string='Notification Name', required=True)
|
||||
notification_type = fields.Selection([
|
||||
('create_kafala', _('Create Kafala')),
|
||||
('before_finish', _('Before Kafala End Date')),
|
||||
('after_kafala_end', _('After Kafala End Date')),
|
||||
('cancel_kafala', _('Cancel Kafala')),
|
||||
('refund_full_kafala', _('Fully Refund Kafala')),
|
||||
('refund_partial_kafala', _('Partially refund Kafala')),
|
||||
('replace_orphan', _('Replace Orphan / Widow')),
|
||||
('full_payment', _('Full Payment')),
|
||||
('partial_payment', _('Partial Payment')),
|
||||
('before_cancel', _('Before Cancel')),
|
||||
],
|
||||
string='Notification Type',
|
||||
default='create_kafala',
|
||||
required=True
|
||||
)
|
||||
|
||||
notification_state_ids = fields.Many2many('sponsorship.states', required=True)
|
||||
|
||||
message = fields.Html(string="Message")
|
||||
|
||||
|
||||
|
||||
@api.onchange('notification_type')
|
||||
def _onchange_notification_type(self):
|
||||
"""Filter available states based on notification_type."""
|
||||
if not self.notification_type:
|
||||
return
|
||||
|
||||
allowed_states = {
|
||||
'create_kafala': ['draft'],
|
||||
'before_finish': ['confirmed', 'wait_pay'],
|
||||
'after_kafala_end': ['paid', 'closed'],
|
||||
'cancel_kafala': ['canceled'],
|
||||
'refund_full_kafala': ['fully_refund'],
|
||||
'refund_partial_kafala': ['partial_refund'],
|
||||
'replace_orphan': ['under_replacement', 'replacement_done'],
|
||||
'full_payment': ['paid'],
|
||||
'partial_payment': ['wait_pay'],
|
||||
'before_cancel': ['confirmed'],
|
||||
}
|
||||
|
||||
state_names = allowed_states.get(self.notification_type, [])
|
||||
|
||||
domain = [('name', 'in', state_names)]
|
||||
|
||||
if allowed_states:
|
||||
self.notification_state_ids = self.env['sponsorship.states'].search(domain)
|
||||
|
||||
return {
|
||||
'domain': {
|
||||
'notification_state_ids': domain
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
|
||||
|
||||
class TakafulPaymentMethod(models.Model):
|
||||
_name = 'takaful.payment.method'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
payment_method = fields.Selection([
|
||||
("cash", "Cash"),
|
||||
("bank", "Bank Transfer"),
|
||||
("direct_debit", "Direct Debit"),
|
||||
("check", "Check"),
|
||||
("network", "Network"),
|
||||
], required=True)
|
||||
|
||||
journal_id = fields.Many2one('account.journal', string="Journal", required=True)
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
class TakafulMessageTemplate(models.Model):
|
||||
_name = "takaful.message.template"
|
||||
_description = "Message Template"
|
||||
_rec_name = 'title'
|
||||
|
||||
title = fields.Char(string='Subject')
|
||||
body = fields.Text(string='Message', required=True)
|
||||
template_name = fields.Char('Template Name', readonly=True, copy=False)
|
||||
|
||||
_sql_constraints = [
|
||||
('template_name_uniq', 'unique (template_name)', 'Template Name Is Already Exist!')
|
||||
]
|
||||
|
||||
|
||||
class TakafulPushNotification(models.Model):
|
||||
_name = 'takaful.push.notification'
|
||||
_description = 'Push Notification'
|
||||
|
||||
user_id = fields.Many2one('res.users', string="Sponsor User", required=True)
|
||||
email = fields.Char(string='Email', related='user_id.login',store=True)
|
||||
mobile = fields.Char(string='Mobile', related='user_id.phone',store=True)
|
||||
|
||||
title = fields.Char(string='Subject')
|
||||
body = fields.Text(string='Message', required=True)
|
||||
sent_on = fields.Datetime(string="Sent On", default=fields.Datetime.now)
|
||||
|
||||
is_read = fields.Boolean(string="Seen", default=False)
|
||||
|
||||
# @api.multi
|
||||
def send_sms_notification(self):
|
||||
self.ensure_one()
|
||||
return self.user_id.partner_id.sudo().send_sms_notification(body=self.body, phone=self.mobile)
|
||||
|
||||
# @api.multi
|
||||
def send_email_notification(self):
|
||||
self.ensure_one()
|
||||
if not all([self.email, self.body]):
|
||||
# Missing email message information"
|
||||
return False
|
||||
|
||||
email_from = self.env.user.company_id.email
|
||||
company_name = self.env.user.company_id.name
|
||||
|
||||
template_id = self.env.ref('odex_takaful.push_notification_email_template').id
|
||||
context = {
|
||||
'email_from': email_from,
|
||||
'email_to': self.email,
|
||||
'partner_name': self.user_id.partner_id.name,
|
||||
'body': self.body,
|
||||
'title': self.title or _("Notification"),
|
||||
'company_name': company_name
|
||||
}
|
||||
try:
|
||||
# Start to SEND Email
|
||||
self.env['mail.template'].browse(template_id).with_context(context).send_mail(self.id, force_send=True)
|
||||
except Exception as e:
|
||||
return False
|
||||
|
||||
"""
|
||||
And getting the values (context) in email template
|
||||
${ctx.get('your_key')}
|
||||
"""
|
||||
# Email is SENT ...
|
||||
return True
|
||||
|
||||
# @api.multi
|
||||
def send_all(self):
|
||||
self.ensure_one()
|
||||
for tool in self.notification_type_ids:
|
||||
if tool.tool_type == "sms":
|
||||
sms = self.send_sms_notification()
|
||||
if sms:
|
||||
print("SMS is sent.")
|
||||
|
||||
elif tool.tool_type == "app":
|
||||
print("App message is sent.")
|
||||
|
||||
elif tool.tool_type == "email":
|
||||
email= self.send_email_notification()
|
||||
if email:
|
||||
print("Email is sent.")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,74 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, _
|
||||
from dateutil.parser import parse
|
||||
|
||||
|
||||
class TakafulSponsorOperation(models.Model):
|
||||
_name = 'takaful.sponsor.operation'
|
||||
# _rec_name = 'sponsor_id'
|
||||
|
||||
name = fields.Char(string="Operation Name")
|
||||
title = fields.Char(string="Operation Title")
|
||||
sponsor_id = fields.Many2one(
|
||||
'res.partner',
|
||||
string='The Sponsor',
|
||||
ondelete='set null'
|
||||
)
|
||||
benefit_ids = fields.Many2many(
|
||||
'grant.benefit',
|
||||
string='Beneficiaries'
|
||||
)
|
||||
benefit_id = fields.Many2one(
|
||||
'grant.benefit',
|
||||
string='Beneficiary',
|
||||
ondelete='set null'
|
||||
)
|
||||
benefit_type = fields.Selection([
|
||||
('orphan', 'Orphans'),
|
||||
('widow', 'Widows'),
|
||||
('general', 'General')],
|
||||
string='Beneficiaries Type',
|
||||
compute='_compute_benefit_type_value',
|
||||
related=False,
|
||||
readonly=True,
|
||||
)
|
||||
operation_type = fields.Selection([
|
||||
('sponsorship', 'Sponsorship'),
|
||||
('contribution', 'Needs Contribution'),
|
||||
('gift', 'Financial Gift')],
|
||||
string='Operation Type',
|
||||
)
|
||||
date = fields.Date(string="Date", default=fields.Date.today)
|
||||
operation_on = fields.Datetime(string="Operation Time", default=fields.Datetime.now)
|
||||
month = fields.Integer(string="The Month", compute='_compute_period_filter')
|
||||
origin_id = fields.Integer(readonly=True)
|
||||
period_code = fields.Char(string="Period Code", compute='_compute_period_filter')
|
||||
amount = fields.Float(string="Amount")
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
default=lambda self: self.env.company.currency_id, readonly=True)
|
||||
|
||||
def _compute_period_filter(self):
|
||||
""" Extract period code from date """
|
||||
for rec in self:
|
||||
if rec.date:
|
||||
date = parse(str(rec.date)).date()
|
||||
rec.period_code = date.strftime("%Y_%m")
|
||||
rec.month = int(date.strftime("%m"))
|
||||
|
||||
def _compute_benefit_type_value(self):
|
||||
for rec in self:
|
||||
b_type = []
|
||||
if rec.benefit_ids:
|
||||
for i in rec.benefit_ids:
|
||||
b_type.append(i.benefit_type)
|
||||
if rec.benefit_id:
|
||||
b_type.append(rec.benefit_id.benefit_type)
|
||||
if 'orphan' in b_type and 'widow' not in b_type:
|
||||
rec.benefit_type = 'orphan'
|
||||
if 'widow' in b_type and 'orphan' not in b_type:
|
||||
rec.benefit_type = 'widow'
|
||||
if 'widow' in b_type and 'orphan' in b_type:
|
||||
rec.benefit_type = 'general'
|
||||
if b_type == []:
|
||||
rec.benefit_type = ''
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _
|
||||
from odoo import SUPERUSER_ID
|
||||
|
||||
|
||||
class SponsorshipStopReason(models.Model):
|
||||
_name = "sponsorship.reason.stop"
|
||||
_description = "Sponsorship Stop Reason"
|
||||
_order = 'sequence'
|
||||
|
||||
sequence = fields.Integer(help="Determine the display order", index=True,
|
||||
string='Sequence')
|
||||
name = fields.Char(string='Reason', required=True)
|
||||
|
||||
class SponsorshipCancellation(models.Model):
|
||||
_name = 'sponsorship.cancellation'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
_description = "Sponsorship Cancellation"
|
||||
_rec_name = "code"
|
||||
|
||||
sponsorship_id = fields.Many2one("takaful.sponsorship", string="Sponsorship")
|
||||
code = fields.Char(string="Sponsorship Number", related="sponsorship_id.code",store=True)
|
||||
sponsor_id = fields.Many2one(string="The Sponsor", related="sponsorship_id.sponsor_id",store=True)
|
||||
create_date = fields.Date(string='Create Date', readonly=True, default=fields.Date.today)
|
||||
confirm_date = fields.Date(string='Confirm Date', readonly=True)
|
||||
cancel_type = fields.Selection([
|
||||
('user', 'Manually'),
|
||||
('sys', 'Automatically'),
|
||||
], string='Cancellation Type', default="user", readonly=True)
|
||||
cancel_user_id = fields.Many2one('res.users', 'Cancelled By', readonly=True)
|
||||
confirm_user_id = fields.Many2one('res.users', 'Confirmed By', readonly=True)
|
||||
reason_id = fields.Many2one('sponsorship.reason.stop', string='Cancellation Reason')
|
||||
note = fields.Text(string='Comment')
|
||||
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('cancel', 'Cancelled'),
|
||||
], string='state', default="draft")
|
||||
|
||||
|
||||
# @api.multi
|
||||
def do_cancel_action(self):
|
||||
"""Confirm cancellation for Sponsorship"""
|
||||
for rec in self:
|
||||
if rec.sponsorship_id:
|
||||
rec.confirm_user_id = self.env.uid or SUPERUSER_ID
|
||||
rec.confirm_date = fields.Date.today()
|
||||
rec.state = "cancel"
|
||||
|
||||
# Send SMS and Email Notifications
|
||||
canceled_template = self.env['takaful.message.template'].sudo().search(
|
||||
[('template_name', '=', 'sponsorship_canceled')], limit=1)
|
||||
|
||||
subject = canceled_template.title
|
||||
message = canceled_template.body
|
||||
partner_id = rec.sponsor_id
|
||||
user_id = self.env['res.users'].sudo().search([('partner_id', '=', partner_id.id)], limit=1)
|
||||
|
||||
push = self.env['takaful.push.notification'].sudo().create({
|
||||
'user_id': user_id.id,
|
||||
'title': subject,
|
||||
'body': message,
|
||||
})
|
||||
|
||||
push.sudo().send_sms_notification()
|
||||
push.sudo().send_email_notification()
|
||||
|
||||
month_count = 0
|
||||
residual_amount = 0
|
||||
|
||||
# Get other open invoices
|
||||
open_invoices = self.env['account.move'].sudo().search([('state', '=', 'open'), ('operation_id', '=', rec.sponsorship_id.id), ('operation_type', '=', 'sponsorship')])
|
||||
for inv in open_invoices:
|
||||
# Get residual amount
|
||||
month_count += 1
|
||||
residual_amount += inv.residual_company_signed
|
||||
# Enable Removing for journal_id
|
||||
if inv.journal_id:
|
||||
inv.journal_id.sudo().write({"update_posted": True,})
|
||||
|
||||
inv.sudo().action_cancel()
|
||||
|
||||
rec.sponsorship_id.journal_entry_ids.button_draft()
|
||||
rec.sponsorship_id.journal_entry_ids.button_cancel()
|
||||
rec.sponsorship_id.state = "canceled"
|
||||
rec.sponsorship_id.cancel_reason_id = self.id
|
||||
|
||||
# Moving the arrears
|
||||
if month_count >0 and rec.sponsorship_id.sponsorship_type =='person':
|
||||
arrears_id = self.env['sponsorship.benefit.arrears'].sudo().create({
|
||||
'sponsorship_id': rec.sponsorship_id.id,
|
||||
'benefit_id': rec.sponsorship_id.benefit_id.id,
|
||||
'sponsor_id': rec.sponsorship_id.sponsor_id.id,
|
||||
'arrears_month_number': month_count,
|
||||
'arrears_total': residual_amount,
|
||||
})
|
||||
elif month_count >0 and rec.sponsorship_id.sponsorship_type =='group':
|
||||
for ben in rec.sponsorship_id.benefit_ids:
|
||||
arrears_id = self.env['sponsorship.benefit.arrears'].sudo().create({
|
||||
'sponsorship_id': rec.sponsorship_id.id,
|
||||
'benefit_id': ben.id,
|
||||
'sponsor_id': rec.sponsorship_id.sponsor_id.id,
|
||||
'arrears_month_number': month_count,
|
||||
'arrears_total': rec.sponsorship_id.load_amount * month_count,
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _
|
||||
from dateutil.parser import parse
|
||||
from odoo.exceptions import UserError,ValidationError, Warning
|
||||
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SponsorshipPayment(models.Model):
|
||||
_name = 'sponsorship.payment'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
_description = "Payments for Sponsorship system in Takaful project"
|
||||
_rec_name = 'code'
|
||||
_order = 'date desc'
|
||||
|
||||
sponsorship_id = fields.Many2one(
|
||||
'takaful.sponsorship',
|
||||
string='Sponsorship'
|
||||
)
|
||||
|
||||
sponsor_id = fields.Many2one(
|
||||
'res.partner',
|
||||
string='Sponsor Name'
|
||||
)
|
||||
code = fields.Char(string="Sponsorship Number", related="sponsorship_id.code",store=True)
|
||||
|
||||
payment_month_number = fields.Integer(string="Sponsorships Number To Pay")
|
||||
month_amount = fields.Float(string="Sponsorship Amount", related="sponsorship_id.contribution_value",store=True, readonly=True)
|
||||
amount = fields.Float(string="Total Amount", compute="get_amount_month", store=True)
|
||||
currency_id = fields.Many2one('res.currency', string='Currency',
|
||||
default=lambda self: self.env.company.currency_id, readonly=True)
|
||||
iban = fields.Char(string='IBAN / Account Number', tracking=True)
|
||||
transfer_receipt = fields.Binary(string='Transfer Receipt')
|
||||
bank_id = fields.Many2one('res.bank', string="Bank Name")
|
||||
has_bank_account = fields.Boolean(string="Has Another Account?")
|
||||
payment_method = fields.Char(string='Method Of Payment', store=False)
|
||||
|
||||
user_id = fields.Many2one('res.users',string="Issued By", default=lambda self: self.env.user)
|
||||
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('financial', 'Financial'),
|
||||
('paid', 'Paid'),
|
||||
], string='state', default="draft", tracking=True)
|
||||
|
||||
date = fields.Date('Date', readonly=True,default=fields.Date.today())
|
||||
invoice_ids = fields.Many2many('account.move', string="Invoices")
|
||||
is_invoiced = fields.Boolean(string='Is Invoiced?', compute='check_is_invoiced')
|
||||
|
||||
def check_is_invoiced(self):
|
||||
for rec in self:
|
||||
if rec.invoice_ids and rec.state == "financial":
|
||||
total_paid = 0
|
||||
for invoice in rec.invoice_ids:
|
||||
if invoice.state == 'paid':
|
||||
payments = self.env['account.payment'].sudo().search([('invoice_ids', 'in', [invoice.id])])
|
||||
# if len(payments) > 0:
|
||||
for payment in payments:
|
||||
total_paid += payment.amount
|
||||
|
||||
if total_paid >0 and total_paid >= rec.amount:
|
||||
rec.is_invoiced = True
|
||||
rec.state = "paid"
|
||||
else:
|
||||
rec.is_invoiced = False
|
||||
|
||||
elif rec.invoice_ids and rec.state == "paid":
|
||||
rec.is_invoiced = True
|
||||
|
||||
else:
|
||||
rec.is_invoiced = False
|
||||
|
||||
@api.onchange('sponsor_id')
|
||||
def onchange_sponsor_id(self):
|
||||
res = {}
|
||||
sponsorships = self.env['takaful.sponsorship'].sudo().search([('sponsor_id', '=', self.sponsor_id.id)])
|
||||
sponsorships_ids = []
|
||||
for record in sponsorships:
|
||||
sponsorships_ids.append(record.id)
|
||||
|
||||
res['domain'] = {'sponsorship_id': [('id', 'in', sponsorships_ids)]}
|
||||
return res
|
||||
|
||||
@api.onchange('has_bank_account', 'payment_method')
|
||||
def onchange_bank_account(self):
|
||||
for rec in self:
|
||||
if rec.payment_method and rec.payment_method != "cash" and not rec.has_bank_account:
|
||||
self.bank_id = self.sponsor_id.bank_id.id
|
||||
self.iban = self.sponsor_id.iban
|
||||
else:
|
||||
self.bank_id = None
|
||||
self.iban = ''
|
||||
|
||||
# @api.constrains('month_amount')
|
||||
# def check_month_amount(self):
|
||||
# if int(self.month_amount) <= 0:
|
||||
# raise ValidationError(
|
||||
# _(u'Month Amount Is Invalid'))
|
||||
|
||||
@api.constrains('payment_month_number')
|
||||
def check_payment_month_number(self):
|
||||
if int(self.month_amount) <= 0:
|
||||
raise ValidationError(
|
||||
_(u'Payment Month Number should be at least for one month'))
|
||||
|
||||
@api.depends('month_amount', 'payment_month_number')
|
||||
def get_amount_month(self):
|
||||
for rec in self:
|
||||
rec.amount = rec.month_amount * rec.payment_month_number
|
||||
|
||||
def action_pay(self):
|
||||
# Check for already sponsored beneficiaries only for sponsorship records
|
||||
|
||||
count = 0
|
||||
invoices = []
|
||||
if self.sponsorship_id.state in ['confirmed','wait_pay','progress' , 'to_cancel']:
|
||||
if self.sponsorship_id.next_due_date:
|
||||
next_date = parse(str(self.sponsorship_id.next_due_date)).date()
|
||||
while (count < self.payment_month_number):
|
||||
count +=1
|
||||
invoice_id = self.sponsorship_id.sudo().create_next_invoice(next_date)
|
||||
invoices.append(invoice_id.id)
|
||||
try:
|
||||
next_date = next_date.replace(month=(next_date.month +1))
|
||||
except Exception as e:
|
||||
next_date = next_date.replace(year=(next_date.year +1), month=1)
|
||||
|
||||
# Update invoices Ids
|
||||
for _id in invoices:
|
||||
self.write({'invoice_ids': [(4, _id)]})
|
||||
|
||||
self.state = 'financial'
|
||||
self.sponsorship_id.sudo().donations_details_lines_mechanism_ids.filtered(lambda line: line.benefit_id).write({'state': 'active'})
|
||||
self.sponsorship_id.sudo().donations_details_lines_mechanism_ids.filtered(lambda line: not line.benefit_id).write({'state': 'waiting'})
|
||||
all_lines = self.sponsorship_id.sudo().donations_details_lines_mechanism_ids + self.sponsorship_id.sudo().donations_details_lines_ids
|
||||
payment_method_ids = all_lines.mapped('payment_method_id')
|
||||
invoice_id = self.env['account.move'].search([('takaful_sponsorship_id', '=', self.sponsorship_id.id)], limit=1)
|
||||
if invoice_id and payment_method_ids and invoice_id.state == 'posted':
|
||||
receivable_lines = invoice_id.line_ids.filtered(
|
||||
lambda l: l.account_id.account_type == 'asset_receivable' and not l.reconciled
|
||||
)
|
||||
|
||||
if not receivable_lines:
|
||||
_logger.warning(f"No receivable lines found for invoice {invoice_id.name}")
|
||||
return
|
||||
|
||||
for payment_method_id in payment_method_ids:
|
||||
|
||||
if not payment_method_id.journal_id:
|
||||
continue
|
||||
|
||||
lines_with_method = all_lines.filtered(lambda l: l.payment_method_id == payment_method_id)
|
||||
payment_amount = sum(lines_with_method.mapped('donation_amount'))
|
||||
|
||||
if payment_amount <= 0:
|
||||
continue
|
||||
|
||||
payment_method_line = self.env['account.payment.method.line'].search([
|
||||
('journal_id', '=', payment_method_id.journal_id.id),
|
||||
('payment_type', '=', 'inbound')
|
||||
], limit=1)
|
||||
|
||||
if not payment_method_line:
|
||||
_logger.warning(
|
||||
f"No inbound payment method found for journal {payment_method_id.journal_id.name}. "
|
||||
f"Skipping payment creation for payment method {payment_method_id.name}"
|
||||
)
|
||||
continue
|
||||
|
||||
payment_register_vals = {
|
||||
'payment_date': fields.Date.today(),
|
||||
'amount': payment_amount,
|
||||
'journal_id': payment_method_id.journal_id.id,
|
||||
'payment_method_line_id': payment_method_line.id,
|
||||
'communication': f"{self.sponsorship_id.code} - {payment_method_id.name}",
|
||||
}
|
||||
|
||||
if payment_method_id.bank_id:
|
||||
payment_register_vals['partner_bank_id'] = payment_method_id.bank_id.id
|
||||
|
||||
payment_register = self.env['account.payment.register'].with_context(
|
||||
active_model='account.move',
|
||||
active_ids=[invoice_id.id]
|
||||
).create(payment_register_vals)
|
||||
|
||||
payment_register.action_create_payments()
|
||||
|
||||
|
||||
# @api.multi
|
||||
def open_account_invoice_action(self):
|
||||
"""Open Sponsorship Payments Entries"""
|
||||
domain = []
|
||||
if self.invoice_ids:
|
||||
domain = [('id', 'in', self.invoice_ids.ids)]
|
||||
|
||||
if self.is_invoiced is True:
|
||||
self.state ="paid"
|
||||
|
||||
context = dict(self.env.context or {})
|
||||
context["create"] = False
|
||||
context["edit"] = False
|
||||
flags = {'initial_mode': 'readonly'} # default is 'edit'
|
||||
return {
|
||||
'name': _('Financial'),
|
||||
'domain': domain,
|
||||
'view_type': 'form',
|
||||
'res_model': 'account.move',
|
||||
'view_mode': 'tree,form',
|
||||
'type': 'ir.actions.act_window',
|
||||
'flags': flags,
|
||||
'context': context,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from . import takaful_reports
|
||||
from . import month_payment_report
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
|
||||
from datetime import datetime, timedelta, date
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
|
||||
from dateutil.parser import parse
|
||||
|
||||
class BenefitREP(models.AbstractModel):
|
||||
_name = 'report.odex_takaful.benefit_payment_report_pdf'
|
||||
|
||||
def get_result(self, data=None):
|
||||
form = data
|
||||
domain = []
|
||||
if form['benefit_ids']:
|
||||
domain += [('benefit_id', 'in', form['benefit_ids'])]
|
||||
if form['date_from'] and form['date_to']:
|
||||
domain = [('month_id.date', '>=', form['date_from']), ('month_id.date', '<=', form['date_to'])]
|
||||
payment = self.env['month.payment.line'].sudo().search(domain)
|
||||
return payment
|
||||
|
||||
@api.model
|
||||
def get_report_values(self, docids, data=None):
|
||||
record = self.get_result(data)
|
||||
date_to, date_from = '', ''
|
||||
if data['date_from'] and data['date_to']:
|
||||
date_from = data['date_from']
|
||||
date_to = data['date_to']
|
||||
if not record:
|
||||
raise ValidationError(_("Sorry, there are no results for this selection !"))
|
||||
return {
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'docs': record,
|
||||
}
|
||||
|
||||
|
||||
class BenefitMonth(models.AbstractModel):
|
||||
_name = 'report.odex_takaful.benefit_month_payment_report_pdf'
|
||||
|
||||
def get_result(self, data=None):
|
||||
form = data
|
||||
domain = []
|
||||
if form['benefit_ids']:
|
||||
domain += [('benefit_id', 'in', form['benefit_ids'])]
|
||||
if form['date_from'] and form['date_to']:
|
||||
domain += [('month_id.date', '>=', form['date_from']), ('month_id.date', '<=', form['date_to'])]
|
||||
|
||||
payment = self.env['month.payment.line'].sudo().search(domain)
|
||||
month_payment = payment.mapped('month_id')
|
||||
li = []
|
||||
for y in month_payment:
|
||||
date = parse(str(y.date))
|
||||
li.append({'name': y.name , 'code': y.code, 'month_payment': date.strftime("%m-%Y"), 'payment': payment.filtered(lambda r: r.month_id == y)})
|
||||
return li
|
||||
|
||||
@api.model
|
||||
def get_report_values(self, docids, data=None):
|
||||
record = self.get_result(data)
|
||||
# if record.get('data'):
|
||||
# gender = record.get('gender').title()
|
||||
# record.update({'gender': _(gender)})
|
||||
date_to, date_from = '', ''
|
||||
if data['date_from'] and data['date_to']:
|
||||
date_from = data['date_from']
|
||||
date_to = data['date_to']
|
||||
if not record:
|
||||
raise ValidationError(_("Sorry, there are no results for this selection !"))
|
||||
return {
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'docs': record,
|
||||
}
|
||||
|
||||
|
||||
class MonthReportXlsx(models.AbstractModel):
|
||||
_name = "report.odex_takaful.benefit_month_payment_report_xlsx"
|
||||
_inherit = 'report.report_xlsx.abstract'
|
||||
|
||||
@api.model
|
||||
def generate_xlsx_report(self, workbook, data, objs):
|
||||
docs = objs
|
||||
sheet = workbook.add_worksheet(_('Bank Sheet'))
|
||||
if self.env.user.lang != 'en_US':
|
||||
sheet.right_to_left()
|
||||
format0 = workbook.add_format(
|
||||
{'bottom': True, 'bg_color': '#b8bcbf', 'right': True, 'left': True, 'top': True, 'align': 'center', })
|
||||
format1 = workbook.add_format({'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center', })
|
||||
format2 = workbook.add_format(
|
||||
{'font_size': 14, 'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center',
|
||||
'bold': True, 'bg_color': '#0f80d6', 'font_color': 'white'})
|
||||
for doc in docs:
|
||||
|
||||
format2.set_align('center')
|
||||
sheet.merge_range('A9:L9',
|
||||
(_("Month Payment Sheet")) + " - " + doc.name + " / " + doc.code, format2)
|
||||
sheet.set_column('B:D', 15)
|
||||
sheet.set_column('E:F', 10)
|
||||
row = 10
|
||||
clm = 0
|
||||
labels = [(_("#")), (_("Benefit Name")), (_("Benefit Type")), (_("Benefit ID Number")), (_("Birth Date")),
|
||||
(_("Sponsorship Number")), (_("The Sponsor")),
|
||||
(_("Amount")), (_("Iban")), (_("Bank Name")), (_("Responsible Name")), (_("Responsible ID Number"))]
|
||||
|
||||
for res in labels:
|
||||
sheet.write(row, clm, res, format0)
|
||||
clm += 1
|
||||
row = 11
|
||||
seq = 0
|
||||
for rec in doc.line_ids:
|
||||
seq += 1
|
||||
clm = 0
|
||||
sheet.write(row, clm, seq, format1)
|
||||
sheet.write(row, clm + 1, rec.benefit_id.name, format1)
|
||||
sheet.write(row, clm + 2, rec.benefit_id.benefit_type, format1)
|
||||
sheet.write(row, clm + 3, rec.benefit_id.id_number, format1)
|
||||
sheet.write(row, clm + 4, rec.benefit_id.birth_date, format1)
|
||||
sheet.write(row, clm + 5, rec.s_code, format1)
|
||||
sheet.write(row, clm + 6, rec.sponsor_id.name, format1)
|
||||
sheet.write(row, clm + 7, rec.amount, format1)
|
||||
sheet.write(row, clm + 8, rec.benefit_id.iban, format1)
|
||||
sheet.write(row, clm + 9, rec.benefit_id.bank_id.name, format1)
|
||||
sheet.write(row, clm + 10, rec.responsible_id.name, format1)
|
||||
sheet.write(row, clm + 11, rec.responsible_id.id_number, format1)
|
||||
|
||||
row += 1
|
||||
row += 3
|
||||
|
||||
|
||||
class BankSheetReportXlsx(models.AbstractModel):
|
||||
_name = "report.odex_takaful.benefit_month_payment_bank_sheet"
|
||||
_inherit = 'report.report_xlsx.abstract'
|
||||
|
||||
@api.model
|
||||
def generate_xlsx_report(self, workbook, data, objs):
|
||||
docs = objs
|
||||
sheet = workbook.add_worksheet('Bank Sheet')
|
||||
if self.env.user.lang != 'en_US':
|
||||
sheet.right_to_left()
|
||||
format0 = workbook.add_format(
|
||||
{'bottom': True, 'bg_color': '#b8bcbf', 'right': True, 'left': True, 'top': True, 'align': 'center', })
|
||||
format1 = workbook.add_format({'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center', })
|
||||
format2 = workbook.add_format(
|
||||
{'font_size': 14, 'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center',
|
||||
'bold': True, 'bg_color': '#0f80d6', 'font_color': 'white'})
|
||||
for doc in docs:
|
||||
|
||||
format2.set_align('center')
|
||||
sheet.merge_range('A9:F9',
|
||||
(_("Bank Sheet")) + " - " + doc.name + " / " + doc.code, format2)
|
||||
sheet.set_column('B:D', 15)
|
||||
sheet.set_column('E:F', 10)
|
||||
row = 9
|
||||
clm = 0
|
||||
labels = [(_("#")), (_("Bank Name")), (_("Account Number")), (_("Amount")),
|
||||
(_("Benefit Name")), (_("Benefit ID Number")), (_("Responsible Name")), (_("Responsible ID Number"))]
|
||||
|
||||
for res in labels:
|
||||
sheet.write(row, clm, res, format0)
|
||||
clm += 1
|
||||
row = 10
|
||||
seq = 0
|
||||
for rec in doc.line_ids:
|
||||
seq += 1
|
||||
clm = 0
|
||||
sheet.write(row, clm, seq, format1)
|
||||
sheet.write(row, clm + 1, rec.benefit_id.bank_id.name, format1)
|
||||
sheet.write(row, clm + 2, rec.benefit_id.iban, format1)
|
||||
sheet.write(row, clm + 3, rec.amount, format1)
|
||||
sheet.write(row, clm + 4, rec.benefit_id.name, format1)
|
||||
sheet.write(row, clm + 5, rec.benefit_id.id_number, format1)
|
||||
sheet.write(row, clm + 6, rec.responsible_id.name, format1)
|
||||
sheet.write(row, clm + 7, rec.responsible_id.id_number, format1)
|
||||
|
||||
row += 1
|
||||
row += 3
|
||||
|
|
@ -0,0 +1,369 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<!-- Benefits Payments Report -->
|
||||
<template id="benefit_payment_report_pdf">
|
||||
<t t-call="web.html_container">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<div class="text-center">
|
||||
<h2><span>Benefits Payments Report</span></h2>
|
||||
<span>
|
||||
<t t-if="date_from">
|
||||
<span t-esc="date_from"/>
|
||||
/
|
||||
</t>
|
||||
<t t-if="date_to">
|
||||
<span t-esc="date_to"/>
|
||||
</t>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<table class="table table-condensed table-bordered">
|
||||
<thead class="text-center">
|
||||
<tr style="background-color: #b8bcbf;width:100%;">
|
||||
<th style="text-align:center;">#</th>
|
||||
<th style="text-align:center;">Benefit Name</th>
|
||||
<th style="text-align:center;">Benefit Type</th>
|
||||
<th style="text-align:center;">Benefit ID Number</th>
|
||||
<th style="text-align:center;">Sponsorship Number</th>
|
||||
<th style="text-align:center;">Month Payment</th>
|
||||
<th style="text-align:center;">Payment Code</th>
|
||||
<th style="text-align:center;">Amount</th>
|
||||
<th style="text-align:center;">Date</th>
|
||||
<th style="text-align:center;">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-center">
|
||||
<t t-set="sequence" t-value="0"/>
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-set="sequence" t-value="sequence +1"/>
|
||||
<t t-esc="sequence"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.name"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['benefit_type'])['benefit_type']['selection'])[o.benefit_id.benefit_type]"/>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.id_number"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.s_code"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.month_id.name"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.code"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.amount"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.date"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['state'])['state']['selection'])[o.state]"/>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div style="page-break-before: always;"></div>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- End Template -->
|
||||
|
||||
<report
|
||||
id="benefit_payment_report_pdf_act"
|
||||
model="month.payment.line"
|
||||
string="Benefit Payment Report"
|
||||
report_type="qweb-pdf"
|
||||
name="odex_takaful.benefit_payment_report_pdf"
|
||||
file="odex_takaful.benefit_payment_report_pdf"
|
||||
menu="False"/>
|
||||
|
||||
|
||||
<!-- Sponsorship Monthly Payments of Benefits Report -->
|
||||
<template id="benefit_month_payment_report_pdf">
|
||||
<t t-call="web.html_container">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<div class="text-center">
|
||||
<h2><span>Sponsorship Monthly Payments of Benefits :</span></h2>
|
||||
<span>
|
||||
<t t-if="date_from">
|
||||
<span t-esc="date_from"/>
|
||||
/
|
||||
</t>
|
||||
<t t-if="date_to">
|
||||
<span t-esc="date_to"/>
|
||||
</t>
|
||||
</span>
|
||||
</div>
|
||||
<br></br>
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<div class="text-center" style="font-size:20px">
|
||||
<span t-esc="doc['name']"/>
|
||||
</div>
|
||||
<div class="text-center" style="font-size:20px">
|
||||
Month :
|
||||
<span t-esc="doc['month_payment']"/>
|
||||
</div>
|
||||
<div class="text-center" style="font-size:20px">
|
||||
Number :
|
||||
<span t-esc="doc['code']"/>
|
||||
</div>
|
||||
<br></br>
|
||||
|
||||
<table class="table table-condensed table-bordered">
|
||||
<thead class="text-center">
|
||||
<tr style="background-color: #b8bcbf;width:100%;">
|
||||
<th style="text-align:center;">#</th>
|
||||
<th style="text-align:center;">Benefit Name</th>
|
||||
<th style="text-align:center;">Benefit Type</th>
|
||||
<th style="text-align:center;">Sponsorship Number</th>
|
||||
<th style="text-align:center;">The Sponsor</th>
|
||||
<th style="text-align:center;">Amount</th>
|
||||
|
||||
<th style="text-align:center;">Benefit ID Number</th>
|
||||
<th style="text-align:center;">IBAN</th>
|
||||
<th style="text-align:center;">Bank</th>
|
||||
<th style="text-align:center;">Responsible Name</th>
|
||||
<th style="text-align:center;">Responsible ID Number</th>
|
||||
<th style="text-align:center;">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-center">
|
||||
<t t-set="sequence" t-value="0"/>
|
||||
<t t-foreach="doc['payment']" t-as="o">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-set="sequence" t-value="sequence +1"/>
|
||||
<t t-esc="sequence"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.name"/>
|
||||
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['benefit_type'])['benefit_type']['selection'])[o.benefit_id.benefit_type]"/>
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.s_code"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.sponsor_id.name"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.amount"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.id_number"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.iban"/>
|
||||
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.bank_id.name"/>
|
||||
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.responsible_id.name"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.responsible_id.id_number"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['state'])['state']['selection'])[o.state]"/>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<div style="page-break-before: always;"></div>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
<!-- End monthly -->
|
||||
|
||||
<report
|
||||
id="benefit_month_payment_report_pdf_act"
|
||||
model="month.payment.line"
|
||||
string="Month Payment Report"
|
||||
report_type="qweb-pdf"
|
||||
name="odex_takaful.benefit_month_payment_report_pdf"
|
||||
file="odex_takaful.benefit_month_payment_report_pdf"
|
||||
menu="False"/>
|
||||
|
||||
<!-- Benefits Payments Shares Report -->
|
||||
<template id="benefit_month_payment_share">
|
||||
<t t-call="web.html_container">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<div class="text-center">
|
||||
<h2><span>Benefits Payments Shares Report From Sponsorship:</span></h2>
|
||||
<span>
|
||||
<t t-if="date_from">
|
||||
<span t-esc="date_from"/>
|
||||
/
|
||||
</t>
|
||||
<t t-if="date_to">
|
||||
<span t-esc="date_to"/>
|
||||
</t>
|
||||
</span>
|
||||
</div>
|
||||
<br></br>
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<br></br>
|
||||
<div class="text-center" style="font-size:20px">
|
||||
<span t-esc="doc.name"/> /
|
||||
<span t-esc="doc.code"/>
|
||||
</div>
|
||||
<br></br>
|
||||
|
||||
<table class="table table-condensed table-bordered">
|
||||
<thead class="text-center">
|
||||
<tr style="background-color: #b8bcbf;width:100%;">
|
||||
<th style="text-align:center;">#</th>
|
||||
<th style="text-align:center;">Benefit Name</th>
|
||||
<th style="text-align:center;">Benefit Type</th>
|
||||
<th style="text-align:center;">Benefit ID Number</th>
|
||||
<th style="text-align:center;">Birth Date</th>
|
||||
<th style="text-align:center;">Sponsorship Number</th>
|
||||
<th style="text-align:center;">The Sponsor</th>
|
||||
<th style="text-align:center;">Amount</th>
|
||||
<th style="text-align:center;">IBAN</th>
|
||||
<th style="text-align:center;">Bank</th>
|
||||
<th style="text-align:center;">Responsible Name</th>
|
||||
<th style="text-align:center;">Responsible ID Number</th>
|
||||
<th style="text-align:center;">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-center">
|
||||
<t t-set="sequence" t-value="0"/>
|
||||
<t t-foreach="doc.line_ids" t-as="o">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-set="sequence" t-value="sequence +1"/>
|
||||
<t t-esc="sequence"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.name"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['benefit_type'])['benefit_type']['selection'])[o.benefit_id.benefit_type]"/>
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.id_number"/>
|
||||
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.birth_date"/>
|
||||
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.s_code"/>
|
||||
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.sponsor_id.name"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.amount"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.iban"/>
|
||||
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.benefit_id.bank_id.name"/>
|
||||
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.responsible_id.name"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.responsible_id.id_number"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['state'])['state']['selection'])[o.state]"/>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<div style="page-break-before: always;"></div>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
<!-- End Template -->
|
||||
|
||||
<report
|
||||
id="benefit_month_payment_share_report_pdf_act"
|
||||
model="month.payment"
|
||||
string="Month Payments Shares PDF"
|
||||
report_type="qweb-pdf"
|
||||
name="odex_takaful.benefit_month_payment_share"
|
||||
file="odex_takaful.benefit_month_payment_share"
|
||||
menu="True"/>
|
||||
|
||||
<!-- xlx-->
|
||||
<report
|
||||
id="benefit_month_payment_report_xlsx_act"
|
||||
model="month.payment"
|
||||
string="Month Payments Shares Xlsx"
|
||||
report_type="xlsx"
|
||||
name="odex_takaful.benefit_month_payment_report_xlsx"
|
||||
file="odex_takaful.benefit_month_payment_report_xlsx"
|
||||
menu="True"/>
|
||||
<!-- Bank Statement-->
|
||||
<report
|
||||
id="benefit_month_payment_bank_Sheet_act"
|
||||
model="month.payment"
|
||||
string="Print Bank Sheet"
|
||||
report_type="xlsx"
|
||||
name="odex_takaful.benefit_month_payment_bank_sheet"
|
||||
file="odex_takaful.benefit_month_payment_bank_sheet"
|
||||
menu="True"/>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<template id="report_payment_voucher">
|
||||
<t t-call="web.html_container">
|
||||
<t t-set="sar_currency_id" t-value="docs.env.ref('base.SAR')"/>
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<t t-if="o.sponsorship_scheduling_line_id">
|
||||
<t t-set="donnation_details_id" t-value="o.sponsorship_scheduling_line_id.donation_detail_linked_id"/>
|
||||
</t>
|
||||
<t t-else="1">
|
||||
<t t-set="donnation_details_id" t-value="o.sponsorship_scheduling_line_ids.donation_detail_linked_id"/>
|
||||
</t>
|
||||
<h3 class="text-center"><t-esc t-field="o.name"/></h3>
|
||||
<div class="row mt-4">
|
||||
<div class="col-12 mb-3">
|
||||
<strong>Scheduling Sequence(s):</strong> <span t-field="o.sponsorship_scheduling_ref" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 mb-3">
|
||||
<strong>Sponsor Name:</strong> <span t-field="o.sponsorship_id.sponsor_id" />
|
||||
</div>
|
||||
<div class="col-6 mb-3">
|
||||
<strong>Point of Sale:</strong> <span t-field="o.branch_custom_id" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 mb-3">
|
||||
<strong>Donation Type:</strong> <span t-field="o.sponsorship_id.record_type" />
|
||||
</div>
|
||||
<div class="col-6 mb-3">
|
||||
<strong>Donation Name:</strong> <span t-field="donnation_details_id.product_template_id" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 mb-3">
|
||||
<strong>Beneficiary:</strong> <span t-field="donnation_details_id.benefit_id" />
|
||||
</div>
|
||||
<div class="col-6 mb-3">
|
||||
<strong>Payment Date:</strong> <span t-field="o.donation_date" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 mb-3">
|
||||
<strong>Payment Method:</strong> <span t-field="o.payment_method" />
|
||||
</div>
|
||||
<div class="col-6 mb-3">
|
||||
<strong>Donation Amount:</strong> <span t-field="o.donation_amount" t-options="{'widget': 'monetary', 'display_currency': sar_currency_id}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 mb-3">
|
||||
<strong>Amount Paid:</strong> <span t-field="o.donation_amount" t-options="{'widget': 'monetary', 'display_currency': sar_currency_id}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<report
|
||||
id="action_payment_voucher_report"
|
||||
string="Payment Voucher Report"
|
||||
model="payment.details.lines"
|
||||
report_type="qweb-pdf"
|
||||
name="odex_takaful.report_payment_voucher"
|
||||
file="odex_takaful.report_payment_voucher"
|
||||
print_report_name="object.print_report_name()"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import api, models, fields, _
|
||||
|
||||
class ReportMakfuleen(models.AbstractModel):
|
||||
_name = 'report.odex_takaful.makfuleen_report_pdf'
|
||||
|
||||
@api.model
|
||||
def get_report_values(self, docids, data=None):
|
||||
selected_id = data.get('sponsor_id', False)
|
||||
domain = [('sponsor_id', '=', selected_id)]
|
||||
records = self.env['takaful.sponsorship'].sudo().search(domain)
|
||||
|
||||
return {
|
||||
'docs': records,
|
||||
'name': data.get('name', ""),
|
||||
}
|
||||
|
||||
|
||||
class ReportKafalatPayment(models.AbstractModel):
|
||||
_name = 'report.odex_takaful.kafalat_payment_report_pdf'
|
||||
|
||||
|
||||
@api.model
|
||||
def get_report_values(self, docids, data=None):
|
||||
|
||||
sponsor_id = data.get('sponsor_id', False)
|
||||
overdue_sponsorships = self.env['takaful.sponsorship'].sudo().search([('sponsor_id','=', sponsor_id), ('has_delay','=', False), ('state','in', ['wait_pay','progress' , 'to_cancel'])])
|
||||
|
||||
overdue_amount = sum(overdue_sponsorships.mapped('overdue_amount')) or 0
|
||||
|
||||
return {
|
||||
'docs': overdue_sponsorships or [],
|
||||
'name': data.get('name', ""),
|
||||
'overdue_amount': overdue_amount,
|
||||
'overdue_count': len(overdue_sponsorships),
|
||||
}
|
||||
|
||||
|
||||
class ReportKafalatCancel(models.AbstractModel):
|
||||
_name = 'report.odex_takaful.kafalat_cancel_report_pdf'
|
||||
|
||||
|
||||
@api.model
|
||||
def get_report_values(self, docids, data=None):
|
||||
start_date = data.get('start_date', False)
|
||||
end_date = data.get('end_date', False)
|
||||
|
||||
|
||||
if start_date and end_date:
|
||||
canceled_kafalat = self.env['sponsorship.cancellation'].sudo().search([
|
||||
('confirm_date', '>=', start_date),
|
||||
('confirm_date', '<=', end_date),
|
||||
('state', '=', 'cancel'),
|
||||
])
|
||||
|
||||
else:
|
||||
canceled_kafalat = []
|
||||
|
||||
return {
|
||||
'docs': canceled_kafalat,
|
||||
'cancel_count': len(canceled_kafalat),
|
||||
'start_date': start_date,
|
||||
'end_date': end_date,
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="paperformat_transfer_deduction_landscape" model="report.paperformat">
|
||||
<field name="name">Transfer Deduction Report Landscape</field>
|
||||
<field name="default" eval="False"/>
|
||||
<field name="format">A4</field> <!-- You can use Letter, Legal, etc. -->
|
||||
<field name="page_height">0</field>
|
||||
<field name="page_width">0</field>
|
||||
<field name="orientation">Landscape</field>
|
||||
<field name="margin_top">40</field> <!-- Adjust margins as needed -->
|
||||
<field name="margin_bottom">25</field>
|
||||
<field name="margin_left">7</field>
|
||||
<field name="margin_right">7</field>
|
||||
<field name="header_line" eval="False"/>
|
||||
<field name="header_spacing">30</field>
|
||||
<field name="dpi">120</field>
|
||||
</record>
|
||||
|
||||
<record id="action_report_transfer_deduction_pdf" model="ir.actions.report">
|
||||
<field name="name">Transfer and Deduction Report (PDF)</field>
|
||||
<field name="model">transfer.deduction.wizard</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">odex_takaful.report_transfer_deduction_document</field>
|
||||
<field name="report_file">odex_takaful.report_transfer_deduction_document</field>
|
||||
<field name="print_report_name">
|
||||
(object.sponsorship_creation_date and ('Transfer Deduction Report - %s' % (object.sponsorship_creation_date.strftime('%Y-%m-%d'))) or 'Transfer Deduction Report')
|
||||
</field>
|
||||
<field name="paperformat_id" ref="odex_takaful.paperformat_transfer_deduction_landscape"/> <!-- Add this line -->
|
||||
<field name="binding_model_id" eval="False"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="report_transfer_deduction_document">
|
||||
<t t-call="web.html_container">
|
||||
<t t-set="report_title" t-value="data.get('report_title', 'Transfer and Deduction Report')"/>
|
||||
<t t-set="criteria" t-value="data.get('criteria', {})"/>
|
||||
<t t-set="sponsorship_lines" t-value="data.get('sponsorship_lines_details', [])"/>
|
||||
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<h2 class="text-center"><span t-esc="report_title"/></h2>
|
||||
|
||||
<h3 class="mt-4"><u>Selected Criteria</u></h3>
|
||||
<table class="table table-sm table-bordered mt-2" style="width: 100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width: 15%;"><strong>Start Date</strong></td>
|
||||
<td style="width: 35%;"><span t-esc="criteria.get('start_date')"/></td>
|
||||
<td style="width: 15%;"><strong>Payment Method</strong></td>
|
||||
<td style="width: 35%;"><span t-esc="criteria.get('payment_method_name')"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>End Date</strong></td>
|
||||
<td><span t-esc="criteria.get('end_date')"/></td>
|
||||
<td><strong>Branches</strong></td>
|
||||
<td><span t-esc="criteria.get('branch_names')"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Sponsors</strong></td>
|
||||
<td><span t-esc="criteria.get('sponsor_names')"/></td>
|
||||
<td><strong>Benefit Members</strong></td>
|
||||
<td><span t-esc="criteria.get('benefit_member_names')"/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3 class="mt32"><u>Sponsorship Details</u></h3>
|
||||
<t t-if="sponsorship_lines">
|
||||
<table class="table table-sm table-condensed table-bordered mt-2">
|
||||
<thead>
|
||||
<tr style="background-color: #f2f2f2;">
|
||||
<th>Sponsor</th>
|
||||
<th>Sponsor Mobile</th>
|
||||
<th>Sponsorship Creator</th>
|
||||
<th>Sponsorship Creator Branch</th>
|
||||
<th>Sponsorship Branch</th>
|
||||
<th>Beneficiary</th>
|
||||
<th>Sponsorship Creation Date</th>
|
||||
<th>Sponsorship Number</th>
|
||||
<th>Sponsor Bank</th>
|
||||
<th>Charity Bank</th>
|
||||
<th>Sponsor Account Number</th>
|
||||
<th>Payment Method</th>
|
||||
<th>Donation Type</th>
|
||||
<th>Donation Name</th>
|
||||
<th>Direct Debit Start</th>
|
||||
<th>Direct Debit End</th>
|
||||
<th>Donation Date</th>
|
||||
<th class="text-right">Amount</th>
|
||||
<th class="text-right">Total Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="sponsorship_lines" t-as="line">
|
||||
<tr>
|
||||
<td><span t-esc="line.get('sponsor_name')"/></td>
|
||||
<td><span t-esc="line.get('sponsor_mobile')"/></td>
|
||||
<td><span t-esc="line.get('sponsorship_create_uid_name')"/></td>
|
||||
<td><span t-esc="line.get('sponsorship_create_uid_branch_name')"/></td>
|
||||
<td><span t-esc="line.get('sponsorship_branch_name')"/></td>
|
||||
<td><span t-esc="line.get('beneficiary_name')"/></td>
|
||||
<td><span t-esc="line.get('sponsorship_create_date')" t-options="{'widget': 'date'}"/></td>
|
||||
<td><span t-esc="line.get('sponsorship_sequence_no')"/></td>
|
||||
<td><span t-esc="line.get('bank_name')"/></td>
|
||||
<td><span t-esc="line.get('charity_bank_name')"/></td>
|
||||
<td><span t-esc="line.get('sponsor_account_number')"/></td>
|
||||
<td><span t-esc="line.get('payment_method_name')"/></td>
|
||||
<td><span t-esc="line.get('donation_type')"/></td>
|
||||
<td><span t-esc="line.get('donation_name')"/></td>
|
||||
<td><span t-esc="line.get('direct_debit_start_date')" t-options="{'widget': 'date'}"/></td>
|
||||
<td><span t-esc="line.get('direct_debit_end_date')" t-options="{'widget': 'date'}"/></td>
|
||||
<td><span t-esc="line.get('donation_date')" t-options="{'widget': 'date'}"/></td>
|
||||
<td class="text-right">
|
||||
<span t-esc="line.get('amount')" t-options="{'widget': 'monetary', 'display_currency': docs.env.company.currency_id}"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="line.get('total_amount')" t-options="{'widget': 'monetary', 'display_currency': docs.env.company.currency_id}"/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="mt-2"><strong>Total lines found: <span t-esc="len(sponsorship_lines)"/></strong></p>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<p class="mt-2">No sponsorship scheduling lines found for the selected criteria.</p>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_sponsorship_payment_user,Full access on sponsorship.payment to Payment User,model_sponsorship_payment,group_kufula_user,1,1,1,1
|
||||
access_month_payment_full,Full access on month.payment to Month Payment Manager,model_month_payment,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_takaful_message_template,Full access on takaful.message.template,model_takaful_message_template,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_sponsorship_cancellation,Full access on sponsorship.cancellation,model_sponsorship_cancellation,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_takaful_contribution,Full access on takaful.contribution,model_takaful_contribution,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_takaful_push_notification,Full access on takaful.push.notification,model_takaful_push_notification,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_month_payment_line,Full access on month.payment.line,model_month_payment_line,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_sponsorship_benefit_arrears,Full access on sponsorship.benefit.arrears,model_sponsorship_benefit_arrears,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_sponsorship_reason_stop,Full access on sponsorship.reason.stop,model_sponsorship_reason_stop,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_donate_for_another_person,access_donate_for_another_person,model_donate_for_another_person,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_donations_items,access_donations_items,model_donations_items,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_replacement_reasons,access_replacement_reasons,model_replacement_reasons,odex_takaful.group_orphan_replacement,1,1,1,1
|
||||
access_replacement_process,access_replacement_process,model_replacement_process,odex_takaful.group_orphan_replacement,1,1,1,0
|
||||
access_takaful_notification,access_takaful_notification,model_takaful_notification,,1,1,1,1
|
||||
access_sponsorship_states,access_sponsorship_states,model_sponsorship_states,,1,1,1,1
|
||||
|
||||
|
||||
access_replacement_wiz,access_replacement_wiz,model_replacement_wiz,,1,1,1,1
|
||||
access_donations_details_lines,access_donations_details_lines,model_donations_details_lines,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_refund_details_lines,access_refund_details_lines,model_refund_details_lines,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_points_of_sale_custom,access_points_of_sale_custom,model_points_of_sale_custom,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_payment_details_lines,access_payment_details_lines,model_payment_details_lines,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_sponsorship_scheduling_line,access_sponsorship_scheduling_line,model_sponsorship_scheduling_line,odex_takaful.group_kufula_user,1,0,0,0
|
||||
access_refund_reasons,access_refund_reasons,model_refund_reasons,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_takaful_sponsorship_user,Full access on takaful.sponsorship to Sponsorship User,model_takaful_sponsorship,group_kufula_user,1,1,1,1
|
||||
access_res_partner_user,Access on res.pfartner to Sponsorship User,base.model_res_partner,group_kufula_user,1,1,0,0
|
||||
access_res_users_user,Access on res.users to Sponsorship User,base.model_res_users,group_kufula_user,1,1,0,0
|
||||
access_grant_benefit_invoice,Full access on grant.benefit.invoice to Month Payment Manager,model_grant_benefit_invoice,base.group_user,1,1,1,1
|
||||
access_refund_wiz,access_refund_wiz,model_refund_wiz,,1,1,1,1
|
||||
access_add_details_wiz,access_add_details_wiz,model_add_details_wiz,,1,1,1,1
|
||||
access_preferred_communication,access_preferred_communication,model_preferred_communication,,1,1,1,1
|
||||
access_takaful_payment_method,access_takaful_payment_method,model_takaful_payment_method,,1,1,1,1
|
||||
access_replacement_line_method,access_takaful_replacement_line,model_replacement_line,,1,1,1,1
|
||||
access_replacement_process_line_method,access_takaful_replacement_process_line,model_replacement_process_line,,1,1,1,1
|
||||
|
||||
|
||||
access_transfer_deduction_wizard,transfer.deduction.wizard.access,model_transfer_deduction_wizard,base.group_user,1,1,1,1
|
||||
access_account_payment_register_donation_officer,account_payment_register_donation_officer,account.model_account_payment_register,odex_takaful.donation_officer_group,1,1,1,0
|
||||
access_product_template_donation_officer,product_template_donation_officer,product.model_product_template,odex_takaful.donation_officer_group,1,1,1,0
|
||||
access_product_product_donation_officer,product_product_donation_officer,product.model_product_product,odex_takaful.donation_officer_group,1,1,1,0
|
||||
|
||||
access_group_kufula_user_account_payment,access_group_kufula_user_account_payment,account.model_account_payment,odex_takaful.group_kufula_user,1,1,1,0
|
||||
access_group_kufula_user_account_partial_reconcile,access_group_kufula_user_account_partial_reconcile,account.model_account_partial_reconcile,odex_takaful.group_kufula_user,1,1,1,0
|
||||
access_group_kufula_user_account_full_reconcile,access_group_kufula_user_account_full_reconcile,account.model_account_full_reconcile,odex_takaful.group_kufula_user,1,1,1,0
|
||||
access_donation_extension_wizard,donation.extension.wizard.access,model_donation_extension_wizard,base.group_user,1,1,1,1
|
||||
access_donation_extension_history,donation.extension.history.access,model_donation_extension_history,odex_takaful.group_kufula_user,1,1,1,0
|
||||
access_donation_extension_wizard_line,donation.extension.wizard.line.access,model_donation_extension_wizard_line,odex_takaful.group_kufula_user,1,1,1,0
|
||||
access_donation_replacement_log,donation.replacement.log.access,model_donation_replacement_log,odex_takaful.group_kufula_user,1,1,1,0
|
||||
access_replace_sponsor_wizard,replace.sponsor.wizard.access,model_replace_sponsor_wizard,odex_takaful.group_replace_sponsor,1,1,1,1
|
||||
access_add_benefit_wizard,add.benefit.wizard.access,model_add_benefit_wizard,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_extension_payment_wizard_line,extension.payment.wizard.line.access,model_extension_payment_wizard_line,odex_takaful.group_kufula_user,1,1,1,1
|
||||
access_group_kufula_user_product_template,access_group_kufula_user_product_template,product.model_product_template,odex_takaful.group_kufula_user,1,1,0,0
|
||||
access_group_kufula_user_account_move,access_group_kufula_user_account_move,account.model_account_move,odex_takaful.group_kufula_user,1,1,1,0
|
||||
access_group_kufula_user_sale_order,access_group_kufula_user_sale_order,sale.model_sale_order,odex_takaful.group_kufula_user,1,1,1,0
|
||||
access_group_kufula_user_grant_benefit,access_group_kufula_user_grant_benefit,odex_benefit.model_grant_benefit,odex_takaful.group_kufula_user,1,1,1,0
|
||||
access_group_kufula_user_res_partner,access_group_kufula_user_res_partner,base.model_res_partner,odex_takaful.group_kufula_user,1,1,1,0
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
<odoo>
|
||||
<data noupdate="0">
|
||||
|
||||
<record id="module_category_kufula" model="ir.module.category">
|
||||
<field name="name">Kufula System</field>
|
||||
<field name="description">Helps you manage Kafleen and Kafalat in kufula System</field>
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
|
||||
<!-- <record id="group_kufula_viewer" model="res.groups">
|
||||
<field name="name">Viewer</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
</record>
|
||||
|
||||
<record id="group_kufula_officer" model="res.groups">
|
||||
<field name="name">Officer</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_kufula_viewer'))]"/>
|
||||
<field name="users" eval="[(4, ref('base.group_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="group_kufula_manager" model="res.groups">
|
||||
<field name="name">Administrator</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_kufula_officer'))]"/>
|
||||
<field name="users" eval="[(4, ref('base.user_root'))]"/>
|
||||
</record> -->
|
||||
|
||||
<record id="group_can_make_sponsorship_payment" model="res.groups">
|
||||
<field name="name">Make Sponsorship Payments</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Can Make Payments For Sponsorships?</field>
|
||||
</record>
|
||||
|
||||
<record id="group_can_recieve_sponsorship_payment" model="res.groups">
|
||||
<field name="name">Recieve Sponsorship Payments</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Can Recieve Payments For Sponsorships?</field>
|
||||
</record>
|
||||
|
||||
<record id="takaful_group_user_sponsor" model="res.groups">
|
||||
<field name="name">Sponsor Account</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Is this user a Sponsor?</field>
|
||||
</record>
|
||||
|
||||
<record id="group_can_activate_sponsor" model="res.groups">
|
||||
<field name="name">Can Activate Inactive Sponsors</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Can make Sponsor active again?</field>
|
||||
</record>
|
||||
|
||||
<record id="group_refund_approval" model="res.groups">
|
||||
<field name="name">Refund Approval</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Can make Approval for refund?</field>
|
||||
</record>
|
||||
|
||||
<record id="group_orphan_replacement" model="res.groups">
|
||||
<field name="name">Orphan Replacement</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Orphan Replacement</field>
|
||||
</record>
|
||||
|
||||
<record id="group_replace_sponsor" model="res.groups">
|
||||
<field name="name">Replace Sponsor</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Can Replace Sponsor on Donation Lines</field>
|
||||
</record>
|
||||
|
||||
<record id="group_show_donation_item_product" model="res.groups">
|
||||
<field name="name">Show Donation Item Product</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Can Show Donation Item Product?</field>
|
||||
</record>
|
||||
|
||||
<!-- <record id="group_donations_coordinator" model="res.groups">
|
||||
<field name="name">Donations Coordinator</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
</record>
|
||||
|
||||
<record id="group_sponsorship_coordinator" model="res.groups">
|
||||
<field name="name">Sponsorship Coordinator</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
</record> -->
|
||||
|
||||
<!-- <record id="group_branch_manager" model="res.groups">
|
||||
<field name="name">Branch Manager</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
</record> -->
|
||||
|
||||
<!-- <record id="group_sponsorship_system_manager" model="res.groups">
|
||||
<field name="name">Sponsorship System Manager</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
</record> -->
|
||||
|
||||
|
||||
<!-- <record id="donations_coordinator_rule" model="ir.rule">
|
||||
<field name="name">Donations Coordinator - Record Type Donation</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="groups" eval="[(4, ref('group_donations_coordinator'))]"/>
|
||||
<field name="domain_force">[('record_type', '=', 'donation')]</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record> -->
|
||||
|
||||
<!-- <record id="sponsorship_coordinator_rule" model="ir.rule">
|
||||
<field name="name">Sponsorship Coordinator - Record Type Sponsorship</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="groups" eval="[(4, ref('group_sponsorship_coordinator'))]"/>
|
||||
<field name="domain_force">[('record_type', '=', 'sponsorship')]</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record> -->
|
||||
|
||||
|
||||
<!-- <record id="branch_manager_rule" model="ir.rule">
|
||||
<field name="name">Branch Manager - Can Only See Their Branch</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="groups" eval="[(4, ref('group_branch_manager'))]"/>
|
||||
<field name="domain_force">[('manager_id.user_id', '=', user.id)]</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record> -->
|
||||
|
||||
<!-- <record id="sponsorship_system_manager_rule" model="ir.rule">
|
||||
<field name="name">Sponsorship System Manager</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="groups" eval="[(4, ref('group_sponsorship_system_manager'))]"/>
|
||||
<field name="domain_force">[(1,'=',1)]</field>
|
||||
</record> -->
|
||||
|
||||
<record id="group_kufula_user" model="res.groups">
|
||||
<field name="name">Kufula User</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
</record>
|
||||
|
||||
<record id="donation_officer_group" model="res.groups">
|
||||
<field name="name">Donations Officer</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_kufula_user'))]"/>
|
||||
</record>
|
||||
<record id="donation_officer_restrictions" model="ir.rule">
|
||||
<field name="name">Donations Officer can only see his donations or his branch sponsors</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="groups" eval="[(4, ref('donation_officer_group'))]"/>
|
||||
<field name="domain_force">[
|
||||
('record_type', 'in', [False, 'donation']),
|
||||
('create_uid', '=', user.id)
|
||||
]
|
||||
</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
|
||||
<record id="sponsorship_officer_group" model="res.groups">
|
||||
<field name="name">Sponsorships Officer</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_kufula_user'))]"/>
|
||||
</record>
|
||||
<record id="sponsorship_officer_restrictions" model="ir.rule">
|
||||
<field name="name">Sponsorships Officer can only see his sponsorships or his branch sponsors</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="groups" eval="[(4, ref('sponsorship_officer_group'))]"/>
|
||||
<field name="domain_force">[
|
||||
('record_type', 'in', [False, 'sponsorship']),
|
||||
('create_uid', '=', user.id)
|
||||
]
|
||||
</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
|
||||
<record id="branch_manager_group" model="res.groups">
|
||||
<field name="name">Branch Manager</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_kufula_user'))]"/>
|
||||
</record>
|
||||
<record id="branch_manager_restrictions" model="ir.rule">
|
||||
<field name="name">Branch Manager can only see all his branch sponsorships and donations</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="groups" eval="[(4, ref('branch_manager_group'))]"/>
|
||||
<field name="domain_force">[('branch_custom_id.branch.manager_id.user_id', 'in', [user.id, False])]</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
|
||||
<record id="sponsorship_system_manager_group" model="res.groups">
|
||||
<field name="name">Sponsorship System Manager</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_kufula_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="sponsorship_restrict_orphan_group" model="res.groups">
|
||||
<field name="name">Sponsorship General Restriction</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_kufula_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="responsible_user_sponsorship_access" model="ir.rule">
|
||||
<field name="name">Responsible Users can access related Sponsorships</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="groups" eval="[(4, ref('group_kufula_user'))]"/>
|
||||
<field name="domain_force">[('create_uid','=',user.id)]</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
|
||||
<record id="kufula_user_donations_details_lines_access" model="ir.rule">
|
||||
<field name="name">Users can access related Donations Details Lines</field>
|
||||
<field name="model_id" ref="model_donations_details_lines"/>
|
||||
<field name="groups" eval="[(4, ref('group_kufula_user'))]"/>
|
||||
<field name="domain_force">[('create_uid','=',user.id)]</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
|
||||
<record id="sponsorship_system_manager_restrictions" model="ir.rule">
|
||||
<field name="name">Sponsorship System Manager can see everything and settings</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="groups" eval="[(4, ref('sponsorship_system_manager_group'))]"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
|
||||
<!-- Groups for Department-based Access Control -->
|
||||
<record id="group_beneficiary_department_access" model="res.groups">
|
||||
<field name="name">Beneficiary - Department Access</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Limits beneficiary records to user's department</field>
|
||||
</record>
|
||||
|
||||
<record id="group_sponsor_department_access" model="res.groups">
|
||||
<field name="name">Sponsor - Department Access</field>
|
||||
<field name="category_id" ref="module_category_kufula"/>
|
||||
<field name="comment">Limits sponsor records to user's department</field>
|
||||
</record>
|
||||
<!-- Record Rules for Department-based Access Control -->
|
||||
<record id="grant_benefit_department_rule" model="ir.rule">
|
||||
<field name="name">Grant Benefit - Department Based Access</field>
|
||||
<field name="model_id" ref="odex_benefit.model_grant_benefit"/>
|
||||
<field name="groups" eval="[(4, ref('group_beneficiary_department_access'))]"/>
|
||||
<field name="domain_force">[('branch_custom_id.branch', 'child_of', user.employee_id.department_id.id)]
|
||||
</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
|
||||
<record id="family_member_department_rule" model="ir.rule">
|
||||
<field name="name">Family Member - Department Based Access</field>
|
||||
<field name="model_id" ref="odex_benefit.model_family_member"/>
|
||||
<field name="groups" eval="[(4, ref('group_beneficiary_department_access'))]"/>
|
||||
<field name="domain_force">[('benefit_id.branch_custom_id.branch', 'child_of',
|
||||
user.employee_id.department_id.id)]
|
||||
</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
|
||||
<record id="sponsor_department_rule" model="ir.rule">
|
||||
<field name="name">Sponsor - Department Based Access</field>
|
||||
<field name="model_id" ref="odex_takaful.model_takaful_sponsor"/>
|
||||
<field name="groups" eval="[(4, ref('group_sponsor_department_access'))]"/>
|
||||
<field name="domain_force">[('branch_custom_id.branch', 'child_of', user.employee_id.department_id.id)]
|
||||
</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="sponsorship_marketer_restrictions" model="ir.rule">
|
||||
<!-- <field name="name">Sponsorship Marketer can see and select all employees</field>-->
|
||||
<field name="name">Sponsorship Marketer can see his employees</field>
|
||||
<field name="model_id" ref="hr.model_hr_employee"/>
|
||||
<field name="groups" eval="[(4, ref('donation_officer_group'))]"/>
|
||||
<!-- <field name="domain_force">[(1, '=', 1)]</field>-->
|
||||
<field name="domain_force">['|', '|', ('user_id','=',user.id), ('department_id.manager_id.user_id','=', user.id), ('parent_id.user_id','=', user.id)]</field>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="0"/>
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
|
||||
</odoo>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
|
|
@ -0,0 +1,25 @@
|
|||
odoo.define('odex_takaful.CustomKanbanRecord', function (require) {
|
||||
"use strict";
|
||||
|
||||
const KanbanRecord = require('web.KanbanRecord');
|
||||
|
||||
const CustomKanbanRecord = KanbanRecord.extend({
|
||||
events: _.extend({}, KanbanRecord.prototype.events, {
|
||||
'click .oe_dynamic_button': '_onClickDynamicButton',
|
||||
}),
|
||||
|
||||
/**
|
||||
* Hide the button when clicked
|
||||
*
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickDynamicButton: function (ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
$(ev.currentTarget).hide(); // Hide the button
|
||||
},
|
||||
});
|
||||
|
||||
return CustomKanbanRecord;
|
||||
});
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
odoo.define('odex_takaful.custom_dialog', function (require) {
|
||||
"use strict";
|
||||
|
||||
const AbstractAction = require('web.AbstractAction');
|
||||
const Dialog = require('web.Dialog');
|
||||
const core = require('web.core');
|
||||
const _t = core._t;
|
||||
const ActionManager = require('web.ActionManager');
|
||||
|
||||
ActionManager.include({
|
||||
//----------------------------------------------------------------------
|
||||
// Public
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the action of the controller currently opened in a dialog,
|
||||
* i.e. a target='new' action, if any.
|
||||
*
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
getCurrentActionInDialog: function () {
|
||||
if (this.currentDialogController) {
|
||||
return this.actions[this.currentDialogController.actionID];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
/**
|
||||
* Returns the controller currently opened in a dialog, if any.
|
||||
*
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
getCurrentControllerInDialog: function () {
|
||||
return this.currentDialogController;
|
||||
},
|
||||
});
|
||||
|
||||
Dialog.include({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
open: function () {
|
||||
var self = this;
|
||||
this.opened(function () {
|
||||
setTimeout(function () {
|
||||
var parent = self.getParent();
|
||||
|
||||
if (parent instanceof ActionManager) {
|
||||
|
||||
var action = parent.getCurrentActionInDialog();
|
||||
if (action) {
|
||||
if (action.context) {
|
||||
let context = action.context;
|
||||
if (context.action_code) {
|
||||
if (context.action_code === 'donation_items') {
|
||||
|
||||
if (self.$footer) {
|
||||
const closeBtn = $('<button/>', {
|
||||
text: _t('Add'),
|
||||
class: 'btn btn-primary btn-close-custom',
|
||||
}).on('click', () => self.close());
|
||||
self.$footer.append(closeBtn);
|
||||
}
|
||||
|
||||
if (self.$modal) {
|
||||
self.$modal.find('.modal-header button.close').hide();
|
||||
self.$modal.find('.modal-header .modal-title').css("width", "100%");
|
||||
}
|
||||
|
||||
if (self.$el) {
|
||||
self.$el.find('.o_cp_top_left').hide();
|
||||
self.$el.find('.o_cp_bottom_left').hide();
|
||||
self.$el.find('.o_cp_top_right').css("width", "100%");
|
||||
self.$el.find('.o_cp_bottom_right').css("width", "100%");
|
||||
}
|
||||
|
||||
if (context.sponsorship_id) {
|
||||
$('#cspid').remove();
|
||||
$('body').append(`<input type="hidden" id="cspid" value="${context.sponsorship_id}"/>`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
odoo.define('odex_takaful.DonationQuantityWidget', function (require) {
|
||||
"use strict";
|
||||
|
||||
const Widget = require('web.Widget');
|
||||
const rpc = require('web.rpc');
|
||||
const core = require('web.core');
|
||||
const QWeb = core.qweb;
|
||||
const _t = core._t;
|
||||
|
||||
let o_cart_kanban_donation = $('.o_cart_kanban_donation');
|
||||
if(o_cart_kanban_donation){
|
||||
$(o_cart_kanban_donation).parents('.o_act_window').find('.o_cp_top_left').remove();
|
||||
}
|
||||
|
||||
$(document).on('click', 'button[data-name="add_quantity_button_request"]', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleQuantityChange($(this), 'first_add');
|
||||
return false; // ensure Odoo's default kanban action handler does not run
|
||||
});
|
||||
|
||||
$(document).on('click', 'button[data-name="add_quantity_button_so"]', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleQuantityChange($(this), 'add');
|
||||
return false; // ensure Odoo's default kanban action handler does not run
|
||||
});
|
||||
|
||||
$(document).on('click', 'button[data-name="remove_quantity_button_so"]', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
handleQuantityChange($(this), 'remove');
|
||||
return false; // ensure Odoo's default kanban action handler does not run
|
||||
});
|
||||
|
||||
// Expose imperative handlers as a reliable fallback (callable from inline onclick if needed)
|
||||
window.__dc_add = function (btn) {
|
||||
return __dc_handle(btn, 'add');
|
||||
};
|
||||
window.__dc_remove = function (btn) {
|
||||
return __dc_handle(btn, 'remove');
|
||||
};
|
||||
window.__dc_first_add = function (btn) {
|
||||
return __dc_handle(btn, 'first_add');
|
||||
};
|
||||
|
||||
function __dc_handle(btn, operation) {
|
||||
try {
|
||||
const $btn = $(btn);
|
||||
handleQuantityChange($btn, operation);
|
||||
} catch (_e) {
|
||||
// no-op
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function handleQuantityChange($button, operation) {
|
||||
|
||||
// Get the kanban record (product card) container
|
||||
const $kanbanRecord = $button.closest('.o_kanban_record');
|
||||
if (!$kanbanRecord.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get quantity display element from the button's parent container using stable custom classes
|
||||
let $container = $button.closest('.dc-qty-controls');
|
||||
if (operation === 'first_add') {
|
||||
$container = $kanbanRecord.find('.dc-qty-controls')
|
||||
}
|
||||
let $quantityDisplay = $container.find('.dc-qty-badge');
|
||||
// if (!$quantityDisplay.length) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Extract product ID from the image URL
|
||||
const $img = $kanbanRecord.find('.o_kanban_image img');
|
||||
// if (!$img.length) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
const imgSrc = $img.attr('src');
|
||||
const match = imgSrc.match(/[&?]id=(\d+)/);
|
||||
// if (!match || !match[1]) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
const productId = parseInt(match[1]);
|
||||
let currentQuantity = parseFloat($quantityDisplay.text()) || 0;
|
||||
|
||||
|
||||
// Prevent going below zero for remove operation
|
||||
if (operation === 'remove' && currentQuantity <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve sponsorship id from multiple sources (robust against context differences)
|
||||
let sponsorship_id;
|
||||
if (!sponsorship_id) {
|
||||
const $input = $('#cspid');
|
||||
if ($input) sponsorship_id = parseInt($input.val());
|
||||
}
|
||||
|
||||
if (!sponsorship_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable buttons during operation
|
||||
$button.prop('disabled', true).addClass('o_btn_loading');
|
||||
$button.siblings('button').prop('disabled', true);
|
||||
|
||||
// Calculate new quantity
|
||||
let newQuantity = currentQuantity;
|
||||
if (operation === 'first_add') {
|
||||
$button.addClass('d-none');
|
||||
$kanbanRecord.find('.dc-qty-controls').removeClass("d-none");
|
||||
}
|
||||
|
||||
if (operation === 'add' || operation === 'first_add') {
|
||||
newQuantity = newQuantity + 1;
|
||||
}
|
||||
|
||||
if (operation === 'remove') {
|
||||
newQuantity = newQuantity - 1;
|
||||
}
|
||||
|
||||
// Update display optimistically
|
||||
$quantityDisplay.text(newQuantity);
|
||||
|
||||
try {
|
||||
// Call server to update quantity
|
||||
await $.ajax({
|
||||
url: "/qtyupdatecart_so",
|
||||
method: "GET",
|
||||
dataType: 'json',
|
||||
data: {
|
||||
quantity: newQuantity,
|
||||
product_id: productId,
|
||||
sponsorship_id: sponsorship_id
|
||||
}
|
||||
}).catch(function (jqXHR) {
|
||||
// Re-throw with more details
|
||||
const info = {
|
||||
status: jqXHR?.status,
|
||||
responseText: jqXHR?.responseText,
|
||||
readyState: jqXHR?.readyState
|
||||
};
|
||||
throw info;
|
||||
});
|
||||
|
||||
|
||||
} catch (error) {
|
||||
// Revert on error
|
||||
$quantityDisplay.text(currentQuantity);
|
||||
// $quantityDisplay.addClass('bg-danger').removeClass('bg-secondary');
|
||||
setTimeout(() => {
|
||||
// $quantityDisplay.removeClass('bg-danger').addClass('bg-secondary');
|
||||
}, 1000);
|
||||
} finally {
|
||||
// Re-enable buttons
|
||||
$button.prop('disabled', false).removeClass('o_btn_loading');
|
||||
$button.siblings('button').prop('disabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
function change_input_so(params) {
|
||||
let id = params.className
|
||||
console.log(id)
|
||||
let _quantity = params.getElementsByTagName("span")[0];
|
||||
if (_quantity) {
|
||||
params.innerHTML = `<input class='text-center px-1 mx-1' value='${_quantity.innerHTML}' id='inputid${id}' onchange='change_quantity_so("${id}","${_quantity.innerHTML}",event)' min='0' max='999999999' type='number'/>`;
|
||||
}
|
||||
}
|
||||
|
||||
const change_quantity_so = async (id, _quantity, event) => {
|
||||
let qtyspantag = document.createElement("span");
|
||||
let tag = event.target
|
||||
if (Number(tag.value) < 0) {
|
||||
console.log("changing")
|
||||
tag.value = '0.00'
|
||||
// qtyspantag.innerText = '0';
|
||||
// tag.replaceWith(qtyspantag);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = JSON.parse(sessionStorage.getItem("current_action"));
|
||||
if (data) {
|
||||
data = JSON.parse(data);
|
||||
let _sponsorship_id = data.context.sponsorship_id;
|
||||
// let uom_category = await $.ajax({
|
||||
// url: "/getuom_so",
|
||||
// method: "GET",
|
||||
// dataType: 'json',
|
||||
// data: { quantity: Number(tag.value), product_id: id, sale_id: _sale_id }
|
||||
// });
|
||||
// if(uom_category["uom_category"] == 'unit'){
|
||||
// tag.value = Math.round(tag.value);
|
||||
// tag.value = tag.value.concat('.00')
|
||||
// }
|
||||
$.ajax({
|
||||
url: "/qtyupdatecart_so",
|
||||
method: "GET",
|
||||
dataType: 'json',
|
||||
data: { quantity: Number(tag.value), product_id: id, sponsorship_id: _sponsorship_id }
|
||||
});
|
||||
qtyspantag.innerText = tag.value;
|
||||
tag.replaceWith(qtyspantag);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
.o_cart_industry_product {
|
||||
.o_button_invisible {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.o_product_quantity {
|
||||
z-index: 1;
|
||||
font-size: $font-size-lg * 1.5;
|
||||
|
||||
input {
|
||||
width: 104px;
|
||||
|
||||
&:not(.small) {
|
||||
width: 74px;
|
||||
}
|
||||
|
||||
&.o_input {
|
||||
// to prevent the "mini flicker" on the display name of the product.
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
&:not(.o_input) {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Remove arrow buttons input type="number"
|
||||
appearance: textfield;
|
||||
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
.o_form_view .o_form_sheet_bg > .o_form_sheet {
|
||||
width: 95%!important;
|
||||
max-width: initial;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 80vw;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 481px) and (max-width: 767px){
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 400px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 510px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 680px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 900px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 1070px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HD laptops (13–15”)
|
||||
@media screen and (min-width: 1366px) and (max-width: 1599px){
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 1230px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Large laptops / small desktops
|
||||
@media screen and (min-width: 1600px) and (max-width: 1919px){
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 1510px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Full HD monitors (1080p)
|
||||
@media screen and (min-width: 1920px) and (max-width: 2559px){
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 1820px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2K monitors (1440p)
|
||||
@media screen and (min-width: 2560px) and (max-width: 3839px){
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 2480px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4K monitors (2160p+)
|
||||
@media screen and (min-width: 3840px){
|
||||
.fix_overflow {
|
||||
.table-responsive{
|
||||
width: 3750px;
|
||||
overflow-x: auto;
|
||||
table.o_list_table{
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
|
||||
PHONE_FORMAT = re.compile(r'^0*(\d{9})$')
|
||||
ID_FORMATS = re.compile(r'^0*(\d{10})$')
|
||||
PHONE_FORMAT_BACKEND = re.compile(r'^0*(\d{14})$')
|
||||
MOBILE_FORMAT = re.compile(r'^(\d{8})$')
|
||||
MOBILE_FORMAT_BACKEND = re.compile(r'^(\d{14})$')
|
||||
EMAIL_FORMAT = re.compile(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$')
|
||||
ID_FORMAT = re.compile(r'^.+$')
|
||||
# IBAN_FORMAT = re.compile(r'^[a-zA-Z]{2}[0-9]{2}[a-zA-Z0-9]{4}[0-9]{7}([a-zA-Z0-9]?){0,16}$')
|
||||
IBAN_FORMAT = re.compile(r'^(\d{22})$')
|
||||
PASSWORD_FORMAT = re.compile(r'^(?=.*[A-Zء-يa-z])(?=.*\d)[A-Zء-يa-z\d]{6,}$')
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<odoo>
|
||||
<!-- Inherit form account move view -->
|
||||
<record id="takaful_account_move_inherit_form" model="ir.ui.view">
|
||||
<field name="name">takaful.account.move.inherit.form</field>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="account.view_move_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='invoice_origin']" position="attributes">
|
||||
<attribute name="attrs">{'invisible': False}</attribute>
|
||||
|
||||
</xpath>
|
||||
|
||||
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
|
||||
<template id="assets_backend" name="product_catalogue_assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" type="text/scss" href="/odex_takaful/static/src/scss/donation_item_views.scss"/>
|
||||
<link rel="stylesheet" type="text/scss" href="/odex_takaful/static/src/scss/fix_table_overflow.scss"/>
|
||||
<script type="text/javascript" src="/odex_takaful/static/src/js/product_product_views.js"/>
|
||||
<script type="text/javascript" src="/odex_takaful/static/src/js/donation_catalog_button.js"/>
|
||||
<script type="text/javascript" src="/odex_takaful/static/src/js/donation_catalog_controls.js"/>
|
||||
<!-- <script type="text/javascript" src="/odex_takaful/static/src/js/catalog_kanban_dynamic_button.js"/>-->
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- تحسينات بسيطة للتكافل -->
|
||||
<template id="takaful_simple_enhancements" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<style>
|
||||
/* تحسينات بسيطة فقط */
|
||||
.o_form_label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.o_field_widget.o_field_monetary input {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.o_field_widget.o_field_phone input {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
/* Fix top spacing caused by h1 */
|
||||
h1 {
|
||||
margin-bottom: 5px !important;
|
||||
margin-top: 5px !important;
|
||||
}
|
||||
|
||||
/* Record Type Simple & Clean Design */
|
||||
.o_record_type_simple {
|
||||
background: #f8f9fa;
|
||||
padding: 8px 15px;
|
||||
border-radius: 8px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.record_type_options {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.record_option {
|
||||
background: white;
|
||||
border: 2px solid #e9ecef;
|
||||
border-radius: 8px;
|
||||
padding: 15px 25px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
min-width: 120px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.record_option:hover {
|
||||
border-color: #007bff;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 8px rgba(0,123,255,0.15);
|
||||
}
|
||||
|
||||
.record_option.selected {
|
||||
border-color: #28a745;
|
||||
background: #f8fff9;
|
||||
box-shadow: 0 2px 8px rgba(40,167,69,0.15);
|
||||
}
|
||||
|
||||
.record_option i {
|
||||
font-size: 24px;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.donation_option.selected i {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.sponsorship_option.selected i {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
/* Donation Mechanism Simple Design */
|
||||
.o_donation_mechanism_simple {
|
||||
margin: 8px 0;
|
||||
padding: 8px 15px;
|
||||
background: #fff8e1;
|
||||
border-radius: 6px;
|
||||
border-left: 4px solid #ffc107;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mechanism_options {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mechanism_option {
|
||||
background: white;
|
||||
border: 2px solid #e9ecef;
|
||||
border-radius: 6px;
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 120px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mechanism_option i {
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.mechanism_option span {
|
||||
min-width: 90px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mechanism_option:hover {
|
||||
border-color: #ffc107;
|
||||
background: #fffbf0;
|
||||
}
|
||||
|
||||
.mechanism_option.selected {
|
||||
border-color: #ff9800;
|
||||
background: #fff3e0;
|
||||
color: #e65100;
|
||||
}
|
||||
|
||||
/* Help Messages Styling */
|
||||
.alert {
|
||||
margin: 8px 0;
|
||||
padding: 8px 15px;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background-color: #e8f4fd;
|
||||
border: 1px solid #bee5eb;
|
||||
color: #0c5460;
|
||||
}
|
||||
|
||||
.alert-primary {
|
||||
background-color: #cce7ff;
|
||||
border: 1px solid #b3d7ff;
|
||||
color: #004085;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
odoo.define('takaful.simple_ui_enhancement', function (require) {
|
||||
'use strict';
|
||||
|
||||
var FormController = require('web.FormController');
|
||||
|
||||
FormController.include({
|
||||
start: function () {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
if (self.modelName === 'takaful.sponsorship') {
|
||||
self._setupSimpleUI();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_update: function () {
|
||||
var result = this._super.apply(this, arguments);
|
||||
if (this.modelName === 'takaful.sponsorship') {
|
||||
var self = this;
|
||||
setTimeout(function() {
|
||||
self._setupSimpleUI();
|
||||
}, 50);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
_onSave: function () {
|
||||
var result = this._super.apply(this, arguments);
|
||||
if (this.modelName === 'takaful.sponsorship') {
|
||||
var self = this;
|
||||
setTimeout(function() {
|
||||
self._setupSimpleUI();
|
||||
}, 100);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
_setupSimpleUI: function () {
|
||||
var self = this;
|
||||
var currentData = self.model.localData[self.handle].data;
|
||||
|
||||
var isNewRecord = !currentData.id;
|
||||
var isDraftState = currentData.state === 'draft';
|
||||
var isEditMode = self.mode === 'edit';
|
||||
var isEditable = isNewRecord || (isDraftState && isEditMode);
|
||||
|
||||
// Remove old event handlers to prevent duplicates
|
||||
this.$('.record_option').off('click');
|
||||
this.$('.mechanism_option').off('click');
|
||||
|
||||
// Maintain visual selection (selected class) but disable interaction
|
||||
// Update selected state based on current values
|
||||
var recordType = currentData.record_type;
|
||||
var donationMechanism = currentData.donation_mechanism;
|
||||
|
||||
// Update visual selection for record_type
|
||||
this.$('.record_option').each(function() {
|
||||
var $opt = $(this);
|
||||
if ($opt.data('value') === recordType) {
|
||||
$opt.addClass('selected');
|
||||
} else {
|
||||
$opt.removeClass('selected');
|
||||
}
|
||||
});
|
||||
|
||||
// Update visual selection for donation_mechanism
|
||||
this.$('.mechanism_option').each(function() {
|
||||
var $opt = $(this);
|
||||
if ($opt.data('value') === donationMechanism) {
|
||||
$opt.addClass('selected');
|
||||
} else {
|
||||
$opt.removeClass('selected');
|
||||
}
|
||||
});
|
||||
|
||||
if (!isEditable) {
|
||||
this.$('.record_option').css({
|
||||
'pointer-events': 'none',
|
||||
'cursor': 'not-allowed'
|
||||
});
|
||||
this.$('.mechanism_option').css({
|
||||
'pointer-events': 'none',
|
||||
'cursor': 'not-allowed'
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
this.$('.record_option').css({
|
||||
'pointer-events': 'auto',
|
||||
'cursor': 'pointer'
|
||||
});
|
||||
this.$('.mechanism_option').css({
|
||||
'pointer-events': 'auto',
|
||||
'cursor': 'pointer'
|
||||
});
|
||||
}
|
||||
|
||||
// Record Type Options - Odoo 14 Compatible Method
|
||||
this.$('.record_option').on('click', function () {
|
||||
var $option = $(this);
|
||||
var recordType = $option.data('value');
|
||||
var currentData = self.model.localData[self.handle].data;
|
||||
|
||||
// Clear sponsor_id when changing type if not registered
|
||||
var sponsorOrDonorType = currentData.sponsor_or_donor_type;
|
||||
var sponsorDonorType = currentData.sponsor_donor_type;
|
||||
var changes = {record_type: recordType};
|
||||
|
||||
// Clear sponsor_id if switching types and not 'registered'
|
||||
if (sponsorOrDonorType !== 'registered' && sponsorDonorType !== 'registered') {
|
||||
changes.sponsor_id = false;
|
||||
}
|
||||
|
||||
// Update field value using Odoo 14 method
|
||||
self.trigger_up('field_changed', {
|
||||
dataPointID: self.handle,
|
||||
changes: changes
|
||||
});
|
||||
|
||||
// Update visual selection
|
||||
self.$('.record_option').removeClass('selected');
|
||||
$option.addClass('selected');
|
||||
});
|
||||
|
||||
// Donation Mechanism Options - Odoo 14 Compatible Method
|
||||
this.$('.mechanism_option').on('click', function () {
|
||||
var $option = $(this);
|
||||
var mechanism = $option.data('value');
|
||||
|
||||
// Update field value using Odoo 14 method
|
||||
self.trigger_up('field_changed', {
|
||||
dataPointID: self.handle,
|
||||
changes: {donation_mechanism: mechanism}
|
||||
});
|
||||
|
||||
// Update visual selection
|
||||
self.$('.mechanism_option').removeClass('selected');
|
||||
$option.addClass('selected');
|
||||
});
|
||||
|
||||
// Set default selection on load
|
||||
setTimeout(function() {
|
||||
var currentRecordType = self.model.localData[self.handle].data.record_type;
|
||||
if (currentRecordType) {
|
||||
self.$('.record_option[data-value="' + currentRecordType + '"]').addClass('selected');
|
||||
} else {
|
||||
// Default to donation as requested
|
||||
self.$('.record_option[data-value="donation"]').addClass('selected');
|
||||
}
|
||||
|
||||
var currentMechanism = self.model.localData[self.handle].data.donation_mechanism;
|
||||
if (currentMechanism) {
|
||||
self.$('.mechanism_option[data-value="' + currentMechanism + '"]').addClass('selected');
|
||||
} else {
|
||||
// Default to without_conditions (غير مشروط) as requested
|
||||
self.$('.mechanism_option[data-value="without_conditions"]').addClass('selected');
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<odoo>
|
||||
<!-- Inherit the original form view -->
|
||||
<record id="inherit_grant_benefit_form_add_replaced" model="ir.ui.view">
|
||||
<field name="name">grant.benefit.form.inherit.replaced</field>
|
||||
<field name="model">grant.benefit</field>
|
||||
<field name="inherit_id" ref="odex_benefit.grant_benefit_form"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button name="action_open_replacements" class="oe_stat_button" string="Replacement Processes"
|
||||
type="object" icon="fa-users">
|
||||
</button>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='member_ids']/tree/field[@name='state']" position="before">
|
||||
<field name="replaced" readonly="1" invisible="1"/>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="family_member_form_inherit_add_replaced" model="ir.ui.view">
|
||||
<field name="name">family.member.form.inherit.add.replaced</field>
|
||||
<field name="model">family.member</field>
|
||||
<field name="inherit_id" ref="odex_benefit.family_member_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='member_status']" position="after">
|
||||
|
||||
<field name="replaced" readonly="1" invisible="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- Tree View -->
|
||||
<record id="donation_extension_history_tree" model="ir.ui.view">
|
||||
<field name="name">donation.extension.history.tree</field>
|
||||
<field name="model">donation.extension.history</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree create="0" edit="0" delete="0">
|
||||
<field name="extension_ref"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="product_template_id"/>
|
||||
<field name="extension_months"/>
|
||||
<field name="extension_amount"/>
|
||||
<field name="old_end_date"/>
|
||||
<field name="new_end_date"/>
|
||||
<field name="extension_date"/>
|
||||
<field name="user_id"/>
|
||||
<field name="invoice_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Form View -->
|
||||
<record id="donation_extension_history_form" model="ir.ui.view">
|
||||
<field name="name">donation.extension.history.form</field>
|
||||
<field name="model">donation.extension.history</field>
|
||||
<field name="arch" type="xml">
|
||||
<form create="0" edit="0" delete="0">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="extension_ref"/>
|
||||
<field name="donation_detail_id"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="sponsorship_id"/>
|
||||
<field name="product_template_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="extension_amount"/>
|
||||
<field name="extension_months"/>
|
||||
<field name="old_end_date"/>
|
||||
<field name="new_end_date"/>
|
||||
<field name="extension_date"/>
|
||||
<field name="user_id"/>
|
||||
<field name="invoice_id"/>
|
||||
<field name="old_direct_debit"/>
|
||||
<field name="new_direct_debit"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<field name="notes"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Action -->
|
||||
<record id="action_donation_extension_history" model="ir.actions.act_window">
|
||||
<field name="name">Extension History</field>
|
||||
<field name="res_model">donation.extension.history</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No extension history found
|
||||
</p>
|
||||
<p>
|
||||
Extension history will appear here when donations are extended.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Menu Item (Optional - can be added to existing menu structure) -->
|
||||
<!-- <menuitem id="menu_donation_extension_history"
|
||||
name="Extension History"
|
||||
parent="existing_parent_menu"
|
||||
action="action_donation_extension_history"
|
||||
sequence="100"/> -->
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="product_product_view_kanban" model="ir.ui.view">
|
||||
<field name="name">product.product.view.kanban</field>
|
||||
<field name="model">donations.items</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban edit="0" create="0" class="o_kanban_mobile o_cart_kanban">
|
||||
<field name="id"/>
|
||||
<field name="name"/>
|
||||
<field name="donation_types"/>
|
||||
<field name="payment_method_id"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="o_product_quantity d-flex flex-column justify-content-between"
|
||||
style="min-height: 100px">
|
||||
<div class="o_kanban_image">
|
||||
|
||||
</div>
|
||||
<div class="oe_kanban_details p-2 d-flex">
|
||||
<div class="o_kanban_record_top flex-column w-100 "
|
||||
style="justify-content: space-between;">
|
||||
<div class="o_kanban_record_title">
|
||||
<strong>
|
||||
<field name="name"/>
|
||||
</strong>
|
||||
</div>
|
||||
|
||||
<div style="z-index:1;align-items: center;">
|
||||
<button id="add_payment_method" string="Add Payment Method" style="width:140px;height:27px"
|
||||
class="btn btn-primary"
|
||||
type="object" name="add_payment_method">
|
||||
Add Payment
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Amount :
|
||||
<field name="fixed_donation_amount" widget="monetary"></field>
|
||||
</strong>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div name="_quantity"
|
||||
class="h-100 ml-2 d-flex align-items-center o_product_quantity o_field_widget o_quick_editable"
|
||||
style="z-index:1;align-items: center;">
|
||||
<button id="remove_quantity"
|
||||
class="btn d-flex align-items-center justify-content-center o_qty_button btn-light text-muted"
|
||||
type="object" name="remove_quantity_button_so">
|
||||
<i class="fa fa-minus center" title="Decrease"/>
|
||||
</button>
|
||||
<span style="font-size:1.5rem;"
|
||||
t-attf-class="{{record.id.value}}"
|
||||
onclick="change_input_so(this)">
|
||||
<field name="_quantity"></field>
|
||||
</span>
|
||||
<button id="add_quantity"
|
||||
class="btn d-flex align-items-center justify-content-center o_qty_button btn-light text-muted"
|
||||
type="object" name="add_quantity_button_so">
|
||||
<i class="fa fa-plus" title="Increase"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- Tree View -->
|
||||
<record id="donation_replacement_log_tree" model="ir.ui.view">
|
||||
<field name="name">donation.replacement.log.tree</field>
|
||||
<field name="model">donation.replacement.log</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree create="0" edit="0" delete="0">
|
||||
<field name="replacement_ref"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="record_type"/>
|
||||
<field name="old_benefit"/>
|
||||
<field name="new_benefit"/>
|
||||
<field name="replacement_date"/>
|
||||
<field name="replacement_reason_id"/>
|
||||
|
||||
<field name="user_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Form View -->
|
||||
<record id="donation_replacement_log_form" model="ir.ui.view">
|
||||
<field name="name">donation.replacement.log.form</field>
|
||||
<field name="model">donation.replacement.log</field>
|
||||
<field name="arch" type="xml">
|
||||
<form create="0" edit="0" delete="0">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="replacement_ref"/>
|
||||
<field name="donation_detail_id"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="sponsorship_id"/>
|
||||
<field name="replacement_reason_id"/>
|
||||
|
||||
</group>
|
||||
<group>
|
||||
<field name="old_benefit"/>
|
||||
<field name="new_benefit"/>
|
||||
<field name="replacement_date"/>
|
||||
<field name="user_id"/>
|
||||
|
||||
</group>
|
||||
</group>
|
||||
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Action -->
|
||||
<record id="action__replacement_log_history" model="ir.actions.act_window">
|
||||
<field name="name">Replacement Log</field>
|
||||
<field name="res_model">donation.replacement.log</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No extension history found
|
||||
</p>
|
||||
<p>
|
||||
Replacement Log will appear here when Benefit donations are replaced.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,485 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="donations_details_lines_view_search" model="ir.ui.view">
|
||||
<field name="name">donations.details.lines.view.search</field>
|
||||
<field name="model">donations.details.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Donation Details Lines">
|
||||
<field name="sequence_no"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="benefit_id"/>
|
||||
<field name="product_template_id"/>
|
||||
<field name="branch_custom_id"/>
|
||||
<separator/>
|
||||
<!-- State Filters -->
|
||||
<filter string="To Pay" name="filter_draft" domain="[('state', '=', 'draft')]"/>
|
||||
<filter string="Waiting" name="filter_waiting" domain="[('state', '=', 'waiting')]"/>
|
||||
<filter string="To Replace" name="filter_replace" domain="[('state', '=', 'replace')]"/>
|
||||
<filter string="Active" name="filter_active" domain="[('state', '=', 'active')]"/>
|
||||
<filter string="Closed" name="filter_closed" domain="[('state', '=', 'closed')]"/>
|
||||
<filter string="Extended" name="filter_extended" domain="[('state', '=', 'extended')]"/>
|
||||
<separator/>
|
||||
<!-- Record Type Filters -->
|
||||
<filter string="Sponsorship" name="filter_sponsorship" domain="[('donation_type', '=', 'sponsorship')]"/>
|
||||
<filter string="Donation" name="filter_donation" domain="[('donation_type', '=', 'donation')]"/>
|
||||
<filter string="Waqf" name="filter_waqf" domain="[('donation_type', '=', 'waqf')]"/>
|
||||
<separator/>
|
||||
<!-- Sponsorship Duration Filters -->
|
||||
<filter string="Permanent" name="filter_permanent" domain="[('sponsorship_duration', '=', 'permanent')]"/>
|
||||
<filter string="Temporary" name="filter_temporary" domain="[('sponsorship_duration', '=', 'temporary')]"/>
|
||||
<separator/>
|
||||
<!-- Donation Mechanism Filters -->
|
||||
<filter string="With Conditions" name="filter_with_conditions" domain="[('donation_mechanism', '=', 'with_conditions')]"/>
|
||||
<filter string="Without Conditions" name="filter_without_conditions" domain="[('donation_mechanism', '=', 'without_conditions')]"/>
|
||||
<separator/>
|
||||
<filter string="Without Beneficiary" name="filter_no_benefit" domain="[('benefit_id', '=', False), ('donation_type', '=', 'sponsorship')]"/>
|
||||
<filter string="With Beneficiary" name="filter_with_benefit" domain="[('benefit_id', '!=', False), ('donation_type', '=', 'sponsorship')]"/>
|
||||
<separator/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="State" name="group_state" context="{'group_by': 'state'}"/>
|
||||
<filter string="Donation Type" name="group_donation_type" context="{'group_by': 'donation_type'}"/>
|
||||
<filter string="Sponsorship Duration" name="group_duration" context="{'group_by': 'sponsorship_duration'}"/>
|
||||
<filter string="Donation Mechanism" name="group_mechanism" context="{'group_by': 'donation_mechanism'}"/>
|
||||
<filter string="Sponsor" name="group_sponsor" context="{'group_by': 'sponsor_id'}"/>
|
||||
<filter string="Branch" name="group_branch" context="{'group_by': 'branch_custom_id'}"/>
|
||||
<filter string="Product" name="group_product" context="{'group_by': 'product_template_id'}"/>
|
||||
<filter string="Creation Date" name="group_creation_date" context="{'group_by': 'create_date'}"/>
|
||||
</group>
|
||||
<separator/>
|
||||
<searchpanel>
|
||||
<field name="state" enable_counters="1"/>
|
||||
<field name="record_type" enable_counters="1"/>
|
||||
<field name="sponsorship_duration" enable_counters="1"/>
|
||||
<field name="donation_mechanism" enable_counters="1"/>
|
||||
</searchpanel>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="donations_details_lines_view_tree" model="ir.ui.view">
|
||||
<field name="name">donations.details.lines.view.tree</field>
|
||||
<field name="model">donations.details.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree default_order="create_date asc , waiting_date asc " create="0" edit="0" >
|
||||
<field name="sponsorship_scheduling_line_ids" invisible="1" />
|
||||
<field name="direct_debit" invisible="1" />
|
||||
<field name="sequence_no" />
|
||||
<field name="sponsor_id" />
|
||||
|
||||
<field name="sponsor_phone" widget="phone"/>
|
||||
<field name="donation_type" optional="show"/>
|
||||
<field name="sponsorship_duration" optional="hide"/>
|
||||
<field name="donation_mechanism" optional="hide"/>
|
||||
<field name="product_template_id" />
|
||||
<field name="benefit_status" widget="badge"
|
||||
decoration-success="benefit_status == 'benefit'"
|
||||
decoration-danger="benefit_status == 'non_benefit'"/>
|
||||
<field name="start_date" widget="date"/>
|
||||
<field name="end_date" widget="date"/>
|
||||
<field name="donation_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="total_donation_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="branch_custom_id" optional="hide" />
|
||||
<field name="benefit_family_code" optional="hide" />
|
||||
<field name="benefit_id" optional="hide" />
|
||||
<!-- <field name="sponsorship_creation_date" />-->
|
||||
<field name="create_date" optional="hide"/>
|
||||
<field name="waiting_date" widget="date" optional="hide"/>
|
||||
<field name="state" widget="badge"
|
||||
decoration-muted="state == 'draft'"
|
||||
decoration-warning="state == 'waiting'"
|
||||
decoration-success="state in ['active', 'paid','confirmed']"
|
||||
decoration-danger="state == 'closed'"
|
||||
decoration-info="state == 'extended'" />
|
||||
<field name="age_category" widget="state" />
|
||||
<button name="action_view_scheduling_lines"
|
||||
string="View Scheduling Lines"
|
||||
type="object"
|
||||
attrs="{'invisible': ['|', ('direct_debit', '=', False), ('sponsorship_scheduling_line_ids', '=', [])]}"
|
||||
class="btn-secondary"
|
||||
icon="fa-calendar" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="donations_details_lines_view_form" model="ir.ui.view">
|
||||
<field name="name">donations.details.lines.view.form</field>
|
||||
<field name="model">donations.details.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Donation Details" create="0" edit="0" >
|
||||
<header>
|
||||
<!-- <button name="action_register_payment"
|
||||
string="Register Payment"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
attrs="{'invisible': ['|', '|', ('direct_debit', '=', True), ('is_paid', '=', True), ('parent_state', '!=', 'confirmed')]}" /> -->
|
||||
<button string="Compute Sponsorships"
|
||||
name="compute_sponsorships_lines"
|
||||
type="object"
|
||||
class="oe_highlight"
|
||||
attrs="{'invisible': ['|', ('sponsorships_computed', '=', True), ('direct_debit', '=', False)]}" />
|
||||
<button string="Extend Donation"
|
||||
name="action_extend_sponsorship"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-plus-circle"
|
||||
attrs="{'invisible': [('show_extend_button', '=', False)]}" />
|
||||
|
||||
<button string="Orphan Replacement"
|
||||
name="action_view_replacement_wizard"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-exchange"
|
||||
attrs="{'invisible': [('show_replaced_button', '=', False)]}"
|
||||
groups="odex_takaful.group_orphan_replacement" />
|
||||
|
||||
<button string="Replace Sponsor"
|
||||
name="replace_sponsor_wizard"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-exchange"
|
||||
attrs="{'invisible': [('sponsor_id', '=', False)]}"
|
||||
groups="odex_takaful.group_replace_sponsor" />
|
||||
|
||||
<button string="Add Benefit"
|
||||
name="add_benefit_wizard"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-plus-circle"
|
||||
attrs="{'invisible': [('show_add_benefit_button', '=', False)]}"
|
||||
groups="odex_takaful.group_kufula_user" />
|
||||
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="draft,confirmed,waiting,active,replace,closed" />
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_view_extension_history"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-history"
|
||||
attrs="{'invisible': [('extension_count', '=', 0)]}">
|
||||
<field name="extension_count" widget="statinfo" string="Extensions"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_view_replacement_log"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-exchange"
|
||||
attrs="{'invisible': [('replacement_count', '=', 0)]}">
|
||||
<field name="replacement_count" widget="statinfo" string="Replacement"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="sequence_no" readonly="1" />
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<group>
|
||||
<group string="Donation Information">
|
||||
<field name="ages" invisible="1" />
|
||||
<field name="period_display" invisible="0" />
|
||||
<field name="waiting_date" widget="date" invisible="1"/>
|
||||
<field name="donation_type" invisible="1"/>
|
||||
<field name="donation_types"
|
||||
attrs="{'invisible': [('donation_type', '!=', 'donation')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="product_template_id"
|
||||
attrs="{'readonly': [('parent_state', '!=', 'draft')]}"
|
||||
options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/>
|
||||
<field name="product_id" invisible="1" />
|
||||
<field name="donation_mechanism" invisible="1" />
|
||||
<field name="fixed_value" invisible="1" />
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="total_donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
</group>
|
||||
<group string="Sponsorship Information">
|
||||
<field name="sponsorship_id" readonly="1"
|
||||
attrs="{'invisible': [('sponsorship_id', '=', False)]}" />
|
||||
<field name="sponsorship_mechanism_id" readonly="1"
|
||||
attrs="{'invisible': [('sponsorship_mechanism_id', '=', False)]}" />
|
||||
<field name="sponsor_id"
|
||||
attrs="{'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="sponsor_phone" widget="phone"
|
||||
attrs="{'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="branch_custom_id"
|
||||
attrs="{'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="sponsorship_creation_date" invisible="1" />
|
||||
<field name="parent_state" invisible="1" />
|
||||
<field name="is_paid" invisible="1" />
|
||||
<field name="show_extend_button" invisible="1" />
|
||||
<field name="show_replaced_button" invisible="1" />
|
||||
<field name="show_add_benefit_button" invisible="1" />
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<notebook>
|
||||
<page string="Sponsorship Details" attrs="{'invisible': [('donation_mechanism', '!=', 'with_conditions')]}">
|
||||
<group>
|
||||
<group>
|
||||
<field name="display_type" invisible="1" />
|
||||
<field name="sequence" invisible="1" />
|
||||
<field name="sponsorships_computed" invisible="1" />
|
||||
<field name="record_type" invisible="1" />
|
||||
<field name="donation_type"
|
||||
attrs="{'invisible': [('record_type', '!=', 'sponsorship')], 'readonly': ['|', ('record_type', '=', 'sponsorship'), ('parent_state', '!=', 'draft')]}"
|
||||
force_save="1" />
|
||||
<field name="age_category" widget="state" />
|
||||
<field name="direct_debit" invisible="1" />
|
||||
<field name="donation_types"
|
||||
attrs="{
|
||||
'invisible': [('record_type', '!=', 'donation')],
|
||||
'required': [('record_type', '=', 'donation')],
|
||||
'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="sponsorship_duration"
|
||||
attrs="{'invisible': [('donation_type','!=','sponsorship')], 'required': [('donation_type','=','sponsorship')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="payment_option"
|
||||
attrs="{'invisible': [('sponsorship_duration','!=','temporary')], 'required': [('sponsorship_duration','=','temporary')], 'readonly': [('parent_state', '!=', 'draft')]}"
|
||||
readonly="1" force_save="1" />
|
||||
<field name="payment_month_count"
|
||||
attrs="{'invisible': ['&', ('sponsorship_duration','!=','temporary'), ('direct_debit', '=', False)], 'required': [('sponsorship_duration','=','temporary')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="start_date" string="Start Date" widget="date"
|
||||
attrs="{'invisible': ['&', ('sponsorship_duration', '!=', 'temporary'), ('direct_debit', '=', False)], 'required': [('sponsorship_duration', '=','temporary')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="end_date" string="End Date" widget="date"
|
||||
attrs="{'invisible': ['&', ('sponsorship_duration', '!=', 'temporary'), ('direct_debit', '=', False)], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="donation_mechanism" invisible="1" />
|
||||
<field name="fixed_value" invisible="1" />
|
||||
<field name="donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'readonly':['|', ('fixed_value','=',True), ('parent_state', '!=', 'draft')]}"
|
||||
force_save="1" required="1" />
|
||||
<field name="benefits_count"
|
||||
attrs="{'invisible':[('sponsorship_type','!=','group')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="total_donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'invisible':[('sponsorship_type','!=','group')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="name" attrs="{'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
</group>
|
||||
</group>
|
||||
<group string="Benefit Details"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')]}">
|
||||
<group>
|
||||
<field name="members_domain_ids" invisible="1" />
|
||||
<field name="family_domain_ids" invisible="1" />
|
||||
<field name="sponsorship_type"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')], 'required': [('donation_mechanism','=','with_conditions')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="benefit_type"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')], 'required': [('donation_mechanism','=','with_conditions')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="benefit_id"
|
||||
attrs="{'invisible': ['|', ('sponsorship_type','!=','person'), ('donation_mechanism','!=','with_conditions')], 'required': [('members_domain_ids', '!=', []), ('sponsorship_type','=','person'), ('donation_mechanism','=','with_conditions'), ('state', 'in', ['active', 'closed', 'extended'])], 'readonly': ['&', ('parent_state', '!=', 'draft'), ('state', '!=', 'waiting')]}"
|
||||
options="{'no_create': True, 'no_create_edit':True}" />
|
||||
<field name="family_id"
|
||||
attrs="{'invisible': ['&', ('sponsorship_type','=','group'), ('record_type','=','sponsorship')],
|
||||
'readonly': ['|', '|', ('sponsorship_type', '!=', 'group'), ('record_type','!=','donation'), ('parent_state', '!=', 'draft')],
|
||||
'required': ['&', ('sponsorship_type', '=','group'), ('record_type','=','donation')]}"
|
||||
groups="odex_takaful.sponsorship_system_manager_group" />
|
||||
</group>
|
||||
<!-- <group/> -->
|
||||
<group
|
||||
attrs="{'invisible': ['&', ('sponsorship_type','=','group'), ('record_type','=','donation')]}">
|
||||
<field name="gender"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="age_category_id"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="education_status"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="education_level"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="benefit_id_number"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
<field name="benefit_family_code"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')], 'readonly': [('parent_state', '!=', 'draft')]}" />
|
||||
</group>
|
||||
</group>
|
||||
<group string="Orphans List"
|
||||
attrs="{'invisible': ['|', '|',('record_type','!=','sponsorship'), ('sponsorship_type', '!=', 'group'), ('benefit_type', '!=', 'orphan')]}">
|
||||
<field name="benefit_ids" nolabel="1" attrs="{'readonly': ['&', ('parent_state', '!=', 'draft'), ('state', '!=', 'waiting')]}" />
|
||||
</group>
|
||||
<group string="Widows List"
|
||||
attrs="{'invisible': ['|', '|',('record_type','!=','sponsorship'), ('sponsorship_type', '!=', 'group'), ('benefit_type', '!=', 'widow')]}">
|
||||
<field name="benefit_ids" nolabel="1" attrs="{'readonly': ['&', ('parent_state', '!=', 'draft'), ('state', '!=', 'waiting')]}" />
|
||||
</group>
|
||||
<group string="Orphans and Widows List"
|
||||
attrs="{'invisible': ['|', '|',('record_type','!=','sponsorship'), ('sponsorship_type', '!=', 'group'), ('benefit_type', '!=', 'both')]}">
|
||||
<field name="benefit_ids" nolabel="1" attrs="{'readonly': ['&', ('parent_state', '!=', 'draft'), ('state', '!=', 'waiting')]}" />
|
||||
</group>
|
||||
</page>
|
||||
|
||||
<page string="Sponsorship Scheduling"
|
||||
attrs="{'invisible': [('sponsorship_scheduling_line_ids', '=', False)]}">
|
||||
<field name="sponsorship_scheduling_line_ids" mode="tree">
|
||||
<tree create="false" delete="false" edit="false">
|
||||
<field name="sequence_no" />
|
||||
<field name="beneficiary_id" />
|
||||
<field name="month_year" />
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="refunded_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="status" widget="badge"
|
||||
decoration-danger="status == 'unpaid'"
|
||||
decoration-success="status == 'paid'"
|
||||
decoration-muted="status in ('partial_refund','fully_refund')" />
|
||||
<field name="sponsorship_state" invisible="1" />
|
||||
<field name="cancel_refund" invisible="1" />
|
||||
|
||||
<!-- To approve refund for donation lines -->
|
||||
<button string="Approve Refund" name="approve_refund"
|
||||
type="object" class="oe_highlight"
|
||||
attrs="{'invisible': ['|', ('parent.donation_type', '!=', 'donation'), ('sponsorship_state', '!=', 'approve_refund')]}"
|
||||
groups="odex_takaful.group_refund_approval" />
|
||||
|
||||
<!-- To action refund paid line -->
|
||||
<button string="Action Refund" name="action_refund"
|
||||
type="object" class="oe_highlight"
|
||||
attrs="{'invisible': ['|', '|', '|', ('parent.donation_type', '!=', 'donation'), ('cancel_refund', '=', True), ('status', 'not in', ['paid', 'partial_refund']), ('sponsorship_state', 'not in', ['paid','partial_refund'])]}" />
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" />
|
||||
<field name="message_ids" />
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="donations_details_lines_view_tree_waiting" model="ir.ui.view">
|
||||
<field name="name">donations.details.lines.view.tree.waiting</field>
|
||||
<field name="model">donations.details.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree default_order="waiting_date asc" create="0" edit="0" >
|
||||
<field name="sponsorship_scheduling_line_ids" invisible="1" />
|
||||
<field name="direct_debit" invisible="1" />
|
||||
<field name="sequence_no" />
|
||||
<field name="sponsor_id" />
|
||||
<field name="sponsor_phone" widget="phone"/>
|
||||
<field name="donation_type" optional="show"/>
|
||||
<field name="sponsorship_duration" optional="hide"/>
|
||||
<field name="donation_mechanism" optional="hide"/>
|
||||
<field name="product_template_id" />
|
||||
<field name="benefit_status" widget="badge"
|
||||
decoration-success="benefit_status == 'benefit'"
|
||||
decoration-danger="benefit_status == 'non_benefit'"/>
|
||||
<field name="start_date" widget="date"/>
|
||||
<field name="end_date" widget="date"/>
|
||||
<field name="donation_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="total_donation_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="branch_custom_id" optional="hide" />
|
||||
<field name="benefit_family_code" optional="hide" />
|
||||
<field name="benefit_id" optional="hide" />
|
||||
<!-- <field name="sponsorship_creation_date" />-->
|
||||
<field name="create_date" optional="hide"/>
|
||||
<field name="waiting_date" />
|
||||
<field name="waiting_date" string='مدة الانتظار' widget="remaining_days" />
|
||||
<!-- <field name="period_display" />-->
|
||||
<field name="state" widget="badge"
|
||||
decoration-muted="state == 'draft'"
|
||||
decoration-warning="state == 'waiting'"
|
||||
decoration-success="state in ['active', 'paid','confirmed']"
|
||||
decoration-danger="state == 'closed'"
|
||||
decoration-info="state == 'extended'" />
|
||||
<field name="age_category" widget="state" />
|
||||
|
||||
|
||||
<button name="action_view_scheduling_lines"
|
||||
string="View Scheduling Lines"
|
||||
type="object"
|
||||
attrs="{'invisible': ['|', ('direct_debit', '=', False), ('sponsorship_scheduling_line_ids', '=', [])]}"
|
||||
class="btn-secondary"
|
||||
icon="fa-calendar" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="donations_details_lines_view_tree_replace" model="ir.ui.view">
|
||||
<field name="name">donations.details.lines.view.tree.replace</field>
|
||||
<field name="model">donations.details.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree default_order="end_date asc" create="0" edit="0" >
|
||||
<field name="sponsorship_scheduling_line_ids" invisible="1" />
|
||||
<field name="direct_debit" invisible="1" />
|
||||
<field name="sequence_no" />
|
||||
<field name="sponsor_id" />
|
||||
<field name="sponsor_phone" widget="phone"/>
|
||||
<field name="donation_type" optional="show"/>
|
||||
<field name="sponsorship_duration" optional="hide"/>
|
||||
<field name="donation_mechanism" optional="hide"/>
|
||||
<field name="product_template_id" />
|
||||
<field name="benefit_status" widget="badge"
|
||||
decoration-success="benefit_status == 'benefit'"
|
||||
decoration-danger="benefit_status == 'non_benefit'"/>
|
||||
<field name="start_date" widget="date"/>
|
||||
<field name="end_date" widget="date"/>
|
||||
<field name="donation_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="total_donation_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="branch_custom_id" optional="hide" />
|
||||
<field name="benefit_family_code" optional="hide" />
|
||||
<field name="benefit_id" optional="hide" />
|
||||
<!-- <field name="sponsorship_creation_date" />-->
|
||||
<field name="create_date" optional="hide"/>
|
||||
<field name="actual_end_date" widget="date" string="تاريخ خروج المستفيد" />
|
||||
<field name="actual_end_date" widget="remaining_days" string="فترة الخروج" />
|
||||
<field name="state" widget="badge"
|
||||
decoration-muted="state == 'draft'"
|
||||
decoration-warning="state == 'waiting'"
|
||||
decoration-success="state in ['active', 'paid','confirmed']"
|
||||
decoration-danger="state == 'closed'"
|
||||
decoration-info="state == 'extended'" />
|
||||
<field name="age_category" widget="state" />
|
||||
<button name="action_view_scheduling_lines"
|
||||
string="View Scheduling Lines"
|
||||
type="object"
|
||||
attrs="{'invisible': ['|', ('direct_debit', '=', False), ('sponsorship_scheduling_line_ids', '=', [])]}"
|
||||
class="btn-secondary"
|
||||
icon="fa-calendar" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="donations_details_lines_action" model="ir.actions.act_window">
|
||||
<field name="name">Donations Details Lines</field>
|
||||
<field name="res_model">donations.details.lines</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="donations_details_lines_view_search"/>
|
||||
<field name="context">{'create': False, 'delete': False}</field>
|
||||
</record>
|
||||
|
||||
<record id="donations_details_lines_waiting_action" model="ir.actions.act_window">
|
||||
<field name="name">Donations Details Lines waiting</field>
|
||||
<field name="res_model">donations.details.lines</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('state', '=', 'waiting')]</field>
|
||||
<field name="search_view_id" ref="donations_details_lines_view_search"/>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('donations_details_lines_view_tree_waiting')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('donations_details_lines_view_form')})]"/>
|
||||
<field name="context">{'create': False, 'delete': False}</field>
|
||||
</record>
|
||||
|
||||
<record id="donations_details_lines_replace_action" model="ir.actions.act_window">
|
||||
<field name="name">Donations Details Lines Replacement</field>
|
||||
<field name="res_model">donations.details.lines</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('state', '=', 'replace')]</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('donations_details_lines_view_tree_replace')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('donations_details_lines_view_form')})]"/>
|
||||
<field name="search_view_id" ref="donations_details_lines_view_search"/>
|
||||
<field name="context">{'create': False, 'delete': False}</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Inherit Family Member Form to Add Donation Details Smart Button -->
|
||||
<record id="family_member_form_inherit_donation_button" model="ir.ui.view">
|
||||
<field name="name">family.member.form.inherit.donation.button</field>
|
||||
<field name="model">family.member</field>
|
||||
<field name="inherit_id" ref="odex_benefit.family_member_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button icon="fa-money" name="action_open_donation_detail" type="object"
|
||||
attrs="{'invisible': [('donation_details_count', '=', 0)]}">
|
||||
<field name="donation_details_count" string="Donation Details"
|
||||
widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='sponsor_related_id']" position="replace">
|
||||
|
||||
<field name="sponsor_related_id" readonly="1" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//page[4]" position="after">
|
||||
<page name="kafala_info" string="Kafala Information">
|
||||
<group>
|
||||
<field name="kafala_status" readonly="1"/>
|
||||
<field name="sponsor_related_id"
|
||||
readonly="1"/>
|
||||
<field name="sponsor_id"
|
||||
attrs="{'readonly':[('state','not in',['draft','complete_info'])]}"
|
||||
invisible="1"/>
|
||||
|
||||
<field name="sponsorship_id" invisible="1"
|
||||
attrs="{'readonly':[('state','not in',['draft','complete_info'])]}"/>
|
||||
|
||||
<field name="sponsorship_end_date" readonly="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="is_restricted" widget="boolean_toggle"/>
|
||||
<field name="general_restriction" widget="boolean_toggle"/>
|
||||
</group>
|
||||
|
||||
</page>
|
||||
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//header" position="inside">
|
||||
<button name="action_not_available_for_sponsorship" type="object"
|
||||
string="Not Available For Sponsorship" class="oe_highlight"
|
||||
attrs="{'invisible': [('general_restriction','=', True)]}"
|
||||
groups="odex_takaful.sponsorship_restrict_orphan_group"
|
||||
/>
|
||||
<button name="action_available_for_sponsorship" type="object"
|
||||
string="Available For Sponsorship" class="oe_highlight"
|
||||
attrs="{'invisible': [('general_restriction','!=', True)]}"
|
||||
groups="odex_takaful.sponsorship_restrict_orphan_group"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="family_member_search_inherit" model="ir.ui.view">
|
||||
<field name="name">family.member.search.inherit</field>
|
||||
<field name="model">family.member</field>
|
||||
<field name="inherit_id" ref="odex_benefit.family_member_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="benefit_id" position="after">
|
||||
<separator/>
|
||||
<filter name="have_kafala" string="Have Kafala"
|
||||
domain="[('kafala_status','=','have_kafala')]"/>
|
||||
<filter name="have_not_kafala" string="Have not Kafala"
|
||||
domain="[('kafala_status','=','have_not_kafala')]"/>
|
||||
<separator/>
|
||||
<filter name="orphan_benefit_type" string="Orphans"
|
||||
domain="[('relationn_type', 'in', ['son', 'daughter'])]"/>
|
||||
<filter name="widow_benefit_type" string="Widows"
|
||||
domain="[('relationn_type', 'in', ['mother', 'replacement_mother'])]"/>
|
||||
<separator/>
|
||||
<filter name="male_gender" string="Male"
|
||||
domain="[('relationn_type', '=', 'son')]"/>
|
||||
<filter name="female_gender" string="Female"
|
||||
domain="[('relationn_type', '!=', 'son')]"/>
|
||||
<separator/>
|
||||
<filter name="age_category_0_to_6" string="Age From 0 To 6"
|
||||
domain="[('age', '>=', 0), ('age', '<', 7)]"/>
|
||||
<filter name="age_category_7_to_10" string="Age From 7 To 10"
|
||||
domain="[('age', '>=', 7), ('age', '<', 11)]"/>
|
||||
<filter name="age_category_11_to_15" string="Age From 11 To 15"
|
||||
domain="[('age', '>=', 11), ('age', '<', 16)]"/>
|
||||
<filter name="age_category_16_to_18" string="Age From 16 To 18"
|
||||
domain="[('age', '>=', 16), ('age', '<', 19)]"/>
|
||||
<filter name="age_category_over_18" string="Age Over 18"
|
||||
domain="[('age', '>', 18)]"/>
|
||||
<separator/>
|
||||
<filter name="educated_educated_status" string="Educated"
|
||||
domain="[('education_status', '=', 'educated')]"/>
|
||||
<filter name="illiterate_educated_status" string="Illiterate"
|
||||
domain="[('education_status', '=', 'illiterate')]"/>
|
||||
<filter name="under_study_age_educated_status" string="Under Study Age"
|
||||
domain="[('education_status', '=', 'under_study_age')]"/>
|
||||
<separator/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_family_member_tree_inherit" model="ir.ui.view">
|
||||
<field name="name">family.member.tree.inherit</field>
|
||||
<field name="model">family.member</field>
|
||||
<field name="inherit_id" ref="odex_benefit.family_member_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='member_status']" position="after">
|
||||
<field name="kafala_status" widget="badge"
|
||||
decoration-success="kafala_status == 'have_kafala'"
|
||||
decoration-danger="kafala_status == 'have_not_kafala'"/>
|
||||
<field name="sponsorship_end_date" optional="hide" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="family_member_kanban_kafala_inherit" model="ir.ui.view">
|
||||
<field name="name">family.member.kanban.kafala.inherit</field>
|
||||
<field name="model">family.member</field>
|
||||
<field name="inherit_id" ref="odex_benefit.family_member_kanban"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<xpath expr="//field[@name='total_member_service_requests']" position="after">
|
||||
<field name="kafala_status"/>
|
||||
<field name="sponsorship_end_date"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[@t-attf-class]" position="attributes">
|
||||
<attribute name="t-attf-style">background: linear-gradient(135deg, #{record.member_status.raw_value == 'non_benefit' ? '#fff5f5' : '#ffffff'} 0%, #{record.member_status.raw_value == 'non_benefit' ? '#ffe0e0' : '#f8f9fa'} 100%); border: 2px solid #{record.member_status.raw_value == 'non_benefit' ? '#dc3545' : '#198754'}; border-radius: 15px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); transition: all 0.3s ease; margin-bottom: 15px; overflow: hidden; position: relative; min-height: 300px; opacity: #{record.member_status.raw_value == 'non_benefit' ? '0.85' : '1'};</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[@style='padding: 10px; background: white;']" position="after">
|
||||
<div style="background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); padding: 10px 5px; border-top: 2px solid #198754; text-align: right;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; font-size: 11px;">
|
||||
<div style="display: inline-flex; align-items: center;">
|
||||
<i class="fa fa-shield" style="color: #6c757d; margin-left: 4px;"/>
|
||||
<span style="font-weight: 600; color: #495057; margin-left: 4px;"></span>
|
||||
<span style="font-weight: 600;">
|
||||
<t t-if="record.kafala_status.raw_value == 'have_kafala'">
|
||||
<span style="background: linear-gradient(135deg, #e8f5e8 0%, #c8e6c9 100%); color: #2e7d32; padding: 2px 6px; border-radius: 8px; font-weight: 700; font-size: 10px; border: 1px solid #4caf50;">
|
||||
مكفول
|
||||
</span>
|
||||
</t>
|
||||
<t t-elif="record.kafala_status.raw_value == 'have_not_kafala'">
|
||||
<span style="background: linear-gradient(135deg, #fff8e1 0%, #ffecb3 100%); color: #e65100; padding: 2px 6px; border-radius: 8px; font-weight: 700; font-size: 10px; border: 1px solid #ff9800;">
|
||||
غير مكفول
|
||||
</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span style="color: #6c757d;">--</span>
|
||||
</t>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<t t-if="record.kafala_status.raw_value == 'have_kafala'">
|
||||
<div style="display: inline-flex; align-items: center;">
|
||||
<i class="fa fa-calendar" style="color: #6c757d; margin-left: 4px;"/>
|
||||
<span style="font-weight: 600; color: #495057; margin-left: 4px;">تنتهي الكفالة: </span>
|
||||
<span style="color: #212529; font-weight: 500;">
|
||||
<t t-if="record.sponsorship_end_date.raw_value">
|
||||
<field name="sponsorship_end_date"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span style="color: #6c757d;">--</span>
|
||||
</t>
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_payment_details_wizard_form" model="ir.ui.view">
|
||||
<field name="name">payment.details.wizard.form</field>
|
||||
<field name="model">payment.details.lines</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment Details">
|
||||
<group>
|
||||
<group>
|
||||
<field name="payment_method" invisible="1"/>
|
||||
<field name="payment_method_id" readonly="1"/>
|
||||
<field name="direct_debit_start_date" attrs="{'invisible': [('payment_method','!=','direct_debit')]}"/>
|
||||
<field name="name" attrs="{'invisible': [('payment_method','!=','card'),('payment_method','!=','debit_card')]}"/>
|
||||
<field name="check_number" attrs="{'invisible': [('payment_method','!=','check')]}"/>
|
||||
<field name="bank_id" attrs="{'invisible': ['|',('payment_method','=','cash'),('payment_method','=',False)]}"/>
|
||||
<field name="bank_name" attrs="{'invisible': ['|',('payment_method','!=','credit_card'),('payment_method','=',False)]}"/>
|
||||
<field name="bank_journal_id" attrs="{'invisible': ['|',('payment_method','!=','credit_card'),('payment_method','=',False)]}" />
|
||||
<field name="charity_bank_id" attrs="{'invisible': [('payment_method','!=','bank_transfer'),('payment_method','!=','direct_debit')]}"/>
|
||||
<label for="sponsor_account_number" attrs="{'invisible': [('payment_method','!=','bank_transfer'),('payment_method','!=','direct_debit')]}"/>
|
||||
<div class="o_row" attrs="{'invisible': [('payment_method','!=','bank_transfer'),('payment_method','!=','direct_debit')]}">
|
||||
<field name="sponsor_account_number" width="100%" />
|
||||
<field name="sa_iban"/>
|
||||
</div>
|
||||
<field name="journal_id"/>
|
||||
<field name="branch_custom_id" invisible="1"/>
|
||||
<field name="points_of_sale" attrs="{'invisible': [('payment_method','!=','card'),('payment_method','!=','credit_card')]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="payment_date"/>
|
||||
<field name="direct_debit_end_date" attrs="{'invisible': [('payment_method','!=','direct_debit')]}"/>
|
||||
<field name="donation_date"/>
|
||||
<field name="charity_journal_id" attrs="{'invisible': [('payment_method','!=','card'),('payment_method','!=','credit_card')]}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}" readonly="1" force_save="1"/>
|
||||
<field name="sponsorship_id" invisible="1" readonly="1" force_save="1"/>
|
||||
<field name="account_payment_method" attrs="{'invisible': [('payment_method','!=','card'),('payment_method','!=','credit_card')]}"/>
|
||||
<field name="note"/>
|
||||
<field name="payment_attachment" widget="many2many_attachment_preview" attrs="{'invisible': [('payment_method','!=','bank_transfer'),('payment_method','!=','direct_debit')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="action_confirm" type="object" string="Confirm" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<odoo>
|
||||
|
||||
<record id="view_preferred_communication_form" model="ir.ui.view">
|
||||
<field name="name">preferred.communication.form</field>
|
||||
<field name="model">preferred.communication</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Preferred Communication">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_preferred_communication_tree" model="ir.ui.view">
|
||||
<field name="name">preferred.communication.tree</field>
|
||||
<field name="model">preferred.communication</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Preferred Communication">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_preferred_communication" model="ir.actions.act_window">
|
||||
<field name="name">Preferred Communication</field>
|
||||
<field name="res_model">preferred.communication</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_preferred_communication"
|
||||
name="Preferred Communication"
|
||||
parent="odex_takaful.sponsor_setting_menu"
|
||||
action="action_preferred_communication"/>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
<odoo>
|
||||
<record id="product_template_view_kanban_odex_takaful" model="ir.ui.view">
|
||||
<field name="name">product.template.view.kanban.odex.takaful</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban edit="0" create="0" class="o_kanban_mobile o_cart_kanban o_cart_kanban_donation">
|
||||
<field name="id" />
|
||||
<field name="name" />
|
||||
<field name="_quantity" />
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="o_product_quantity d-flex flex-column justify-content-between"
|
||||
style="min-height: 100px;width: 25%;">
|
||||
<div class="o_kanban_image" style="display: flex;width: 100%;justify-content: space-between;align-items: center;">
|
||||
<img t-att-src="kanban_image('product.template', 'image_128', record.id.raw_value)"
|
||||
alt="Product" class="o_image_64_contain" style="width: 100%;object-fit: cover;height: 100px;"/>
|
||||
</div>
|
||||
<h5 style="margin-top: 5px;text-align: center;">
|
||||
<span>Amount:</span>
|
||||
<field name="lst_price" widget="monetary"/>
|
||||
<svg id="Layer_1" data-name="Layer 1" viewBox="0 0 1124.14 1256.39" style="height: 11px"><defs><style>.cls-1 {fill: #231f20;}</style></defs><path class="cls-1" d="M699.62,1113.02h0c-20.06,44.48-33.32,92.75-38.4,143.37l424.51-90.24c20.06-44.47,33.31-92.75,38.4-143.37l-424.51,90.24Z"/><path class="cls-1" d="M1085.73,895.8c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.33v-135.2l292.27-62.11c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.27V66.13c-50.67,28.45-95.67,66.32-132.25,110.99v403.35l-132.25,28.11V0c-50.67,28.44-95.67,66.32-132.25,110.99v525.69l-295.91,62.88c-20.06,44.47-33.33,92.75-38.42,143.37l334.33-71.05v170.26l-358.3,76.14c-20.06,44.47-33.32,92.75-38.4,143.37l375.04-79.7c30.53-6.35,56.77-24.4,73.83-49.24l68.78-101.97v-.02c7.14-10.55,11.3-23.27,11.3-36.97v-149.98l132.25-28.11v270.4l424.53-90.28Z"/></svg>
|
||||
</h5>
|
||||
<div class="oe_kanban_details p-2 d-flex">
|
||||
<div class="o_kanban_record_top flex-column w-100 "
|
||||
style="justify-content: space-between;">
|
||||
<div class="o_kanban_record_title w-100" style="text-align: center;">
|
||||
<strong>
|
||||
<field name="name" />
|
||||
</strong>
|
||||
</div>
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<!-- <ul>
|
||||
<li>
|
||||
<strong> Amount: <field name="lst_price"
|
||||
widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}" />
|
||||
</strong>
|
||||
</li> -->
|
||||
|
||||
<!-- <field name="currency_id" invisible="1"/> -->
|
||||
<!-- <div> -->
|
||||
<!-- <span>On Hand:</span> -->
|
||||
<!-- <field name="qty_available"/> -->
|
||||
<!-- <field name="uom_id" class="ms-1" -->
|
||||
<!-- groups="uom.group_uom"/> -->
|
||||
<!-- </div> -->
|
||||
<!-- </ul> -->
|
||||
</div>
|
||||
|
||||
<div class="d-flex w-100 justify-content-center align-items-center mt-4">
|
||||
|
||||
<button class="btn btn-secondary" type="button"
|
||||
name="add_quantity_button_so"
|
||||
data-name="add_quantity_button_request"
|
||||
title="إضافة منتج"
|
||||
onclick="return window.__dc_first_add(this);">
|
||||
<i class="fa fa-shopping-cart" />
|
||||
<span>Add</span>
|
||||
</button>
|
||||
|
||||
<div class="dc-qty-controls d-none">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="button"
|
||||
name="remove_quantity_button_so"
|
||||
data-name="remove_quantity_button_so"
|
||||
title="تقليل الكمية"
|
||||
onclick="return window.__dc_remove(this);">
|
||||
<i class="fa fa-minus" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="form-control dc-qty-badge" style="min-width: 40px;text-align: center;">
|
||||
<field name="_quantity" />
|
||||
</div>
|
||||
<div class="input-group-prepend">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="button"
|
||||
name="add_quantity_button_so"
|
||||
data-name="add_quantity_button_so"
|
||||
title="إضافة"
|
||||
onclick="return window.__dc_add(this);">
|
||||
<i class="fa fa-plus" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Tree view for product.template with sponsorship button -->
|
||||
<record id="view_product_template_tree_sponsorship" model="ir.ui.view">
|
||||
<field name="name">product.template.tree.sponsorship</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Products">
|
||||
<header>
|
||||
<button name="link_to_sponsorship" type="object" string="Link to Sponsorship"
|
||||
class="btn-primary"
|
||||
icon="fa-link" />
|
||||
</header>
|
||||
<field name="name" />
|
||||
<field name="donation_category" />
|
||||
<field name="list_price" string="Price" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="odex_takaful_product_template_form_view" model="ir.ui.view">
|
||||
<field name="name">odex.takaful.product.template.form.view</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_form_view" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="uom_id" position="before">
|
||||
<field name="payment_method_id" options="{'no_create': True}" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<odoo>
|
||||
<!-- Tree View -->
|
||||
<record id="view_replacement_process_tree" model="ir.ui.view">
|
||||
<field name="name">replacement.process.tree</field>
|
||||
<field name="model">replacement.process</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Replacement Process" create="false" edit="true">
|
||||
<field name="code"/>
|
||||
<field name="sponsorship_id"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="branch_id"/>
|
||||
<field name="record_type"/>
|
||||
<field name="sponsor_donor_type"/>
|
||||
<field name="replacement_reason_id"/>
|
||||
<field name="state"/>
|
||||
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Form View -->
|
||||
<record id="view_replacement_process_form" model="ir.ui.view">
|
||||
<field name="name">replacement.process.form</field>
|
||||
<field name="model">replacement.process</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Replacement Process" create="false" edit="true">
|
||||
<header>
|
||||
<button name="confirm_replacement" type="object" string="Confirm Replacement"
|
||||
class="btn-primary" attrs="{'invisible': [('replaced', '=', True)]}" groups="odex_takaful.group_orphan_replacement"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,replaced"/>
|
||||
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
|
||||
<group>
|
||||
<field name="code" readonly="1"/>
|
||||
<field name="branch_id" readonly="1"/>
|
||||
<field name="registered_type" readonly="1"/>
|
||||
<field name="record_type"/>
|
||||
<field name="replaced" invisible="1"/>
|
||||
<field name="family_ids" invisible="1"/>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<field name="sponsorship_id" readonly="1"/>
|
||||
<field name="user_id" readonly="1"/>
|
||||
<field name="sponsor_donor_type" readonly="1"/>
|
||||
<field name="sponsor_id" readonly="1"/>
|
||||
<field name="replacement_reason_id" readonly="1"/>
|
||||
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<field name="replacement_line_ids" attrs="{'readonly': [('replaced','=',True)]}">
|
||||
<tree editable="bottom">
|
||||
<field name="members_domain_ids" invisible="1"/>
|
||||
<field name="sponsorship_type" readonly="1"/>
|
||||
<field name="from_benefit_id" readonly="1"/>
|
||||
<field name="to_benefit_id" attrs="{'readonly': [('sponsorship_type','!=','person')]}"/>
|
||||
<field name="from_benefit_ids" readonly="1" widget="many2many_tags"/>
|
||||
<field name="to_benefit_ids" widget="many2many_tags" attrs="{'readonly': [('sponsorship_type','!=','group')]}"/>
|
||||
<field name="process_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
</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>
|
||||
|
||||
<!-- Action -->
|
||||
<record id="action_replacement_process" model="ir.actions.act_window">
|
||||
<field name="name">Replacement Processes</field>
|
||||
<field name="res_model">replacement.process</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create your first Replacement Process
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Menu Item -->
|
||||
<menuitem id="menu_replacement_root" name="Kafala Processes" sequence="11"
|
||||
parent="odex_takaful.takaful_kufula_app_top_menu" groups="odex_takaful.group_orphan_replacement"/>
|
||||
|
||||
<!-- <menuitem id="menu_replacement_process"-->
|
||||
<!-- name="Orphan Replacement"-->
|
||||
<!-- parent="menu_replacement_root"-->
|
||||
<!-- action="action_replacement_process"-->
|
||||
<!-- sequence="1"/>-->
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<!-- Tree View -->
|
||||
<record id="view_replacement_reasons_tree" model="ir.ui.view">
|
||||
<field name="name">replacement.reasons.tree</field>
|
||||
<field name="model">replacement.reasons</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Replacement Reasons">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Form View -->
|
||||
<record id="view_replacement_reasons_form" model="ir.ui.view">
|
||||
<field name="name">replacement.reasons.form</field>
|
||||
<field name="model">replacement.reasons</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Replacement Reasons">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Action -->
|
||||
<record id="action_replacement_reasons" model="ir.actions.act_window">
|
||||
<field name="name">Replacement Reasons</field>
|
||||
<field name="res_model">replacement.reasons</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<!-- Menu -->
|
||||
<menuitem id="menu_replacement_reasons" name="Replacement Reasons" parent="odex_takaful.takaful_app_top_menu" action="action_replacement_reasons" groups="odex_takaful.group_orphan_replacement"/>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<report
|
||||
id ="makfuleen_report_pdf_act"
|
||||
model ="report.odex_takaful.makfuleen_report_pdf"
|
||||
string ="Makfuleen Report"
|
||||
report_type ="qweb-pdf"
|
||||
name ="odex_takaful.makfuleen_report_pdf"
|
||||
file ="odex_takaful.makfuleen_report_pdf"
|
||||
menu="False" />
|
||||
|
||||
<!-- paperformat="odex_takaful.takaful_report_paperformat_id" -->
|
||||
|
||||
<report
|
||||
id ="kafalat_payment_report_pdf_act"
|
||||
model ="report.odex_takaful.kafalat_payment_report_pdf"
|
||||
string ="Kafalat Payment Report"
|
||||
report_type ="qweb-pdf"
|
||||
name ="odex_takaful.kafalat_payment_report_pdf"
|
||||
file ="odex_takaful.kafalat_payment_report_pdf"
|
||||
menu="False" />
|
||||
|
||||
|
||||
<report
|
||||
id ="kafalat_cancel_report_pdf_act"
|
||||
model ="report.odex_takaful.kafalat_cancel_report_pdf"
|
||||
string ="Canceled Kafalat Report"
|
||||
report_type ="qweb-pdf"
|
||||
name ="odex_takaful.kafalat_cancel_report_pdf"
|
||||
file ="odex_takaful.kafalat_cancel_report_pdf"
|
||||
menu="False" />
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<!-- Create PaperFormat -->
|
||||
<record id="takaful_report_paperformat_id" model="report.paperformat">
|
||||
<field name="name">Takaful Paper Format</field>
|
||||
<field name="default" eval="True" />
|
||||
<field name="format">A4</field>
|
||||
<field name="page_height">0</field>
|
||||
<field name="page_width">0</field>
|
||||
<field name="orientation">Portrait</field>
|
||||
<field name="margin_top">50</field>
|
||||
<field name="margin_bottom">40</field>
|
||||
<field name="margin_left">7</field>
|
||||
<field name="margin_right">7</field>
|
||||
<field name="header_line" eval="False" />
|
||||
<field name="header_spacing">50</field>
|
||||
<field name="dpi">110</field>
|
||||
</record>
|
||||
|
||||
<!-- set paper format to any report action -->
|
||||
<!-- <record id="odex_takaful.action_report_beneficiary_sponsorships_number" model="ir.actions.report.xml">
|
||||
<field name="paperformat_id" ref="odex_takaful.takaful_report_paperformat_id" />
|
||||
</record> -->
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Makfuleen Report -->
|
||||
<template id="makfuleen_report_pdf">
|
||||
<t t-call="web.html_container">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<div class="text-center">
|
||||
<h2><span> Sponsor Name: </span><span t-esc='name'/></h2>
|
||||
<h2>Makfuleen Report</h2>
|
||||
</div>
|
||||
|
||||
<table class="table table-condensed table-bordered">
|
||||
<thead class="text-center">
|
||||
<tr style="background-color: #b8bcbf;width:100%;">
|
||||
<th style="text-align:center;">#</th>
|
||||
<th style="text-align:center;">Sponsorship</th>
|
||||
<th style="text-align:center;">Start Date</th>
|
||||
<th style="text-align:center;">End Date</th>
|
||||
<th style="text-align:center;">Sponsorship Type</th>
|
||||
<th style="text-align:center;">Sponsorship Value</th>
|
||||
<th style="text-align:center;">Sponsorship State</th>
|
||||
<th style="text-align:center;">Makfool Name/Makfuleen Names</th>
|
||||
<th style="text-align:center;">Total Payment</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-center">
|
||||
<t t-set="sequence" t-value="0"/>
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-set="sequence" t-value="sequence +1"/>
|
||||
<t t-esc="sequence"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.code"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.start_date"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.end_date"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['sponsorship_type'])['sponsorship_type']['selection'])[o.sponsorship_type]"/>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.contribution_value"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['state'])['state']['selection'])[o.state]"/>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<t t-if="o.sponsorship_type == 'person'">
|
||||
<span t-esc="o.benefit_id.name"/>
|
||||
</t>
|
||||
<t t-if="o.sponsorship_type == 'group'">
|
||||
<p t-foreach="o.benefit_ids" t-as="ben">
|
||||
<p><span t-esc="ben.name"/></p>
|
||||
</p>
|
||||
</t>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.total_contribution"/>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div style="page-break-before: always;"></div>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Kafalat Payments and Delays report -->
|
||||
<template id="kafalat_payment_report_pdf">
|
||||
<t t-call="web.html_container">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<div class="text-center">
|
||||
<h2><span> Sponsor Name: </span><span t-esc='name'/></h2>
|
||||
<h2>Kafalat Overdue Report</h2>
|
||||
</div>
|
||||
|
||||
<table class="table table-condensed table-bordered">
|
||||
<thead class="text-center">
|
||||
<tr style="background-color: #b8bcbf;width:100%;">
|
||||
<th style="text-align:center;">Kafalat Overdue Count</th>
|
||||
<th style="text-align:center;">Total Overdues</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-center">
|
||||
<t>
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<span t-esc='overdue_count'/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc='overdue_amount' t-options='{"widget": "float", "precision": 2}' />
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<!-- Overdue details -->
|
||||
<table class="table table-condensed table-bordered">
|
||||
<thead class="text-center">
|
||||
<tr style="background-color: #b8bcbf;width:100%;">
|
||||
<th style="text-align:center;">#</th>
|
||||
<th style="text-align:center;">Sponsorship</th>
|
||||
<th style="text-align:center;">Contribution Value</th>
|
||||
<th style="text-align:center;">Sponsorship Duration</th>
|
||||
<th style="text-align:center;">Sponsorship Type</th>
|
||||
<th style="text-align:center;">Benefit Type</th>
|
||||
<th style="text-align:center;">Start Date</th>
|
||||
<th style="text-align:center;">End Date</th>
|
||||
<th style="text-align:center;">Overdue Amount</th>
|
||||
<th style="text-align:center;">Expected Cancel Date</th>
|
||||
<th style="text-align:center;">Status</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-center">
|
||||
<t t-set="sequence" t-value="0"/>
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-set="sequence" t-value="sequence +1"/>
|
||||
<t t-esc="sequence"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.code"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.contribution_value" t-options='{"widget": "float", "precision": 2}' />
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['sponsorship_duration'])['sponsorship_duration']['selection'])[o.sponsorship_duration]"/>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['sponsorship_type'])['sponsorship_type']['selection'])[o.sponsorship_type]"/>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['benefit_type'])['benefit_type']['selection'])[o.benefit_type]"/>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.start_date"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.end_date"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.overdue_amount"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.expected_cancel_date"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['state'])['state']['selection'])[o.state]"/>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="page-break-before: always;"></div>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Canceled Kafalat Report -->
|
||||
<template id="kafalat_cancel_report_pdf">
|
||||
<t t-call="web.html_container">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<div class="text-center">
|
||||
<h2>Canceled Kafalat Report </h2>
|
||||
</div>
|
||||
|
||||
<table class="table table-condensed table-bordered">
|
||||
<thead class="text-center">
|
||||
<tr style="background-color: #b8bcbf;width:100%;">
|
||||
<th style="text-align:center;">Canceled Kafalat Count</th>
|
||||
<th style="text-align:center;">From Date</th>
|
||||
<th style="text-align:center;">To Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-center">
|
||||
<t>
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<span t-esc='cancel_count'/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc='start_date'/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc='end_date'/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<!-- Cancel details -->
|
||||
<table class="table table-condensed table-bordered">
|
||||
<thead class="text-center">
|
||||
<tr style="background-color: #b8bcbf;width:100%;">
|
||||
<th style="text-align:center;">#</th>
|
||||
<th style="text-align:center;">Sponsorship</th>
|
||||
<th style="text-align:center;">The Sponsor</th>
|
||||
<th style="text-align:center;">Cancel Date</th>
|
||||
<th style="text-align:center;">Cancel Type</th>
|
||||
<th style="text-align:center;">Cancel Reason</th>
|
||||
<th style="text-align:center;">Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-center">
|
||||
<t t-set="sequence" t-value="0"/>
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-set="sequence" t-value="sequence +1"/>
|
||||
<t t-esc="sequence"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.code"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="o.sponsor_id.name"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.confirm_date"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span>
|
||||
<t t-esc="dict(o.fields_get(allfields=['cancel_type'])['cancel_type']['selection'])[o.cancel_type]"/>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.reason_id.name"/>
|
||||
</td>
|
||||
|
||||
<td class="text-center">
|
||||
<span t-esc="o.note"/>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="page-break-before: always;"></div>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This added for Takaful settings -->
|
||||
<odoo>
|
||||
<record id="takaful_settings_view2" model="ir.ui.view">
|
||||
<field name="name">takaful.res.config.settings.view.form</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@data-key='odex_takaful_base']">
|
||||
|
||||
<h2>Sponsorship Restriction Period</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<div class="content-group mt16">
|
||||
<label for="restriction_period"/>
|
||||
<field name="restriction_period" class="text-center oe_inline"
|
||||
style="margin-right:50px;"/>
|
||||
<span class="text-muted">Day</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Faal Kheer Partner</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="faal_kheer_partner_id"/>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="faal_kheer_partner_id" class="o_light_label"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Whatsapp API Integration</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="twilio_account_sid"/>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="twilio_account_sid" class="o_light_label"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="twilio_auth_token"/>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="twilio_auth_token" class="o_light_label" password="True"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="twilio_from_whatsapp"/>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="twilio_from_whatsapp" class="o_light_label"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h2>Refund Cancel Time</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="cancel_refund"/>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="cancel_refund" class="o_light_label"/>
|
||||
<span class="text-muted">Hours</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>SMS Templates</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="donation_extension_reminder_sms_template_id"/>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="donation_extension_reminder_sms_template_id" class="o_light_label"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="donation_ended_sms_template_id"/>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="donation_ended_sms_template_id" class="o_light_label"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</xpath>
|
||||
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- <record id="odex_takaful_takaful_settings_view2" model="ir.ui.view">-->
|
||||
<!-- <field name="name">odex.takaful.takaful.res.config.settings.view.form</field>-->
|
||||
<!-- <field name="model">res.config.settings</field>-->
|
||||
<!-- <field name="inherit_id" ref="odex_takaful_base.takaful_settings_view2"/>-->
|
||||
<!-- <field name="arch" type="xml">-->
|
||||
<!-- <xpath expr="//div[hasclass('col-md-12')][1]" position="inside">-->
|
||||
<!-- <div class="content-group mt16">-->
|
||||
<!-- <label for="restriction_period"/>-->
|
||||
<!-- <field name="restriction_period" class="text-center oe_inline" style="margin-right:50px;"/>-->
|
||||
<!-- <span class="text-muted">Day</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- </xpath>-->
|
||||
<!-- </field>-->
|
||||
<!-- </record>-->
|
||||
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="res_partner_bank_view_form_quick_create" model="ir.ui.view">
|
||||
<field name="name">res.partner.bank.view.form.quick.create</field>
|
||||
<field name="model">res.partner.bank</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="acc_number"/>
|
||||
<field name="acc_holder_name"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="bank_id"/>
|
||||
<field name="partner_id" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<odoo>
|
||||
|
||||
<record id="res_users_inherit_EXP" model="ir.ui.view">
|
||||
<field name="name">res_users_inherit_EXP</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="inherit_id" ref="branch.view_users_form_inherit_branch"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<xpath expr="//group[2]" position="after">
|
||||
<!-- Add your fields or attributes here -->
|
||||
|
||||
<group>
|
||||
<field name="branch_custom_id"/>
|
||||
</group>
|
||||
|
||||
</xpath>
|
||||
|
||||
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<odoo>
|
||||
<data>
|
||||
<record id="sponsorship_close_reason_tree" model="ir.ui.view">
|
||||
<field name="name">Sponsorship Reason Tree</field>
|
||||
<field name="model">sponsorship.reason.stop</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name" colspan="3"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_config_sponsorship_stop" model="ir.actions.act_window">
|
||||
<field name="name">Sponsorship Reason</field>
|
||||
<field name="res_model">sponsorship.reason.stop</field>
|
||||
<field name="view_mode">tree</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="sponsorship_cancellation_form">
|
||||
<field name="name">sponsorship.cancellation.form</field>
|
||||
<field name="model">sponsorship.cancellation</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sponsorship Cancellation" delete="false">
|
||||
<header>
|
||||
|
||||
<button name="do_cancel_action" type="object" string="Cancel" class="oe_highlight" attrs="{'invisible': [('state', '=', 'cancel')]}"/>
|
||||
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="sponsorship_id" invisible="1"/>
|
||||
<field name="code" readonly="1"/>
|
||||
<field name="sponsor_id" readonly="1"/>
|
||||
<field name="reason_id" required="1"/>
|
||||
|
||||
<field name="create_date" readonly="1"/>
|
||||
<field name="cancel_type"/>
|
||||
<field name="note"/>
|
||||
|
||||
<field name="cancel_user_id"/>
|
||||
<field name="confirm_user_id" attrs="{'invisible': [('state', '!=', 'cancel')]}"/>
|
||||
<field name="confirm_date" attrs="{'invisible': [('state', '!=', 'cancel')]}"/>
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="sponsorship_cancellation_tree">
|
||||
<field name="name">sponsorship.cancellation.tree</field>
|
||||
<field name="model">sponsorship.cancellation</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sponsorships Cancellations List" decoration-warning="state=='draft'" decoration-danger="state=='cancel'">
|
||||
<field name="sponsor_id"/>
|
||||
<field name="code"/>
|
||||
<field name="reason_id"/>
|
||||
<field name="cancel_type"/>
|
||||
<field name="note"/>
|
||||
<field name="state"/>
|
||||
<field name="confirm_date"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="sponsorship_cancellation_search">
|
||||
<field name="name">sponsorship.cancellation.search</field>
|
||||
<field name="model">sponsorship.cancellation</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="code"/>
|
||||
<field name="reason_id"/>
|
||||
<field name="cancel_type"/>
|
||||
<field name="state"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="sponsorship_cancellation_action">
|
||||
<field name="name">Sponsorship Cancellation</field>
|
||||
<field name="res_model">sponsorship.cancellation</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">Create the Sponsorship Cancellation
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<odoo>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="takaful_sponsorship_payment_form">
|
||||
<field name="name">sponsorship.payment.form</field>
|
||||
<field name="model">sponsorship.payment</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sponsorship Payment" delete="false">
|
||||
<header>
|
||||
<button name="action_pay" class="oe_highlight" type="object" string="Send to Finance" attrs="{'invisible': ['|', ('state', 'in', ('financial', 'paid')), ('id', '=', False)]}"/>
|
||||
|
||||
<button name="open_account_invoice_action" string="Financial" type="object" class="oe_highlight" attrs="{'invisible': [('state', '=', 'draft')]}"/>
|
||||
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group name="group_top">
|
||||
<group name="group_left">
|
||||
<field name="code" readonly="1"/>
|
||||
<field name="sponsor_id" force_save="1" attrs="{'readonly': [('id', '>', 0)]}"/>
|
||||
|
||||
<field name="sponsorship_id" force_save="1" attrs="{'readonly': [('id', '>', 0)]}"/>
|
||||
|
||||
<label for="payment_month_number" />
|
||||
<div>
|
||||
|
||||
<field name="payment_month_number" required="1" class="oe_inline" style="margin-right:50px; margin-bottom:20px;"/>
|
||||
<span class="oe_inline text-muted"> Months</span>
|
||||
|
||||
</div>
|
||||
|
||||
<field name="payment_method" style="margin-bottom:20px;"/>
|
||||
|
||||
<field name="has_bank_account" attrs="{'invisible': [('payment_method', '=', 'cash')]}" style="margin-bottom:10px;"/>
|
||||
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="month_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}" force_save="1"/>
|
||||
<field name="amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}" readonly="1"/>
|
||||
</group>
|
||||
|
||||
<group name="group_right" attrs="{'invisible': [('payment_method', '=', 'cash')]}">
|
||||
<field name="bank_id"/>
|
||||
<field name="iban"/>
|
||||
<field name="transfer_receipt"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<field name="user_id" attrs="{'invisible': [('state', '=', 'draft')]}"/>
|
||||
<field name="date" attrs="{'invisible': [('state', '=', 'draft')]}"/>
|
||||
<field name="is_invoiced" invisible="1"/>
|
||||
</group>
|
||||
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="takaful_sponsorship_payment_tree">
|
||||
<field name="name">sponsorship.payment.tree</field>
|
||||
<field name="model">sponsorship.payment</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Payments List" decoration-danger="state=='financial'" decoration-success="state=='paid'">
|
||||
<field name="sponsor_id"/>
|
||||
<field name="code"/>
|
||||
<field name="amount" sum="Total Payments" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="date" widget="date"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="takaful_sponsorship_payment_search">
|
||||
<field name="name">sponsorship.payment.search</field>
|
||||
<field name="model">sponsorship.payment</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="code"/>
|
||||
<field name="date"/>
|
||||
<field name="state"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="takaful_sponsorship_payment_action">
|
||||
<field name="name">Sponsorship Payment</field>
|
||||
<field name="res_model">sponsorship.payment</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">Create the Sponsorship Payment
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Tree View for Sponsorship Scheduling Line -->
|
||||
<record id="view_sponsorship_scheduling_line_tree" model="ir.ui.view">
|
||||
<field name="name">sponsorship.scheduling.line.tree</field>
|
||||
<field name="model">sponsorship.scheduling.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sponsorship Scheduling Lines" decoration-success="status == 'paid'"
|
||||
decoration-info="status == 'unpaid'" decoration-danger="status == 'fully_refund'"
|
||||
decoration-warning="status in ('approve_refund', 'under_refund', 'partial_refund')">
|
||||
<field name="sequence_no"/>
|
||||
<field name="sponsorship_id"/>
|
||||
<field name="sponsorship_state"/>
|
||||
<field name="donation_detail_linked_id"/>
|
||||
<field name="beneficiary_id"/>
|
||||
<field name="month_year"/>
|
||||
<field name="scheduled_date"/>
|
||||
<field name="amount" sum="Total Amount"/>
|
||||
<field name="refunded_amount" sum="Total Refunded"/>
|
||||
<field name="direct_debit"/>
|
||||
<field name="status"/>
|
||||
<button name="action_register_payment"
|
||||
string="Register Payment"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
attrs="{'invisible': ['|', ('status', '!=', 'unpaid'), ('direct_debit', '=', True)]}" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Search View for Sponsorship Scheduling Line -->
|
||||
<record id="view_sponsorship_scheduling_line_search" model="ir.ui.view">
|
||||
<field name="name">sponsorship.scheduling.line.search</field>
|
||||
<field name="model">sponsorship.scheduling.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Sponsorship Scheduling Lines">
|
||||
<field name="sequence_no"/>
|
||||
<field name="sponsorship_id"/>
|
||||
<field name="beneficiary_id"/>
|
||||
<field name="month_year"/>
|
||||
<field name="scheduled_date"/>
|
||||
<field name="donation_detail_linked_id"/>
|
||||
<separator/>
|
||||
<filter string="Scheduled Today" name="scheduled_today" domain="[('scheduled_date', '=', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter string="Scheduled This Week" name="scheduled_this_week" domain="[('scheduled_date', '>=', (context_today() - datetime.timedelta(days=context_today().weekday())).strftime('%Y-%m-%d')), ('scheduled_date', '<=', (context_today() + datetime.timedelta(days=6-context_today().weekday())).strftime('%Y-%m-%d'))]"/>
|
||||
<separator/>
|
||||
<filter string="Unpaid" name="unpaid" domain="[('status', '=', 'unpaid')]"/>
|
||||
<filter string="Paid" name="paid" domain="[('status', '=', 'paid')]"/>
|
||||
<filter string="Approve Refund" name="approve_refund" domain="[('status', '=', 'approve_refund')]"/>
|
||||
<filter string="Under Refund" name="under_refund" domain="[('status', '=', 'under_refund')]"/>
|
||||
<filter string="Partial Refund" name="partial_refund" domain="[('status', '=', 'partial_refund')]"/>
|
||||
<filter string="Fully Refund" name="fully_refund" domain="[('status', '=', 'fully_refund')]"/>
|
||||
<separator/>
|
||||
<filter string="Direct Debit" name="direct_debit" domain="[('direct_debit', '=', True)]"/>
|
||||
<separator/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Sponsorship" name="group_sponsorship" context="{'group_by': 'sponsorship_id'}"/>
|
||||
<filter string="Beneficiary" name="group_beneficiary" context="{'group_by': 'beneficiary_id'}"/>
|
||||
<filter string="Status" name="group_status" context="{'group_by': 'status'}"/>
|
||||
<filter string="Direct Debit" name="group_direct_debit" context="{'group_by': 'direct_debit'}"/>
|
||||
<filter string="Month/Year" name="group_month_year" context="{'group_by': 'month_year'}"/>
|
||||
<filter string="Scheduled Date" name="group_scheduled_date" context="{'group_by': 'scheduled_date'}"/>
|
||||
<filter string="Sponsorship State" name="group_sponsorship_state" context="{'group_by': 'sponsorship_state'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Action for Sponsorship Scheduling Line -->
|
||||
<record id="action_sponsorship_scheduling_line" model="ir.actions.act_window">
|
||||
<field name="name">Sponsorship Scheduling Lines</field>
|
||||
<field name="res_model">sponsorship.scheduling.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="search_view_id" ref="view_sponsorship_scheduling_line_search"/>
|
||||
<field name="context">{'create': False}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new Sponsorship Scheduling Line
|
||||
</p>
|
||||
<p>
|
||||
Track and manage sponsorship payment schedules for beneficiaries.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<odoo>
|
||||
<record model="ir.ui.view" id="sponsorship_states_form">
|
||||
<field name="name">sponsorship.states.form</field>
|
||||
<field name="model">sponsorship.states</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sponsorship States">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="sponsorship_states_tree" model="ir.ui.view">
|
||||
<field name="name">sponsorship.states.tree</field>
|
||||
<field name="model">sponsorship.states</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sponsorship States">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="sponsorship_states_action" model="ir.actions.act_window">
|
||||
<field name="name">Sponsorship States</field>
|
||||
<field name="res_model">sponsorship.states</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a Sponsorship States
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_sponsorship_states_items" name="Sponsorship States"
|
||||
parent="sponsor_setting_menu"
|
||||
action="sponsorship_states_action"/>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
<odoo>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="donations_items_form">
|
||||
<field name="name">donations.items.form</field>
|
||||
<field name="model">donations.items</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Donations Items">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name" required="1"/>
|
||||
<field name="donation_type" required="1"/>
|
||||
<field name="fixed_value"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="fixed_donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'invisible': [('fixed_value', '=', False)],'required': [('fixed_value', '=', True)]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="branch_custom_id" required="1"/>
|
||||
<field name="show_donation_item"/>
|
||||
<field name="account_id" required="1"/>
|
||||
<field name="product_id" readonly="1" groups="odex_takaful.group_show_donation_item_product"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="donations_items_tree" model="ir.ui.view">
|
||||
<field name="name">donations.items.tree</field>
|
||||
<field name="model">donations.items</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Donations Items">
|
||||
<field name="name"/>
|
||||
<field name="donation_type"/>
|
||||
<field name="branch_custom_id"/>
|
||||
<field name="show_donation_item"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="donations_items_action" model="ir.actions.act_window">
|
||||
<field name="name">Donations Items</field>
|
||||
<field name="res_model">donations.items</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a Donation Item
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<!-- Points Of sale custom -->
|
||||
<record model="ir.ui.view" id="points_of_sale_custom_form">
|
||||
<field name="name">points.of.sale.custom.form</field>
|
||||
<field name="model">points.of.sale.custom</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Points of sale custom">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="department_name"/>
|
||||
<field name="branch_custom_ids" widget="many2many_tags"/>
|
||||
<field name="journal_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="points_of_sale_custom_tree" model="ir.ui.view">
|
||||
<field name="name">points.of.sale.custom.tree</field>
|
||||
<field name="model">points.of.sale.custom</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Points of sale custom">
|
||||
<field name="name"/>
|
||||
<field name="department_name"/>
|
||||
<field name="branch_custom_ids" widget="many2many_tags"/>
|
||||
<field name="department_name"/>
|
||||
<field name="journal_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="points_of_sale_custom_action" model="ir.actions.act_window">
|
||||
<field name="name">Points Of Sale Custom</field>
|
||||
<field name="res_model">points.of.sale.custom</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a points of sale
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_donations_items" name="Donations Items"
|
||||
parent="sponsor_setting_menu"
|
||||
action="donations_items_action" />
|
||||
|
||||
<menuitem id="menu_points_of_sale_custom" name="Points of Sale"
|
||||
parent="sponsor_setting_menu"
|
||||
action="points_of_sale_custom_action" />
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<odoo>
|
||||
<data noupdate="0">
|
||||
<record id="financial_gift" model="product.product">
|
||||
<field name="name">هدية مالية</field>
|
||||
<field name="type">service</field>
|
||||
<!-- <field name="standard_price">0</field> -->
|
||||
<field name="list_price">300.0</field>
|
||||
<field name="default_code">financial_gift</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<data>
|
||||
|
||||
<!-- Form View -->
|
||||
<record model="ir.ui.view" id="takaful_contribution_form">
|
||||
<field name="name">takaful.contribution.form</field>
|
||||
<field name="model">takaful.contribution</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="The Financial Contribution" duplicate="false">
|
||||
<header>
|
||||
<!-- <button name="action_confirm_gift" type="object"-->
|
||||
<!-- string="Confirm Gift" class="oe_highlight"-->
|
||||
<!-- attrs="{'invisible': [('operation_type','!=','gift'),('is_confirmed','=', False)]}"/>-->
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="is_confirmed" invisible='1'/>
|
||||
<field name="name"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="benefit_id" attrs="{'invisible': [('benefit_ids','=', False)]}"/>
|
||||
<field name="benefit_ids" attrs="{'invisible': [('benefit_id','!=', False)]}"/>
|
||||
<field name="operation_type"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="note"/>
|
||||
<field name="date"/>
|
||||
<field name="entry_id" invisible='1'/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Tree View -->
|
||||
<record model="ir.ui.view" id="takaful_contribution_tree">
|
||||
<field name="name">takaful.contribution.tree</field>
|
||||
<field name="model">takaful.contribution</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Financial Contributions List" duplicate="false">
|
||||
<field name="name"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="operation_type"/>
|
||||
<field name="amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="date" widget="datetime"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Search View -->
|
||||
<record model="ir.ui.view" id="takaful_contribution_search">
|
||||
<field name="name">takaful.contribution.search</field>
|
||||
<field name="model">takaful.contribution</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="operation_type"/>
|
||||
<field name="amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="date" widget="datetime"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Windows Action -->
|
||||
<record model="ir.actions.act_window" id="takaful_financial_contribution_action">
|
||||
<field name="name">Financial Contributions</field>
|
||||
<field name="res_model">takaful.contribution</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">No Any Financial Contribution!
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<odoo>
|
||||
|
||||
<!-- <record id="benefit_invoice_form_inherit_view" model="ir.ui.view">-->
|
||||
<!-- <field name="name">benefit.invoice.form.inherit.view</field>-->
|
||||
<!-- <field name="model">account.move</field>-->
|
||||
<!-- <field name="inherit_id" ref="account.view_move_form" />-->
|
||||
<!-- <field name="arch" type="xml">-->
|
||||
<!-- <xpath expr="/form/sheet/notebook/page[2]/field[@name='line_ids']" position="after">-->
|
||||
<!-- <field name="benefit_invoice_ids" />-->
|
||||
<!-- </xpath>-->
|
||||
<!-- </field>-->
|
||||
<!-- </record>-->
|
||||
|
||||
<!-- <record id="takaful_grant_benefit_form" model="ir.ui.view">-->
|
||||
<!-- <field name="name">takaful.grant.benefit.form</field>-->
|
||||
<!-- <field name="model">grant.benefit</field>-->
|
||||
<!-- <field name="inherit_id" ref="odex_benefit.grant_benefit_form" />-->
|
||||
<!-- <field name="arch" type="xml">-->
|
||||
<!-- <xpath expr="/form/sheet/notebook/page[9]" position="before">-->
|
||||
<!-- <page string="Sponsorships">-->
|
||||
<!-- <group name="sponsorship_needs_info">-->
|
||||
<!-- <field name="is_active_sponsorship" />-->
|
||||
<!-- </group>-->
|
||||
<!-- <group col="4">-->
|
||||
<!-- <field name="benefit_needs_value" />-->
|
||||
<!-- <field name="benefit_needs_percent" />-->
|
||||
<!-- <field name="benefit_arrears_value" />-->
|
||||
<!-- </group>-->
|
||||
<!-- <group>-->
|
||||
<!-- <field name="has_kafala_delay" />-->
|
||||
<!-- <field name="overdue_kafalat_amount" />-->
|
||||
<!-- <field name="sponsorship_ids" />-->
|
||||
<!-- </group>-->
|
||||
<!-- <!– <page string="Sponsorships" name="sponsorships_info_page">–>-->
|
||||
<!-- <!– <group>–>-->
|
||||
<!-- <!– <field name="sponsorship_payment_ids">–>-->
|
||||
<!-- <!– <tree editable="bottom">–>-->
|
||||
<!-- <!– <field name="benefit_id" invisible="1"/>–>-->
|
||||
<!-- <!– <field name="partner_id"/>–>-->
|
||||
<!-- <!– <field name="operation_code"/>–>-->
|
||||
<!-- <!– <field name="due_date"/>–>-->
|
||||
<!-- <!– <field name="amount"/>–>-->
|
||||
<!-- <!– <field name="status"/>–>-->
|
||||
<!-- <!– <field name="recieve_date"/>–>-->
|
||||
<!-- <!– </tree>–>-->
|
||||
<!-- <!– </field>–>-->
|
||||
<!-- <!– </group>–>-->
|
||||
<!-- <!– </page>–>-->
|
||||
<!-- </page>-->
|
||||
<!-- </xpath>-->
|
||||
<!-- </field>-->
|
||||
<!-- </record>-->
|
||||
|
||||
<!-- New Added -->
|
||||
<!-- Beneficiaries Invoice Form View -->
|
||||
<record model="ir.ui.view" id="benefit_grant_due_invoice_form">
|
||||
<field name="name">grant.benefit.invoice.form</field>
|
||||
<field name="model">grant.benefit.invoice</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Due Payment" create="false" edit="false" delete="false" duplicate="false">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="operation_code" readonly="1" />
|
||||
<field name="operation_type" readonly="1" />
|
||||
<field name="partner_id" readonly="1" />
|
||||
<field name="operation_invoice_id" readonly="1" />
|
||||
<field name="due_date" />
|
||||
|
||||
<field name="journal_id" readonly="1" />
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="paid_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}" readonly="1" />
|
||||
<field name="payment_date" widget="date" readonly="1" />
|
||||
<field name="benefit_target" readonly="1" />
|
||||
<field name="note" readonly="1" />
|
||||
|
||||
<field name="is_recorded" readonly="1" />
|
||||
<field name="due_code" />
|
||||
|
||||
<field name="benefit_ids" readonly="1">
|
||||
<tree>
|
||||
<field name="name" />
|
||||
<field name="gender" />
|
||||
<field name="city_id" />
|
||||
<field name="phone" />
|
||||
<field name="email" />
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Beneficiaries Invoice Tree View -->
|
||||
<record model="ir.ui.view" id="benefit_grant_due_invoice_tree">
|
||||
<field name="name">grant.benefit.invoice.tree</field>
|
||||
<field name="model">grant.benefit.invoice</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Due Payments List" create="false" edit="false" delete="false"
|
||||
duplicate="false"
|
||||
decoration-danger="is_recorded==False">
|
||||
<field name="operation_type" />
|
||||
<field name="operation_code" />
|
||||
<field name="benefit_type" />
|
||||
<field name="benefit_target" />
|
||||
<field name="benefit_ids" widget="many2many_tags" />
|
||||
<field name="partner_id" />
|
||||
<field name="due_date" widget="date"/>
|
||||
<field name="payment_date" widget="date"/>
|
||||
<field name="paid_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="is_recorded" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Beneficiaries Invoice Search View -->
|
||||
<record model="ir.ui.view" id="benefit_grant_due_invoice_search">
|
||||
<field name="name">grant.benefit.invoice.search</field>
|
||||
<field name="model">grant.benefit.invoice</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="operation_type" />
|
||||
<field name="operation_code" />
|
||||
<field name="benefit_type" />
|
||||
<field name="benefit_target" />
|
||||
<field name="benefit_ids" />
|
||||
<field name="partner_id" />
|
||||
<field name="due_date" />
|
||||
<field name="payment_date" />
|
||||
<field name="is_recorded" />
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Beneficiaries Invoice Window Action -->
|
||||
<record model="ir.actions.act_window" id="benefit_grant_due_invoice_action">
|
||||
<field name="name">Beneficiaries Due Payments</field>
|
||||
<field name="res_model">grant.benefit.invoice</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">No Due Payments for Beneficiaries
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Sponsorships Arrears for Benefits -->
|
||||
<record model="ir.ui.view" id="sponsorship_benefit_arrears_form">
|
||||
<field name="name">sponsorship.benefit.arrears.form</field>
|
||||
<field name="model">sponsorship.benefit.arrears</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sponsorships Arrears" delete="false">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="is_paid" invisible="1" />
|
||||
<field name="sponsorship_id" invisible="1" />
|
||||
<field name="code" readonly="1" />
|
||||
<field name="sponsor_id" readonly="1" />
|
||||
<field name="benefit_id" required="1" />
|
||||
<field name="benefit_type" readonly="1" />
|
||||
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="month_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}" readonly="1" />
|
||||
<field name="arrears_month_number" readonly="1" />
|
||||
<field name="arrears_total" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}" readonly="1" />
|
||||
<field name="date" widget="date" readonly="1" />
|
||||
|
||||
</group>
|
||||
|
||||
<group string="Payment Information">
|
||||
<field name="arrears_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}" readonly="1" />
|
||||
<field name="paid_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}" readonly="1" />
|
||||
<field name="invoice_ids" widget="one2many" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="sponsorship_benefit_arrears_tree">
|
||||
<field name="name">sponsorship.benefit.arrears.tree</field>
|
||||
<field name="model">sponsorship.benefit.arrears</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sponsorships Arrears List" decoration-danger="is_paid==False"
|
||||
decoration-success="is_paid==True">
|
||||
<field name="is_paid" invisible="1" />
|
||||
<field name="code" />
|
||||
<field name="sponsor_id" />
|
||||
<field name="benefit_id" />
|
||||
<field name="benefit_type" />
|
||||
<field name="date" widget="date"/>
|
||||
<field name="arrears_month_number" />
|
||||
<field name="arrears_total" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="arrears_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="paid_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="sponsorship_benefit_arrears_search">
|
||||
<field name="name">sponsorship.benefit.arrears.search</field>
|
||||
<field name="model">sponsorship.benefit.arrears</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="code" />
|
||||
<field name="sponsor_id" />
|
||||
<field name="benefit_id" />
|
||||
<field name="benefit_type" />
|
||||
<field name="date" widget="date"/>
|
||||
<field name="arrears_month_number" />
|
||||
<field name="arrears_total" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="arrears_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="paid_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="sponsorship_benefit_arrears_action">
|
||||
<field name="name">Sponsorships Arrears</field>
|
||||
<field name="res_model">sponsorship.benefit.arrears</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">No Any Sponsorships Arrears
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
|
||||
<menuitem id="takaful_kufula_app_top_menu" sequence="15" name="Kafalat System" web_icon="odex_takaful,static/description/icon.png" groups="odex_takaful.group_kufula_user"/>
|
||||
|
||||
<!-- Main Kafalat-->
|
||||
<menuitem id="kafalat_main_menu" parent="takaful_kufula_app_top_menu"
|
||||
sequence="10" name="Kafalat"/>
|
||||
|
||||
<menuitem id="takaful_sponsorship_app_menu" parent="kafalat_main_menu"
|
||||
name="Sponsorships" action="takaful_sponsorship_action" sequence="1"/>
|
||||
|
||||
<menuitem id="donations_details_lines_app_menu" parent="kafalat_main_menu"
|
||||
name="Donations Details Lines" action="donations_details_lines_action" sequence="2"/>
|
||||
|
||||
<menuitem id="donations_details_lines_to_replace_app_menu" parent="menu_replacement_root"
|
||||
name="Donations Details Lines To Replace Benefit" action="donations_details_lines_replace_action" sequence="3"/>
|
||||
|
||||
<menuitem id="donations_details_lines_waiting_app_menu" parent="menu_replacement_root"
|
||||
name="Donations Details Lines Waiting Benefit" action="donations_details_lines_waiting_action" sequence="4"/>
|
||||
|
||||
|
||||
|
||||
<!-- TODO WE WILL USE IT LATER DON'T REMOVE THIS -->
|
||||
<!-- START OF THE BLOCK -->
|
||||
<!-- <menuitem id="takaful_sponsorship_payment_menu" name="Sponsorship Payment"
|
||||
parent="kafalat_main_menu" action="takaful_sponsorship_payment_action" sequence="2" />
|
||||
|
||||
<menuitem id="sponsorship_cancellation_menu" name="Sponsorship Cancellation"
|
||||
parent="kafalat_main_menu" action="sponsorship_cancellation_action" sequence="3" />
|
||||
|
||||
<menuitem id="takaful_contribution_app_menu" name="The Financial Contributions"
|
||||
parent="kafalat_main_menu" action="takaful_financial_contribution_action" sequence="4"/>
|
||||
|
||||
<menuitem id="takaful_push_notification_menu" name="Notifications Messages"
|
||||
parent="kafalat_main_menu" action="takaful_push_notification_action" sequence="5" /> -->
|
||||
<!-- END OF THE BLOCK -->
|
||||
|
||||
<!-- Main Kafileen-->
|
||||
<menuitem id="kafileen_main_menu" parent="takaful_kufula_app_top_menu"
|
||||
sequence="12" name="Kafileen"/>
|
||||
|
||||
<menuitem id="takaful_sponsor_menu" parent="kafileen_main_menu"
|
||||
name="Sponsors Record" action="takaful_sponsor_action" sequence="1"/>
|
||||
|
||||
<!-- <menuitem id="takaful_sponsor_operation_menu" name="Operations Records" parent="kafileen_main_menu" action="takaful_sponsor_operation_action" sequence="2"/> -->
|
||||
|
||||
<!-- Main Online Payments
|
||||
<menuitem id="account_takaful_core_online_paycard_menu" name="Online Payments"
|
||||
parent="takaful_kufula_app_top_menu" sequence="15"/>
|
||||
|
||||
<menuitem sequence="1" id="account_takaful_core_account_move_menu" name="Online Invoices"
|
||||
parent="account_takaful_core_online_paycard_menu" action="takaful_core.takaful_account_move_list_action"/>
|
||||
|
||||
<menuitem sequence="2" id="account_takaful_core_bank_transfer_menu" name="Bank Transfers" parent="account_takaful_core_online_paycard_menu" action="takaful_core.act_takaful_bank_transfer_view"/>
|
||||
-->
|
||||
|
||||
<!-- Main Beneficiaries -->
|
||||
<!-- TODO WE WILL USE IT LATER DON'T REMOVE THIS -->
|
||||
<!-- START OF THE BLOCK -->
|
||||
<!-- <menuitem id="takaful_benefit_operation_menu" name="Beneficiaries" parent="takaful_kufula_app_top_menu" sequence="20"/>
|
||||
|
||||
<menuitem id="benefit_grant_due_invoice_menu" name="Due Payments" parent="takaful_benefit_operation_menu" action="benefit_grant_due_invoice_action" sequence="1"/>
|
||||
|
||||
<menuitem id="benefit_month_payment_menu" name="Monthly Payments"
|
||||
parent="takaful_benefit_operation_menu" action="benefit_month_payment_action" sequence="2"/>
|
||||
|
||||
<menuitem id="benefit_month_payment_line_menu" name="Beneficiaries Payments"
|
||||
parent="takaful_benefit_operation_menu" action="benefit_month_payment_line_action" sequence="3"/>
|
||||
|
||||
<menuitem id="sponsorship_benefit_arrears_menu" name="Beneficiaries Arrears" parent="takaful_benefit_operation_menu" action="sponsorship_benefit_arrears_action" sequence="4"/> -->
|
||||
<!-- END OF THE BLOCK -->
|
||||
|
||||
<!-- Main Reports -->
|
||||
<menuitem id="sponsor_report_menu" parent="takaful_kufula_app_top_menu"
|
||||
name="Reports" sequence="40" />
|
||||
|
||||
<menuitem id="active_sponsor_report_menu" parent="sponsor_report_menu" sequence="10" name="Active Sponsors Report" action="action_active_sponsor_report"/>
|
||||
|
||||
<menuitem id="makfuleen_report_menu" parent="sponsor_report_menu" sequence="15" name="Makfuleen Report" action="makfuleen_wizard_report_action"/>
|
||||
|
||||
<menuitem id="payment_overdue_report_menu" parent="sponsor_report_menu" sequence="20" name="Kafalat Overdue Report" action="kafalat_payment_wizard_report_action"/>
|
||||
|
||||
<menuitem id="canceled_kafalat_report_menu" parent="sponsor_report_menu" sequence="25" name="Canceled Kafalat Report" action="kafalat_cancel_wizard_report_action"/>
|
||||
|
||||
<menuitem id="benefit_payment_sponsorship_menu_report"
|
||||
name="Benefits Payments"
|
||||
parent="sponsor_report_menu"
|
||||
action="sponsor_report_menu_action"
|
||||
sequence="30"
|
||||
/>
|
||||
|
||||
<menuitem id="benefit_month_payment_sponsorship_menu_report"
|
||||
name="Benefits Month Payments"
|
||||
parent="sponsor_report_menu"
|
||||
action="benefit_month_report_action"
|
||||
sequence="35"
|
||||
/>
|
||||
|
||||
<!-- Main Settings -->
|
||||
<menuitem id="sponsor_setting_menu" parent="takaful_kufula_app_top_menu"
|
||||
name="Global Settings" sequence="99" groups="odex_takaful.sponsorship_system_manager_group"/>
|
||||
|
||||
|
||||
<!-- <menuitem id="base_takaful_notification_menu"
|
||||
name="Notifications"
|
||||
parent="odex_takaful.sponsor_setting_menu"
|
||||
action="odex_takaful_base.takaful_notification_action"
|
||||
sequence="1"/> -->
|
||||
|
||||
<menuitem id="sponsorship_stop_reason_menu"
|
||||
name="Reasons To Stop"
|
||||
parent="odex_takaful.sponsor_setting_menu"
|
||||
action="odex_takaful.action_config_sponsorship_stop"
|
||||
sequence="2"/>
|
||||
|
||||
<menuitem id="takaful_message_template_menu"
|
||||
name="Messages Templates"
|
||||
parent="odex_takaful.sponsor_setting_menu"
|
||||
action="odex_takaful.takaful_message_template_action"
|
||||
sequence="3"/>
|
||||
|
||||
|
||||
<!-- Begin Kufala Settings -->
|
||||
|
||||
<menuitem id="takaful_app_top_menu" parent="sponsor_setting_menu" sequence="99"
|
||||
name="Kufala Settings" />
|
||||
|
||||
<menuitem id="message_type_menu" action="odex_takaful_base.takaful_message_type_action"
|
||||
name="Message Types" sequence="5"
|
||||
parent="takaful_app_top_menu"/>
|
||||
|
||||
<menuitem id="takaful_notification_menu" action="odex_takaful_base.takaful_notification_action"
|
||||
name="Notifications" sequence="10"
|
||||
parent="takaful_app_top_menu"/>
|
||||
|
||||
<record model="ir.ui.menu" id="takaful_app_top_menu">
|
||||
<field name="groups_id" eval="[(6,0,[ref('odex_takaful.sponsorship_system_manager_group')])]"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="takaful_settings_menu" name="Kufala Global Settings"
|
||||
parent="takaful_app_top_menu" action="odex_takaful_base.takaful_settings_action" sequence="99"/>
|
||||
|
||||
<!-- END Kufala Settings -->
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
<odoo>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="benefit_month_payment_form">
|
||||
<field name="name">month.payment.form</field>
|
||||
<field name="model">month.payment</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Month Payment">
|
||||
<header>
|
||||
<button name="action_create_lines" class="oe_highlight" type="object" string="Create Lines"
|
||||
confirm="Are you sure you want to Create lines Manually?" states="draft"/>
|
||||
|
||||
<button name="action_approve" class="oe_highlight" type="object" string="Approve"
|
||||
confirm="Are you sure you want to Approve?" states="create"/>
|
||||
|
||||
<button name="action_submit" class="oe_highlight" type="object" string="Submit To Pay"
|
||||
confirm="Are you sure you want to Submit?" states="approve"/>
|
||||
|
||||
|
||||
<button name="action_notify" class="oe_highlight" type="object" string="Pay Notify"
|
||||
confirm="Are you sure you want to Send Pay Notify?" states="submit"/>
|
||||
|
||||
<button name="action_refuse" class="oe_highlight" type="object" string="Refuse"
|
||||
confirm="Are you sure you want to Refuse?"
|
||||
states="create"/>
|
||||
|
||||
<button name="action_cancel" type="object" string="Cancel"
|
||||
states="create,refused"
|
||||
confirm="Are you sure you want to Cancel?"/>
|
||||
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="open_payments"
|
||||
type="object" class="oe_stat_button" icon="fa-users">
|
||||
<field string=" Payments" name="count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field placeholder="Name" name="name" class="oe_inline"
|
||||
attrs="{'readonly':[('state','!=','draft')],'required':True}"/>
|
||||
|
||||
</h1>
|
||||
<h2>
|
||||
<field name="code"/>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<group col="4" colspan="2">
|
||||
|
||||
<field name="date" widget="date" attrs="{'readonly':[('state','!=','draft')],'required':True}"/>
|
||||
<field name="user_id" readonly="1" force_save="1"/>
|
||||
<field name="entry_id" readonly="1" force_save="1"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'readonly':[('state','!=','draft')],'required':True}"/>
|
||||
</group>
|
||||
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="benefit_month_payment_tree">
|
||||
<field name="name">month.payment.tree</field>
|
||||
<field name="model">month.payment</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="benefit_month_payment_search">
|
||||
<field name="name">month.payment.search</field>
|
||||
<field name="model">month.payment</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="state"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!--line-->
|
||||
<record model="ir.ui.view" id="benefit_month_payment_line_form">
|
||||
<field name="name">month.payment.line.form</field>
|
||||
<field name="model">month.payment.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<!-- delete="false"-->
|
||||
<form string="Month Payment" create="false" edit="false">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field placeholder="Name" name="benefit_id" class="oe_inline" force_save="1"
|
||||
attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
<field name="benefit_type"/>
|
||||
</h1>
|
||||
|
||||
<group col="4" colspan="2">
|
||||
<field name="s_code"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="responsible_id"/>
|
||||
<field name="partner_id"/>
|
||||
</group>
|
||||
|
||||
<group col="4" colspan="2">
|
||||
<field name="code"/>
|
||||
<field name="month_id" force_save="1" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
<field name="date" force_save="1" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
<field name="amount" force_save="1" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
<field name="state" invisible="1"/>
|
||||
</group>
|
||||
|
||||
</div>
|
||||
</sheet>
|
||||
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="benefit_month_payment_line_tree">
|
||||
<field name="name">month.payment.line.tree</field>
|
||||
<field name="model">month.payment.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree create="false" edit="false" delete="false">
|
||||
<field name="benefit_id"/>
|
||||
<field name="benefit_type"/>
|
||||
<field name="s_code"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="month_id"/>
|
||||
<field name="code"/>
|
||||
<field name="date"/>
|
||||
<field name="amount"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="benefit_month_payment_line_search">
|
||||
<field name="name">month.payment.line.search</field>
|
||||
<field name="model">month.payment.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="benefit_id"/>
|
||||
<field name="benefit_type"/>
|
||||
<field name="s_code"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="month_id"/>
|
||||
<field name="code"/>
|
||||
<field name="date"/>
|
||||
<field name="amount"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Window Actions -->
|
||||
<record model="ir.actions.act_window" id="benefit_month_payment_action">
|
||||
<field name="name">Month Payment</field>
|
||||
<field name="res_model">month.payment</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">Create a Month Payment
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.actions.act_window" id="benefit_month_payment_line_action">
|
||||
<field name="name">Benefit Month Payment</field>
|
||||
<field name="res_model">month.payment.line</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">Create the Month Payment Line
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<odoo>
|
||||
<!-- Inherit the original form view -->
|
||||
<record id="inherit_takaful_sponsorship_notification_form" model="ir.ui.view">
|
||||
<field name="name">takaful.notification.form.inherit</field>
|
||||
<field name="model">takaful.notification</field>
|
||||
<field name="inherit_id" ref="odex_takaful_base.takaful_notification_form"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<xpath expr="//field[@name='duration']" position="before">
|
||||
<field name="name"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='notification_type']" position="after">
|
||||
<field name="notification_state_ids" widget="many2many_tags" options="{'no_create': True}">
|
||||
<tree>
|
||||
<field name="display_name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//page[@name='Types']" position="after">
|
||||
<page string="Messages">
|
||||
<group>
|
||||
<field name="message"/>
|
||||
</group>
|
||||
|
||||
</page>
|
||||
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="inherit_takaful_sponsorship_notification_tree" model="ir.ui.view">
|
||||
<field name="name">takaful.notification.tree.inherit</field>
|
||||
<field name="model">takaful.notification</field>
|
||||
<field name="inherit_id" ref="odex_takaful_base.takaful_notification_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<xpath expr="//field[@name='duration']" position="before">
|
||||
<field name="name"/>
|
||||
<field name="notification_state_ids" widget="many2many_tags"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<odoo>
|
||||
|
||||
<record id="view_takaful_payment_method_form" model="ir.ui.view">
|
||||
<field name="name">takaful.payment.method.form</field>
|
||||
<field name="model">takaful.payment.method</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Takaful Payment Method">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="payment_method"/>
|
||||
<field name="journal_id"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_takaful_payment_method_tree" model="ir.ui.view">
|
||||
<field name="name">takaful.payment.method.tree</field>
|
||||
<field name="model">takaful.payment.method</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Takaful Payment Method">
|
||||
<field name="name"/>
|
||||
<field name="payment_method"/>
|
||||
<field name="journal_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_takaful_payment_method" model="ir.actions.act_window">
|
||||
<field name="name">Takaful Payment Method</field>
|
||||
<field name="res_model">takaful.payment.method</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_takaful_payment_method"
|
||||
name="Takaful Payment Method"
|
||||
parent="odex_takaful.sponsor_setting_menu"
|
||||
action="action_takaful_payment_method"/>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
<odoo>
|
||||
<data>
|
||||
|
||||
<!-- Form View -->
|
||||
<record model="ir.ui.view" id="takaful_push_notification_form">
|
||||
<field name="name">takaful.push.notification.form</field>
|
||||
<field name="model">takaful.push.notification</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Notification Message" create="false" edit="false" delete="false" duplicate="false">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="user_id" readonly="1"/>
|
||||
<field name="email" readonly="1"/>
|
||||
<field name="mobile" readonly="1"/>
|
||||
<field name="title" readonly="1"/>
|
||||
<field name="body" readonly="1"/>
|
||||
<field name="sent_on" readonly="1"/>
|
||||
<field name="is_read" readonly="1"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Tree View -->
|
||||
<record model="ir.ui.view" id="takaful_push_notification_tree">
|
||||
<field name="name">takaful.push.notification.tree</field>
|
||||
<field name="model">takaful.push.notification</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Notifications Messages List" create="false" edit="false" delete="false" duplicate="false">
|
||||
<field name="user_id"/>
|
||||
<field name="title"/>
|
||||
<field name="mobile"/>
|
||||
<field name="email"/>
|
||||
<field name="sent_on"/>
|
||||
<field name="is_read"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Search View -->
|
||||
<record model="ir.ui.view" id="takaful_push_notification_search">
|
||||
<field name="name">takaful.push.notification.search</field>
|
||||
<field name="model">takaful.push.notification</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="user_id"/>
|
||||
<field name="mobile"/>
|
||||
<field name="email"/>
|
||||
<field name="sent_on"/>
|
||||
<field name="is_read"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Message Template Form View -->
|
||||
<record model="ir.ui.view" id="takaful_message_template_form">
|
||||
<field name="name">Message Template Form</field>
|
||||
<field name="model">takaful.message.template</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Message Template" delete="false" duplicate="false">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="title"/>
|
||||
<field name="body"/>
|
||||
<field name="template_name"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Message Template Tree View -->
|
||||
<record model="ir.ui.view" id="takaful_message_template_tree">
|
||||
<field name="name">Messages Templates List</field>
|
||||
<field name="model">takaful.message.template</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Messages Templates List" delete="false" duplicate="false">
|
||||
<field name="title"/>
|
||||
<field name="body"/>
|
||||
<field name="template_name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Windows Action -->
|
||||
<record model="ir.actions.act_window" id="takaful_push_notification_action">
|
||||
<field name="name">Notification Message</field>
|
||||
<field name="res_model">takaful.push.notification</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">No Notification Messege
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Message Template Window Action -->
|
||||
<record model="ir.actions.act_window" id="takaful_message_template_action">
|
||||
<field name="name">Message Template</field>
|
||||
<field name="res_model">takaful.message.template</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">No Message Template
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,829 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<odoo>
|
||||
|
||||
<data noupdate="0">
|
||||
<record id="sponsorship" model="product.product">
|
||||
<field name="name">كفالة</field>
|
||||
<field name="type">service</field>
|
||||
<field name="default_code">sponsorship</field>
|
||||
<!-- <field name="standard_price">0</field> -->
|
||||
<field name="list_price">300.0</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<record id="grant_benefit_kafala_needs_tree" model="ir.ui.view">
|
||||
<field name="name">grant.benefit.tree</field>
|
||||
<field name="model">grant.benefit</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="benefit_needs_percent"/>
|
||||
<field name="benefit_needs_value"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="takaful_sponsorship_form" model="ir.ui.view">
|
||||
<field name="name">takaful.sponsorship.form</field>
|
||||
<field name="model">takaful.sponsorship</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Takaful Sponsorship">
|
||||
<header>
|
||||
<field name="show_register_payment" invisible="1"/>
|
||||
<!-- <button name="action_open_donation_catalog" type="object"-->
|
||||
<!-- <button name="donation_catelog" type="object"-->
|
||||
<!-- string="Donation Catalog" class="btn-primary"-->
|
||||
<!-- icon="fa-shopping-cart"-->
|
||||
<!-- attrs="{'invisible': ['|', '|', ('state', '!=', 'draft'), ('record_type', '!=', 'donation'), ('donation_mechanism', '!=', 'without_conditions')]}"/>-->
|
||||
<button name="action_confirm_data" type="object"
|
||||
string="Confirm Data" class="oe_highlight"
|
||||
attrs="{'invisible': ['|','|', ('state','!=','draft'), ('id','=',False), '&',('sponsor_or_donor_type','=','new_sponsor'),('sponsor_id','=',False)]}"/>
|
||||
|
||||
<button string="Pay All Sponsorships" name="action_register_payment" type="object"
|
||||
class="oe_highlight"
|
||||
attrs="{'invisible': ['|', ('state', 'not in', ['confirmed', 'wait_pay','under_replacement','replacement_done']), ('show_register_payment', '=', False)]}"/>
|
||||
|
||||
<button name="action_set_cancel" type="object"
|
||||
string="To Cancel" class="oe_highlight"
|
||||
attrs="{'invisible': [('state','not in',['confirmed'])]}"/>
|
||||
<button name="action_reset_to_draft" type="object"
|
||||
string="Reset to Draft" class="btn-link"
|
||||
attrs="{'invisible': [('state','!=','confirmed')]}"/>
|
||||
<button name="action_set_close" type="object"
|
||||
string="Close" class="oe_highlight"
|
||||
attrs="{'invisible': [('state', 'not in', ['wait_pay', 'paid'])]}"/>
|
||||
<button name="action_refund" type="object"
|
||||
string="Refund All" class="oe_highlight"
|
||||
attrs="{'invisible': ['|','|',('state','not in',['paid','partial_refund','under_replacement','replacement_done']),('record_type','!=','donation'), ('cancel_refund', '=', True)]}"/>
|
||||
<button string="Approve Refund" name="approve_refund" type="object"
|
||||
class="oe_highlight"
|
||||
attrs="{'invisible': [ '|', ('record_type', '!=', 'donation'), ('state', '!=', 'approve_refund')]}"
|
||||
groups="odex_takaful.group_refund_approval"/>
|
||||
<field name="state" widget="statusbar"
|
||||
statusbar_visible="draft,confirmed,wait_pay,paid,canceled,closed"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div name="oe_button_box" class="oe_button_box">
|
||||
<button name="action_view_journal_entries" type="object"
|
||||
class="oe_stat_button" icon="fa-book">
|
||||
<field name="journal_entry_count" string="Invoices" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_view_journal_entries_vendor" type="object"
|
||||
class="oe_stat_button" icon="fa-book"
|
||||
attrs="{'invisible': ['|', ('record_type','!=','donation'), ('donation_mechanism','!=','with_conditions')]}">
|
||||
<field name="journal_entry_count_vendor" string="Vendor Invoices" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_view_refund_moves" type="object"
|
||||
class="oe_stat_button" icon="fa-money">
|
||||
<field name="refund_move_count" string="Refund Invoices"
|
||||
widget="statinfo"/>
|
||||
</button>
|
||||
<!-- <button name="action_replacement_processes" type="object"-->
|
||||
<!-- string="Replacement Processes" class="oe_stat_button" icon="fa-users">-->
|
||||
<!-- </button>-->
|
||||
</div>
|
||||
|
||||
<!-- Code badge hidden for now -->
|
||||
<!-- <div style="position: absolute; top: 70px; right: 15px; z-index: 100;" attrs="{'invisible': [('code', '=', False)]}">
|
||||
<span class="badge badge-info" style="font-size: 14px; padding: 6px 12px;">
|
||||
<i class="fa fa-barcode"/> <field name="code" nolabel="1" readonly="1"/>
|
||||
</span>
|
||||
</div> -->
|
||||
|
||||
<!-- Record Type Selection - Simple & Clean Design -->
|
||||
<div class="o_record_type_simple">
|
||||
<div class="record_type_options">
|
||||
<div class="record_option donation_option" data-value="donation">
|
||||
<i class="fa fa-heart"></i>
|
||||
<span>تبرع</span>
|
||||
</div>
|
||||
<div class="record_option sponsorship_option" data-value="sponsorship">
|
||||
<i class="fa fa-users"></i>
|
||||
<span>كفالة</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hidden field for actual value -->
|
||||
<field name="record_type" readonly="0" nolabel="1" invisible="1"
|
||||
groups="!odex_takaful.branch_manager_group,!odex_takaful.sponsorship_system_manager_group,odex_takaful.donation_officer_group,odex_takaful.sponsorship_officer_group"/>
|
||||
<field name="record_type" nolabel="1" invisible="1"
|
||||
groups="odex_takaful.branch_manager_group,odex_takaful.sponsorship_system_manager_group"
|
||||
attrs="{'readonly': [('state','!=','draft')]}"/>
|
||||
</div>
|
||||
|
||||
<!-- Donation Type Selection - Only for Donations -->
|
||||
<div class="o_donation_mechanism_simple"
|
||||
attrs="{'invisible': [('record_type','!=','donation')]}">
|
||||
<div class="mechanism_options">
|
||||
<div class="mechanism_option without_conditions" data-value="without_conditions">
|
||||
<i class="fa fa-check-circle"></i>
|
||||
<span>غير مشروط</span>
|
||||
</div>
|
||||
<div class="mechanism_option with_conditions" data-value="with_conditions">
|
||||
<i class="fa fa-list-alt"></i>
|
||||
<span>مشروط</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hidden field for actual value -->
|
||||
<field name="donation_mechanism" invisible="1" nolabel="1"
|
||||
attrs="{'required': [('record_type','=','donation')], 'readonly': [('state','!=','draft')]}"/>
|
||||
</div>
|
||||
|
||||
<!-- Help Messages Section -->
|
||||
<div class="alert alert-info text-center"
|
||||
attrs="{'invisible': [('record_type','!=','donation')]}">
|
||||
<i class="fa fa-heart text-success"/>
|
||||
أدخل بيانات المتبرع ثم حدد تفاصيل التبرع
|
||||
</div>
|
||||
|
||||
<div class="alert alert-primary text-center"
|
||||
attrs="{'invisible': [('record_type','!=','sponsorship')]}">
|
||||
<i class="fa fa-users text-primary"/>
|
||||
أدخل بيانات الكافل ثم انتقل لإضافة تفاصيل الكفالة
|
||||
</div>
|
||||
|
||||
<group name="group_top">
|
||||
<group name="group_left" string="Donor Information">
|
||||
<field name="manager_id" invisible="1"/>
|
||||
<field name="is_donations_coordinator" invisible="1"/>
|
||||
<field name="is_sponsorship_coordinator" invisible="1"/>
|
||||
<field name="registered_type" invisible="1" attrs="{'readonly': [('state','!=','draft')]}"/>
|
||||
|
||||
<label string="Sponsor / Donor Type" for="sponsor_or_donor_type"/>
|
||||
<div class="o_row">
|
||||
<field name="sponsor_or_donor_type"
|
||||
attrs="{'invisible': [('record_type','!=','donation')], 'required': [('record_type','=','donation')], 'readonly': [('state','!=','draft')]}"/>
|
||||
<field name="sponsor_donor_type"
|
||||
attrs="{'invisible': [('record_type','!=','sponsorship')], 'required': [('record_type','=','sponsorship')], 'readonly': [('state','!=','draft')]}"/>
|
||||
</div>
|
||||
|
||||
<label string="اسم الكافل/المتبرع" for="sponsor_id"
|
||||
attrs="{
|
||||
'invisible': ['|',
|
||||
'&', ('record_type','=','donation'), ('sponsor_or_donor_type','=','unknown'),
|
||||
'&', ('record_type','=','sponsorship'), ('sponsor_donor_type','=','unknown')
|
||||
]
|
||||
}"/>
|
||||
<div class="o_row">
|
||||
<field name="sponsor_id" nolabel="1"
|
||||
context="{'form_view_ref': 'odex_takaful.view_takaful_sponsor_form'}"
|
||||
attrs="{
|
||||
'invisible': ['|',
|
||||
'&', ('record_type','=','donation'), ('sponsor_or_donor_type','=','unknown'),
|
||||
'&', ('record_type','=','sponsorship'), ('sponsor_donor_type','=','unknown')
|
||||
],
|
||||
'required': ['|',
|
||||
'&', ('record_type','=','donation'), ('sponsor_or_donor_type','=','registered'),
|
||||
'&', ('record_type','=','sponsorship'), ('sponsor_donor_type','=','registered')
|
||||
],
|
||||
'readonly': [('state','!=','draft')]
|
||||
}"
|
||||
force_save="1"
|
||||
options="{'no_create': True, 'no_create_edit': True}"/>
|
||||
|
||||
<button name="create_new_sponsor" type="object"
|
||||
string="إنشاء مشترك"
|
||||
class="btn-primary oe_highlight"
|
||||
icon="fa-plus"
|
||||
attrs="{
|
||||
'invisible': ['|', '|',
|
||||
('sponsor_id','!=',False),
|
||||
'&', ('record_type', '=', 'donation'), ('sponsor_or_donor_type', '!=', 'new_sponsor'),
|
||||
'&', ('record_type', '=', 'sponsorship'), ('sponsor_donor_type', '!=', 'new_sponsor')
|
||||
]
|
||||
}"/>
|
||||
</div>
|
||||
|
||||
<field name="sponsor_phone" string="رقم الجوال" widget="phone"
|
||||
attrs="{
|
||||
'invisible': ['|',
|
||||
'&', ('record_type','=','donation'), ('sponsor_or_donor_type','!=','unknown'),
|
||||
'&', ('record_type','=','sponsorship'), ('sponsor_donor_type','!=','unknown')
|
||||
],
|
||||
'readonly': [('state','!=','draft')]
|
||||
}"
|
||||
placeholder="05xxxxxxxx"/>
|
||||
|
||||
<field name="preferred_communication" string="طريقة التواصل المفضلة"
|
||||
attrs="{
|
||||
'invisible': ['|',
|
||||
'&', ('record_type','=','donation'), ('sponsor_or_donor_type','=','unknown'),
|
||||
'&', ('record_type','=','sponsorship'), ('sponsor_donor_type','=','unknown')
|
||||
],
|
||||
'readonly': [True]
|
||||
}"
|
||||
force_save="1"
|
||||
options="{'no_create': True, 'no_create_edit': True}"/>
|
||||
</group>
|
||||
|
||||
<group name="group_right" string="Basic Information">
|
||||
<field name="is_widow_orphan" invisible="1"/>
|
||||
<field name="cancel_refund" invisible="1"/>
|
||||
<field name="has_delay" invisible="1"/>
|
||||
<field name="members_domain_ids" invisible="1"/>
|
||||
|
||||
<field name="donate_for_another_person" widget="boolean_toggle"
|
||||
attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="sponsorship_creation_date" readonly="1"/>
|
||||
<field name="create_uid" string="Sponsorship Creator" readonly="1"/>
|
||||
|
||||
<field name="branch_custom_id" groups="!odex_takaful.sponsorship_system_manager_group"
|
||||
readonly="0"/>
|
||||
<field name="branch_custom_id"
|
||||
groups="odex_takaful.sponsorship_system_manager_group"
|
||||
attrs="{'readonly': [('state','!=','draft')]}"/>
|
||||
|
||||
<field name="marketer_id" attrs="{'readonly': [('state','!=','draft')]}"
|
||||
context="{'default_domain_force_all': True}"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<field name="is_gift" invisible="1"/>
|
||||
<field name="show_payment_details" invisible="1"/>
|
||||
</group>
|
||||
|
||||
<group string="Gifter Information"
|
||||
attrs="{'invisible': [('is_gift', '!=', 'yes')]}">
|
||||
<field name="gifter_id" readonly="1"/>
|
||||
<field name="gifter_name" readonly="1"/>
|
||||
<field name="gifter_mobile" widget="phone" readonly="1"/>
|
||||
<field name="gifter_message" readonly="1"/>
|
||||
</group>
|
||||
|
||||
<group attrs="{'invisible': [('state', '!=', 'canceled')]}">
|
||||
<field name="cancel_reason_id" invisible="1"/>
|
||||
<field name="reason" readonly="1"
|
||||
attrs="{'invisible': [('state', '!=', 'canceled')]}" style="color: red;"/>
|
||||
</group>
|
||||
<group>
|
||||
<notebook>
|
||||
<page string="Another Sponsors"
|
||||
attrs="{'invisible':[('donate_for_another_person','=',False)]}">
|
||||
<field name="another_sponsors">
|
||||
<tree editable="bottom">
|
||||
<field name="sponsor_name"/>
|
||||
<field name="sponsor_phone" widget="phone"/>
|
||||
<field name="sponsor_id_number"/>
|
||||
<field name="receive_messages" widget="boolean_toggle"/>
|
||||
<field name="note"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page name="sponsorship_details" string="Donation Details">
|
||||
<field name="donations_details_lines"
|
||||
context="{'default_active_id': active_id,'default_donation_mechanism': 'without_conditions','default_start_date': sponsorship_creation_date}"
|
||||
widget="section_and_note_one2many"
|
||||
attrs="{'invisible': ['|',('donation_mechanism', '=', 'with_conditions'),('record_type', '!=', 'donation')], 'readonly': [('state','!=','draft')]}">
|
||||
<tree editable="bottom">
|
||||
<control>
|
||||
<create name="add_line_control" string="Add a line"/>
|
||||
<!-- <create name="add_section_control" string="Add a section"-->
|
||||
<!-- context="{'default_display_type': 'line_section'}"/>-->
|
||||
<!-- <button name="action_delegate_to_catalog" string="Catalog" type="object" class="px-4 btn-link" context="{'sponsorship_id': parent.id}"/>-->
|
||||
</control>
|
||||
<field name="sponsorship_duration" invisible="1"/>
|
||||
<field name="payment_option" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="is_paid" invisible="1"/>
|
||||
<field name="donation_mechanism" invisible="1"/>
|
||||
<field name="display_type" invisible="1"/>
|
||||
<field name="sponsorships_computed" invisible="1"/>
|
||||
<field name="direct_debit" invisible="1"/>
|
||||
<field name="members_domain_ids" invisible="1"/>
|
||||
<field name="family_domain_ids" invisible="1"/>
|
||||
<field name="fixed_value" invisible="1"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="sequence_no" readonly="1" optional="hide"/>
|
||||
<field name="sponsorship_scheduling_line_ids" invisible="1"/>
|
||||
<field name="show_extend_button" invisible="1"/>
|
||||
<field name="donation_type"
|
||||
invisible="1"/>
|
||||
<!-- attrs="{'column_invisible': [('parent.record_type', '=', 'donation')],'required': ['|',('parent.record_type', '=', 'donation'),('display_type', '=', False)]}"/>-->
|
||||
<field name="donation_types"
|
||||
invisible="1" force_save="1"/>
|
||||
<!-- attrs="{'column_invisible': [('parent.record_type', '!=', 'donation')], 'required': [('parent.record_type', '=', 'donation'), ('display_type', '=', False)]}"-->
|
||||
<field name="product_template_id"
|
||||
attrs="{'required': [('display_type', '=', False)]}"
|
||||
options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/>
|
||||
<field name="name" widget="section_and_note_text" optional="show"/>
|
||||
<field name="direct_debit"/>
|
||||
<field name="journal_id"
|
||||
attrs="{'invisible': [('direct_debit', '=', False)], 'required': [('direct_debit', '=', True)]}"/>
|
||||
|
||||
<!-- <field name="cheque_number"
|
||||
attrs="{'required': [('payment_method', '=', 'check')], 'invisible': [('payment_method', '!=', 'check')]}"/>
|
||||
<field name="cheque_due_date"
|
||||
attrs="{'required': [('payment_method', '=', 'check')], 'invisible': [('payment_method', '!=', 'check')]}"/>
|
||||
<field name="cheque_file_attachment" widget="binary"
|
||||
filename="cheque_attachment_file_name"
|
||||
attrs="{'required': [('payment_method', '=', 'check')], 'invisible': [('payment_method', '!=', 'check')]}"/>
|
||||
<field name="cheque_attachment_file_name" invisible="1"/>
|
||||
<field name="bank_transfer_file_attachment" widget="binary"
|
||||
filename="bank_transfer_attachment_file_name"
|
||||
attrs="{'required': [('payment_method', '=', 'bank')], 'invisible': [('payment_method', '!=', 'bank')]}"/>
|
||||
<field name="bank_transfer_attachment_file_name" invisible="1"/>
|
||||
-->
|
||||
<field name="debit_payment_attachment_file_name" invisible="1"/>
|
||||
<field name="debit_payment_file_attachment" widget="binary"
|
||||
filename="debit_payment_attachment_file_name"
|
||||
attrs="{'required': [('direct_debit', '=', True)], 'invisible': [('direct_debit', '=', False)]}"
|
||||
optional="hide"/>
|
||||
<field name="sponsorship_type"
|
||||
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')]}"/>
|
||||
<field name="benefit_id"
|
||||
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')]}"/>
|
||||
<field name="payment_month_count" optional="hide"
|
||||
attrs="{'invisible': [('direct_debit', '=', False)]}"/>
|
||||
<field name="start_date" string="From" optional="hide" widget="date"
|
||||
attrs="{'invisible': [('direct_debit', '=', False)],'readonly': [('direct_debit', '=', False)], 'required': [('direct_debit', '=', True)]} "/>
|
||||
<field name="end_date" string="To" optional="hide" widget="date"
|
||||
attrs="{'invisible': [('direct_debit', '=', False)]}"
|
||||
readonly="1"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="donation_qty" force_save="1"/>
|
||||
<field name="donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'readonly':[('fixed_value','=',True)]}"
|
||||
force_save="1"
|
||||
required="1"/>
|
||||
<field name="total_donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
readonly="1" force_save="1"/>
|
||||
<button name="action_view_scheduling_lines"
|
||||
string="View Scheduling Lines"
|
||||
type="object"
|
||||
class="btn-secondary"
|
||||
icon="fa-calendar"
|
||||
attrs="{'invisible': ['|', ('direct_debit', '=', False), ('sponsorship_scheduling_line_ids', '=', [])]}"/>
|
||||
<button name="action_extend_sponsorship"
|
||||
string="Extend"
|
||||
type="object"
|
||||
class="btn-success"
|
||||
icon="fa-plus-circle"
|
||||
attrs="{'invisible': [('show_extend_button', '=', False)]}"/>
|
||||
<!-- <button name="action_register_payment"
|
||||
string="Register Payment"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
attrs="{'column_invisible': [('parent.state', 'not in', ['confirmed', 'wait_pay'])], 'invisible': ['|', ('direct_debit', '=', True), ('state', 'in', ['paid', 'active', 'waiting'])]}"/> -->
|
||||
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
<field name="donations_details_lines_mechanism_ids"
|
||||
context="{'default_active_id': id, 'default_donation_mechanism': 'with_conditions','default_start_date': sponsorship_creation_date, 'default_sponsor_id': sponsor_id, }"
|
||||
attrs="{'invisible': [('donation_mechanism', '=', 'without_conditions')], 'readonly': [('state','!=','draft')]}">
|
||||
<tree>
|
||||
<field name="sponsorships_computed" invisible="1"/>
|
||||
<field name="sponsorship_scheduling_line_ids" invisible="1"/>
|
||||
<field name="show_extend_button" invisible="1"/>
|
||||
<field name="show_replaced_button" invisible="1"/>
|
||||
<field name="show_add_benefit_button" invisible="1"/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="display_type" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="is_paid" invisible="1"/>
|
||||
<field name="direct_debit" invisible="1"/>
|
||||
<field name="sequence_no" readonly="1"/>
|
||||
<field name="donation_type"
|
||||
invisible="1"/>
|
||||
<!-- attrs="{'column_invisible': [('parent.record_type', '=', 'donation')],'required': ['|',('parent.record_type', '=', 'donation'),('display_type', '=', False)]}"/>-->
|
||||
<field name="donation_types"
|
||||
invisible="1"/>
|
||||
<!-- attrs="{-->
|
||||
<!-- 'column_invisible': [('parent.record_type', '!=', 'donation')],-->
|
||||
<!-- 'required': [('parent.record_type', '=', 'donation'), ('display_type', '=', False)]}"/>-->
|
||||
<field name="product_template_id"
|
||||
attrs="{'required': [('display_type', '=', False)]}"
|
||||
options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/>
|
||||
<field name="name"
|
||||
widget="section_and_note_text" optional="show"/>
|
||||
<field name="direct_debit"/>
|
||||
<!-- <field name="cheque_number"
|
||||
attrs="{'required': [('payment_method', '=', 'check')], 'invisible': [('payment_method', '!=', 'check')]}"/>
|
||||
<field name="cheque_due_date"
|
||||
attrs="{'required': [('payment_method', '=', 'check')], 'invisible': [('payment_method', '!=', 'check')]}"/>
|
||||
<field name="cheque_file_attachment" widget="binary"
|
||||
filename="cheque_attachment_file_name"
|
||||
attrs="{'required': [('payment_method', '=', 'check')], 'invisible': [('payment_method', '!=', 'check')]}"/>
|
||||
<field name="cheque_attachment_file_name" invisible="1"/>
|
||||
<field name="bank_transfer_file_attachment" widget="binary"
|
||||
filename="bank_transfer_attachment_file_name"
|
||||
attrs="{'required': [('payment_method', '=', 'bank')], 'invisible': [('payment_method', '!=', 'bank')]}"/>
|
||||
<field name="bank_transfer_attachment_file_name" invisible="1"/>
|
||||
<field name="debit_payment_file_attachment" widget="binary"
|
||||
filename="debit_payment_attachment_file_name"
|
||||
attrs="{'required': [('payment_method', '=', 'direct_debit')], 'invisible': [('payment_method', '!=', 'direct_debit')]}"/>
|
||||
<field name="debit_payment_attachment_file_name" invisible="1"/> -->
|
||||
<field name="sponsorship_type"
|
||||
invisible="1"/>
|
||||
<!-- attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')]}"/>-->
|
||||
<field name="members_domain_ids" invisible="1"/>
|
||||
<field name="family_domain_ids" invisible="1"/>
|
||||
<field name="benefit_id"
|
||||
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')]}"/>
|
||||
<field name="sponsorship_duration" invisible="1"/>
|
||||
<field name="payment_option"
|
||||
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')],'invisible': [('sponsorship_duration','!=','temporary')]}"
|
||||
readonly="1"/>
|
||||
<field name="payment_month_count_visibility" invisible="1"/>
|
||||
<field name="payment_month_count"
|
||||
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')],'invisible': [('direct_debit', '=', False)]}"
|
||||
/>
|
||||
<field name="start_date" widget="date"
|
||||
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')],'invisible': [('payment_option', '!=', 'month')],'readonly': [('direct_debit', '=', False)]}"
|
||||
string="Start Date"/>
|
||||
<field name="end_date" widget="date"
|
||||
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')],'invisible': [('payment_option', '!=', 'month')]}"
|
||||
string="End Date"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="donation_qty" invisible="1" force_save="1"/>
|
||||
<field name="record_type" invisible="1"/>
|
||||
<field name="donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
force_save="1"
|
||||
attrs="{'readonly': [('record_type','=','sponsorship')]}"/>
|
||||
<field name="total_donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
force_save="1"/>
|
||||
<field name="donation_mechanism"
|
||||
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions')]}"/>
|
||||
|
||||
<button name="action_view_scheduling_lines"
|
||||
string="View Scheduling Lines"
|
||||
type="object"
|
||||
class="btn-secondary"
|
||||
icon="fa-calendar"
|
||||
attrs="{'invisible': ['|', ('direct_debit', '=', False), ('sponsorship_scheduling_line_ids', '=', [])]}"/>
|
||||
|
||||
<button name="action_extend_sponsorship"
|
||||
string="Extend"
|
||||
type="object"
|
||||
class="btn-success"
|
||||
icon="fa-plus-circle"
|
||||
attrs="{'invisible': [('show_extend_button', '=', False)]}"/>
|
||||
|
||||
<button string="Add Benefit"
|
||||
name="add_benefit_wizard"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-plus-circle"
|
||||
attrs="{'invisible': [('show_add_benefit_button', '=', False)]}"
|
||||
groups="odex_takaful.group_kufula_user"/>
|
||||
<button name="action_view_replacement_wizard"
|
||||
string="Orphan Replacement"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-exchange"
|
||||
attrs="{'invisible': [('show_replaced_button', '=', False)]}"
|
||||
groups="odex_takaful.group_orphan_replacement"/>
|
||||
|
||||
<!-- <button name="action_register_payment"
|
||||
string="Register Payment"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
attrs="{'column_invisible': [('parent.state', 'not in', ['confirmed', 'wait_pay'])], 'invisible': ['|', ('direct_debit', '=', True), ('state', 'in', ['paid', 'active', 'waiting'])]}"/> -->
|
||||
|
||||
</tree>
|
||||
<form string="Donation Details">
|
||||
<header>
|
||||
<button string="Add Benefit"
|
||||
name="add_benefit_wizard"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-plus-circle"
|
||||
attrs="{'invisible': [('show_add_benefit_button', '=', False)]}"
|
||||
groups="odex_takaful.group_kufula_user"/>
|
||||
<button name="action_view_replacement_wizard"
|
||||
string="Orphan Replacement"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
icon="fa-exchange"
|
||||
attrs="{'invisible': [('show_replaced_button', '=', False)]}"
|
||||
groups="odex_takaful.group_orphan_replacement"/>
|
||||
<button name="action_extend_sponsorship"
|
||||
string="Extend"
|
||||
type="object"
|
||||
class="btn-success"
|
||||
icon="fa-plus-circle"
|
||||
attrs="{'invisible': [('show_extend_button', '=', False)]}"/>
|
||||
</header>
|
||||
<group>
|
||||
<group>
|
||||
<field name="ages" invisible="1"/>
|
||||
<field name="waiting_date" invisible="1" widget="date"/>
|
||||
<field name="family_id"
|
||||
attrs="{'invisible': [('sponsorship_type','=','group'), ('parent.record_type','=','sponsorship')],
|
||||
'readonly': ['|', ('sponsorship_type', '!=', 'group'), ('parent.record_type','!=','donation')],
|
||||
'required': [('hide_beneficiary_group','=', False),('sponsorship_type', '=','group'), ('parent.record_type','=','donation')]}"
|
||||
groups="odex_takaful.sponsorship_system_manager_group"/>
|
||||
<field name="display_type" invisible="1"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="show_extend_button" invisible="1"/>
|
||||
<field name="show_replaced_button" invisible="1"/>
|
||||
<field name="show_add_benefit_button" invisible="1"/>
|
||||
<field name="sequence_no" invisible="1"/>
|
||||
<field name="donation_type" invisible="1"/>
|
||||
<field name="direct_debit" invisible="1"/>
|
||||
<field name="hide_beneficiary_group" invisible="1"/>
|
||||
<field name="payment_option" invisible="1"/>
|
||||
<field name="record_type" invisible="1"/>
|
||||
<field name="sponsorship_duration"
|
||||
attrs="{'invisible': [('record_type','!=','sponsorship')], 'required': [('record_type','=','sponsorship')]}"/>
|
||||
<field name="product_template_id"
|
||||
options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/>
|
||||
<field name="payment_month_count_visibility" invisible="1"/>
|
||||
<field name="direct_debit"
|
||||
attrs="{'invisible': [('sponsorship_duration','=','permanent')]}"/>
|
||||
<field name="payment_month_count"
|
||||
attrs="{'invisible': [('payment_month_count_visibility','!=', True)], 'required': [('direct_debit', '=', True)]}"/>
|
||||
<field name="donation_types"
|
||||
invisible="1"/>
|
||||
<field name="sponsor_id" invisible="1"/>
|
||||
<field name="direct_debit_partner_bank_id"
|
||||
context="{'form_view_ref': 'odex_takaful.res_partner_bank_view_form_quick_create', 'default_partner_id': sponsor_id}"
|
||||
attrs="{'invisible': ['|', ('payment_month_count_visibility','!=', True),('direct_debit', '=', False)], 'required': [('direct_debit', '=', True)]}"/>
|
||||
<field name="journal_id"
|
||||
attrs="{'invisible': ['|', ('payment_month_count_visibility','!=', True),('direct_debit', '=', False)], 'required': [('direct_debit', '=', True)]}"/>
|
||||
|
||||
<field name="debit_payment_file_attachment" widget="binary"
|
||||
filename="debit_payment_attachment_file_name"
|
||||
attrs="{'required': [('direct_debit', '=', True)], 'invisible': ['|', ('payment_month_count_visibility','!=', True),('direct_debit', '=', False)]}"/>
|
||||
<field name="debit_payment_attachment_file_name" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="start_date" string="Start Date" widget="date"
|
||||
attrs="{'invisible': [('payment_month_count_visibility','!=', True)], 'required': [('direct_debit', '=', True)], 'readonly': [('direct_debit', '=', False)],}"/>
|
||||
<field name="end_date" string="End Date" widget="date" readonly="1"
|
||||
attrs="{'invisible': [('payment_month_count_visibility','!=', True)]}"/>
|
||||
<field name="donation_mechanism" invisible="1" force_save="1"/>
|
||||
<field name="fixed_value" invisible="1"/>
|
||||
<field name="donation_qty" force_save="1" invisible="1"/>
|
||||
<field name="donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'readonly':[('fixed_value','=',True)]}"
|
||||
force_save="1" required="1"/>
|
||||
<field name="total_months_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'invisible':[('payment_month_count_visibility','=', False)]}"/>
|
||||
<field name="benefits_count"
|
||||
attrs="{'invisible':['|', ('sponsorship_type','!=','group'), ('record_type','!=','sponsorship')]}"/>
|
||||
<field name="total_donation_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"
|
||||
attrs="{'invisible':['|', ('sponsorship_type','!=','group'), ('record_type','!=','sponsorship')]}"
|
||||
force_save="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="benefit_type"
|
||||
invisible="1"/>
|
||||
<!-- attrs="{'invisible': [('donation_mechanism','!=','with_conditions')]}"/>-->
|
||||
</group>
|
||||
<field name="name"/>
|
||||
<field name="sponsorship_type" widget="radio" nolabel="1"
|
||||
options="{'horizontal': true}"
|
||||
invisible="1"/>
|
||||
<!-- attrs="{'invisible': [('donation_mechanism','!=','with_conditions')], 'required': [('hide_beneficiary_group','=', False), ('donation_mechanism','=','with_conditions')]}"/>-->
|
||||
<field name="members_domain_ids" invisible="1"/>
|
||||
<field name="family_domain_ids" invisible="1"/>
|
||||
<field name="benefit_id"
|
||||
invisible="1"
|
||||
options="{'no_create': True, 'no_create_edit':True}"/>
|
||||
|
||||
</group>
|
||||
<notebook>
|
||||
<!-- <page string="Orphans List" autofocus="autofocus"-->
|
||||
<!-- attrs="{'invisible': ['|', '|', '|', ('hide_beneficiary_group','=', True), ('parent.record_type','!=','sponsorship'), ('sponsorship_type', '!=', 'group'), ('benefit_type', '!=', 'orphan')]}">-->
|
||||
<!-- <field name="benefit_ids" nolabel="1">-->
|
||||
<!-- <tree editable="bottom">-->
|
||||
<!-- <field name="name"/>-->
|
||||
<!-- <field name="age"/>-->
|
||||
<!-- <field name="member_status"/>-->
|
||||
<!-- </tree>-->
|
||||
<!-- </field>-->
|
||||
<!-- </page>-->
|
||||
|
||||
<!-- <page string="Widows List"-->
|
||||
<!-- attrs="{'invisible': ['|', '|', '|', ('hide_beneficiary_group','=', True), ('parent.record_type','!=','sponsorship'), ('sponsorship_type', '!=', 'group'), ('benefit_type', '!=', 'widow')]}">-->
|
||||
<!-- <field name="benefit_ids" nolabel="1">-->
|
||||
<!-- <tree editable="bottom">-->
|
||||
<!-- <field name="name"/>-->
|
||||
<!-- <field name="age"/>-->
|
||||
<!-- <field name="member_status"/>-->
|
||||
<!-- </tree>-->
|
||||
<!-- </field>-->
|
||||
<!-- </page>-->
|
||||
|
||||
<page string="Orphans and Widows List"
|
||||
attrs="{'invisible': ['|',('sponsorship_type', '!=', 'group'), ('hide_beneficiary_group', '=', True)]}">
|
||||
<!-- attrs="{'invisible': ['|', '|', '|', ('hide_beneficiary_group','=', True), ('parent.record_type','!=','sponsorship'), ('sponsorship_type', '!=', 'group'), ('benefit_type', '!=', 'both')]}">-->
|
||||
<field name="benefit_ids" nolabel="1" options="{'no_create': True}">
|
||||
<tree editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="age"/>
|
||||
<field name="member_status"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Beneficiary Filters" autofocus="false"
|
||||
invisible="1">
|
||||
<group>
|
||||
<group>
|
||||
<field name="gender"
|
||||
invisible="1"/>
|
||||
<!-- attrs="{'invisible': [('donation_mechanism','!=','with_conditions')]}"/>-->
|
||||
<field name="age_category_id"
|
||||
invisible="1"/>
|
||||
<field name="education_status"
|
||||
invisible="1"/>
|
||||
<field name="education_level"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')]}"/>
|
||||
<field name="benefit_id_number"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')]}"/>
|
||||
<field name="benefit_family_code"
|
||||
attrs="{'invisible': [('donation_mechanism','!=','with_conditions')]}"/>
|
||||
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
|
||||
</form>
|
||||
</field>
|
||||
|
||||
<group class="oe_subtotal_footer oe_right" colspan="2"
|
||||
name="donation_total">
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="total_sponsorship_amount" string="Total Amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="donations_count"/>
|
||||
</group>
|
||||
<button name="donation_catelog" type="object" string="Donation Catalog"
|
||||
class="btn-primary" icon="fa-shopping-cart"
|
||||
attrs="{'invisible': ['|', '|', ('state', '!=', 'draft'), ('record_type', '!=', 'donation'), ('donation_mechanism', '!=', 'without_conditions')]}"/>
|
||||
<div class="oe_clear"/>
|
||||
|
||||
|
||||
</page>
|
||||
<page string="Payment Details"
|
||||
attrs="{'invisible': [('state', '=', 'draft')]}"
|
||||
groups="odex_takaful.group_refund_approval">
|
||||
<field name="payment_ids" readonly="1"
|
||||
context="{'tree_view_ref': 'account.view_account_payment_tree'}"/>
|
||||
</page>
|
||||
|
||||
|
||||
<page string="Refund Details"
|
||||
attrs="{'invisible': [('state', 'not in', ('approve_refund','under_refund','partial_refund','fully_refund'))]}">
|
||||
<field name="refund_details_lines_ids" mode="tree"
|
||||
options="{'no_open': True}" readonly="1">
|
||||
<tree create="false" delete="false" edit="false">
|
||||
<field name="refund_date"/>
|
||||
<field name="payment_details_line"/>
|
||||
<field name="refund_reason"/>
|
||||
<field name="payment_method_id"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="refund_amount" widget="monetary"
|
||||
options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="journal_id"/>
|
||||
<field name="attachment_ids"
|
||||
widget="many2many_attachment_preview"/>
|
||||
<field name="sponsorship_scheduling_line" invisible="1"/>
|
||||
<field name="sponsorship_scheduling_line_ids" invisible="1"/>
|
||||
<field name="sponsorship_id" invisible="1"/>
|
||||
<field name="invoiced" invisible="1"/>
|
||||
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</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 id="takaful_sponsorship_tree" model="ir.ui.view">
|
||||
<field name="name">takaful.sponsorship.tree</field>
|
||||
<field name="model">takaful.sponsorship</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sponsorship List" decoration-danger="has_delay==True">
|
||||
<field name="has_delay" invisible="1"/>
|
||||
<field name="code"/>
|
||||
<field name="create_uid"/>
|
||||
<field name="sponsorship_creation_date"/>
|
||||
<field name="record_type"/>
|
||||
<field name="branch_custom_id"/>
|
||||
<field name="sponsor_or_donor_type"/>
|
||||
<field name="registered_type"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="sponsor_name" string="Unregistered Sponsor Name" optional="show"/>
|
||||
<field name="total_sponsorship_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="state" widget="badge"
|
||||
decoration-muted="state == 'draft'"
|
||||
decoration-warning="state in ['confirmed', 'wait_pay', 'approve_refund']"
|
||||
decoration-success="state == 'paid'"
|
||||
decoration-danger="state in ['canceled', 'fully_refund']"
|
||||
decoration-info="state in ['closed', 'replacement_done', 'partial_refund', 'under_refund', 'under_replacement']"/>
|
||||
<!-- <field name="code" />
|
||||
<field name="sponsorship_duration"/>
|
||||
<field name="sponsorship_type"/>
|
||||
<field name="benefit_type"/>
|
||||
<field name="contribution_value" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="end_date" widget="date"/>
|
||||
<field name="overdue_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/> -->
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- All actions -->
|
||||
<record id="takaful_sponsorship_action" model="ir.actions.act_window">
|
||||
<field name="name">The Sponsorship</field>
|
||||
<field name="res_model">takaful.sponsorship</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<record id="takaful_sponsorship_view_search" model="ir.ui.view">
|
||||
<field name="name">takaful.sponsorship.view.search</field>
|
||||
<field name="model">takaful.sponsorship</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Takaful SponsorShip Search">
|
||||
<field name="code"/>
|
||||
<field name="create_uid"/>
|
||||
<field name="sponsorship_creation_date" widget="datetime"/>
|
||||
<field name="record_type"/>
|
||||
<field name="branch_custom_id"/>
|
||||
<field name="sponsor_or_donor_type"/>
|
||||
<field name="registered_type"/>
|
||||
<field name="sponsor_id"/>
|
||||
<field name="total_sponsorship_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="state"/>
|
||||
<separator/>
|
||||
<!-- State Filters -->
|
||||
<filter string="Draft" name="filter_draft" domain="[('state', '=', 'draft')]"/>
|
||||
<filter string="Confirmed" name="filter_confirmed" domain="[('state', '=', 'confirmed')]"/>
|
||||
<filter string="Enter Payment Details" name="filter_wait_pay" domain="[('state', '=', 'wait_pay')]"/>
|
||||
<filter string="Paid" name="filter_paid" domain="[('state', '=', 'paid')]"/>
|
||||
<filter string="Partial Refund" name="filter_partial_refund"
|
||||
domain="[('state', '=', 'partial_refund')]"/>
|
||||
<filter string="Fully Refund" name="filter_fully_refund" domain="[('state', '=', 'fully_refund')]"/>
|
||||
<filter string="Approve Refund" name="filter_approve_refund"
|
||||
domain="[('state', '=', 'approve_refund')]"/>
|
||||
<filter string="Under Refund Procedure" name="filter_under_refund"
|
||||
domain="[('state', '=', 'under_refund')]"/>
|
||||
<filter string="Under Replacement" name="filter_under_replacement"
|
||||
domain="[('state', '=', 'under_replacement')]"/>
|
||||
<filter string="Replacement Done" name="filter_replacement_done"
|
||||
domain="[('state', '=', 'replacement_done')]"/>
|
||||
<filter string="Canceled" name="filter_canceled" domain="[('state', '=', 'canceled')]"/>
|
||||
<filter string="Closed" name="filter_closed" domain="[('state', '=', 'closed')]"/>
|
||||
<separator/>
|
||||
<!-- Record Type Filters -->
|
||||
<filter string="Sponsorship" name="filter_sponsorship" domain="[('record_type', '=', 'sponsorship')]"/>
|
||||
<filter string="Donation" name="filter_donation" domain="[('record_type', '=', 'donation')]"/>
|
||||
<separator/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter name="create_uid" context="{'group_by':'create_uid'}"/>
|
||||
<filter name="record_type" context="{'group_by':'record_type'}"/>
|
||||
<filter name="branch_custom_id" context="{'group_by':'branch_custom_id'}"/>
|
||||
<filter name="sponsor_or_donor_type"
|
||||
context="{'group_by':'sponsor_or_donor_type'}"/>
|
||||
<filter name="registered_type" context="{'group_by':'registered_type'}"/>
|
||||
<filter name="sponsor_id" context="{'group_by':'sponsor_id'}"/>
|
||||
<filter name="state" context="{'group_by':'state'}"/>
|
||||
</group>
|
||||
<separator/>
|
||||
<searchpanel>
|
||||
<field name="state" enable_counters="1"/>
|
||||
<field name="record_type" enable_counters="1"/>
|
||||
</searchpanel>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--print_report
|
||||
method is called from server action-->
|
||||
<record id="action_makfuleen_report" model="ir.actions.server">
|
||||
<field name="name">Makfuleen Report</field>
|
||||
<field name="type">ir.actions.server</field>
|
||||
<field name="model_id" ref="model_takaful_sponsorship"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">
|
||||
action = model.print_makfuleen_report()
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="takaful_sponsor_operation_form">
|
||||
<field name="name">partner.sponsor.operation.form</field>
|
||||
<field name="model">takaful.sponsor.operation</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sponsor Operations" delete="false">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="origin_id" invisible="1" />
|
||||
<field name="sponsor_id" readonly="1" />
|
||||
<field name="name" readonly="1" />
|
||||
<field name="operation_type" readonly="1" />
|
||||
<field name="title" readonly="1" />
|
||||
<field name="benefit_id" attrs="{'invisible': [('benefit_ids','=', False)]}" />
|
||||
<field name="benefit_ids"
|
||||
attrs="{'invisible': [('benefit_id','!=', False)]}" />
|
||||
<field name="benefit_type" readonly="1" />
|
||||
|
||||
<field name="month" invisible="1" />
|
||||
<field name="period_code" invisible="1" />
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="amount" widget="monetary" options="{'currency_field': 'currency_id'}" readonly="1" />
|
||||
<field name="date" widget="date" invisible="1" />
|
||||
<field name="operation_on" widget="datetime" readonly="1" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="takaful_sponsor_operation_tree">
|
||||
<field name="name">takaful.sponsor.operation.tree</field>
|
||||
<field name="model">takaful.sponsor.operation</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sponsor Operations List">
|
||||
<field name="name" />
|
||||
<field name="title" />
|
||||
<field name="operation_type" />
|
||||
<field name="sponsor_id" />
|
||||
<field name="benefit_type" />
|
||||
<field name="amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="date" widget="date"/>
|
||||
<field name="operation_on" widget="datetime"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="takaful_sponsor_operation_search">
|
||||
<field name="name">takaful.sponsor.operation.search</field>
|
||||
<field name="model">takaful.sponsor.operation</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name" />
|
||||
<field name="title" />
|
||||
<field name="operation_type" />
|
||||
<field name="sponsor_id" />
|
||||
<field name="benefit_type" />
|
||||
<field name="amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="date" widget="date"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="takaful_sponsor_operation_action">
|
||||
<field name="name">Sponsor Operation</field>
|
||||
<field name="res_model">takaful.sponsor.operation</field>
|
||||
<!-- <field name="view_type">form</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">No Any Sponsor Operations
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
<record id="takaful_sponsor_sequence" model="ir.sequence">
|
||||
<field name="name">Takaful Sponsor Sequence</field>
|
||||
<field name="code">takaful.sponsor.sequence</field>
|
||||
<field name="prefix">S/</field>
|
||||
<field name="padding">4</field>
|
||||
<field eval="1" name="number_next"/>
|
||||
<field eval="1" name="number_increment"/>
|
||||
</record>
|
||||
|
||||
<record id="takaful_sponsor_tree" model="ir.ui.view">
|
||||
<field name="name">partner.sponsor.tree</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Sponsors List" decoration-danger="active==False">
|
||||
<field name="name"/>
|
||||
<field name="company_type"/>
|
||||
<field name="mobile"/>
|
||||
<field name="id_number"/>
|
||||
<field name="city_id"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="active" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_takaful_sponsor_form" model="ir.ui.view">
|
||||
<field name="name">partner.sponsor.form</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="The sponsor" create="false">
|
||||
<header>
|
||||
<button name="action_unlink_sponsor_and_related" string="Unlink Partners" type="object"
|
||||
groups="base.group_no_one" invisible="1"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<separator string="Inactive" style="color: red;" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_type" invisible="1"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
<field name="country_id" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="type" invisible="1"/>
|
||||
<field name="lang" invisible="1"/>
|
||||
|
||||
<div name="button_box" class="oe_button_box" attrs="{'invisible': [('id', '=', False)]}">
|
||||
<button class="oe_stat_button" type="object" name="view_sponsorship_action" icon="fa-dollar">
|
||||
<field string="Kafalat" name="kafalat_count" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_stat_button" type="object" name="action_open_benefit_records" icon="fa-users">
|
||||
<field string="Benefits" name="related_benefits_count" widget="statinfo"/>
|
||||
</button>
|
||||
<!-- <button class="oe_stat_button" name="_compute_contribution_count" type="action"
|
||||
icon="fa-money">
|
||||
<field string="Contributions" name="contribution_count" widget="statinfo"/>
|
||||
</button>
|
||||
|
||||
<button class="oe_stat_button" name="_compute_gift_count" type="action" icon="fa-gift">
|
||||
<field string="Gifts" name="gift_count" widget="statinfo"/>
|
||||
</button>
|
||||
|
||||
<button name="action_open_sponsor_operation" type="object" class="oe_stat_button" icon="fa-history">
|
||||
<field string=" Operations Records" name="operation_count" widget="statinfo"/>
|
||||
</button> -->
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="oe_title" style="margin:10px;" invisible="1">
|
||||
<h4>
|
||||
<field name="serial_code" readonly="1"/>
|
||||
</h4>
|
||||
<h2>
|
||||
<field name="name" placeholder="Name"
|
||||
attrs="{'readonly': [('company_type', '=', 'person')]}" force_save="1"/>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<group attrs="{'invisible': [('company_type', '!=', 'person')]}">
|
||||
<div class="o_row">
|
||||
<field placeholder="اللقب" name="title" class="oe_inline" nolabel="1" style="width: 20%;"
|
||||
domain="[('position', 'in', ['prefix','both'])]"
|
||||
options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/>
|
||||
<field placeholder="الاسم" name="first_name" class="oe_inline" nolabel="1" style="width: 60%;" required="1"/>
|
||||
<field placeholder="العبارة الختامية" name="suffix_title_id" class="oe_inline" nolabel="1" style="width: 20%;"
|
||||
domain="[('position', 'in', ['suffix','both'])]"
|
||||
options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<field name="kafel_id" readonly="1" invisible="1"/>
|
||||
</group>
|
||||
<group name="group_top">
|
||||
<group name="group_main" colspan="2">
|
||||
<field name="mobile" string="رقم الجوال" widget="phone" placeholder="05xxxxxxxx" attrs="{'required': [('parent_id', '=', False)]}" />
|
||||
<field name="preferred_communication" string="طريقة التواصل المفضلة" required="1"/>
|
||||
<field name="gender" attrs="{'required': [('company_type', '=', 'person')],'invisible': [('company_type', '!=', 'person')]}"/>
|
||||
<field name="street" attrs="{'invisible': [('company_type', '=', 'person')]}"/>
|
||||
<field name="zip" attrs="{'invisible': [('company_type', '=', 'person')]}"/>
|
||||
<field name="email"/>
|
||||
<field name="id_number" attrs="{'invisible': [('company_type', '!=', 'person')]}"/>
|
||||
<field name="branch_custom_id"/>
|
||||
<field name="city_id" invisible="1"/>
|
||||
<field name="district_id" invisible="1"/>
|
||||
<field name="user_id" invisible="1" options="{'no_create': True, 'no_create_edit':True}"
|
||||
readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Related Donors" name="related_donors" autofocus="autofocus" invisible="context.get('default_type') == 'other'" >
|
||||
<field name="child_ids" mode="kanban" context="{'form_view_ref': 'odex_takaful.view_takaful_sponsor_form', 'default_parent_id': active_id, 'default_street': street, 'default_city_id': city_id, 'default_zip': zip, 'default_country_id': country_id, 'default_lang': lang, 'default_type': 'other', 'default_user_id': user_id, 'default_is_donor': True, 'default_is_sponsor_portal': True}">
|
||||
<kanban>
|
||||
<field name="id"/>
|
||||
<field name="color"/>
|
||||
<field name="name"/>
|
||||
<field name="title"/>
|
||||
<field name="type"/>
|
||||
<field name="email"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="is_company"/>
|
||||
<field name="function"/>
|
||||
<field name="phone"/>
|
||||
<field name="street"/>
|
||||
<field name="street2"/>
|
||||
<field name="zip"/>
|
||||
<field name="city"/>
|
||||
<field name="country_id"/>
|
||||
<field name="mobile"/>
|
||||
<field name="state_id"/>
|
||||
<field name="image_128"/>
|
||||
<field name="lang"/>
|
||||
<!-- fields in form x2many view to diminish requests -->
|
||||
<field name="comment"/>
|
||||
<field name="display_name"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<t t-set="color" t-value="kanban_color(record.color.raw_value)"/>
|
||||
<div t-att-class="color + (record.title.raw_value == 1 ? ' oe_kanban_color_alert' : '') + ' oe_kanban_global_click'">
|
||||
<div class="o_kanban_image">
|
||||
<img alt="Contact image" t-if="record.image_128.raw_value"
|
||||
t-att-src="kanban_image('res.partner', 'image_128', record.id.raw_value)"/>
|
||||
<t t-if="!record.image_128.raw_value">
|
||||
<img alt="Delivery" t-if="record.type.raw_value === 'delivery'"
|
||||
t-att-src="_s + "/base/static/img/truck.png""/>
|
||||
<img alt="Invoice" t-if="record.type.raw_value === 'invoice'"
|
||||
t-att-src="_s + "/base/static/img/money.png""/>
|
||||
<t t-if="record.type.raw_value !== 'invoice' && record.type.raw_value !== 'delivery'">
|
||||
<img alt="Logo" t-if="record.is_company.raw_value === true"
|
||||
t-att-src="_s + "/base/static/img/company_image.png""/>
|
||||
<img alt="Avatar"
|
||||
t-if="record.is_company.raw_value === false"
|
||||
t-att-src="_s + "/base/static/img/avatar_grey.png""/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<div class="oe_kanban_details">
|
||||
<field name="name"/>
|
||||
<div t-if="record.function.raw_value">
|
||||
<field name="function"/>
|
||||
</div>
|
||||
<div t-if="record.email.raw_value">
|
||||
<field name="email" widget="email"/>
|
||||
</div>
|
||||
<div t-if="record.type.raw_value != 'contact'">
|
||||
<div>
|
||||
<field name="zip"/>
|
||||
<field name="city"/>
|
||||
</div>
|
||||
<field t-if="record.state_id.raw_value" name="state_id"/>
|
||||
<field name="country_id"/>
|
||||
</div>
|
||||
<div t-if="record.phone.raw_value">Phone:
|
||||
<t t-esc="record.phone.value"/>
|
||||
</div>
|
||||
<div t-if="record.mobile.raw_value">Mobile:
|
||||
<t t-esc="record.mobile.value"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</page>
|
||||
|
||||
</notebook>
|
||||
</sheet>
|
||||
<footer>
|
||||
<button name="action_save_and_close" string="حفظ وإغلاق" type="object" class="btn-primary"/>
|
||||
<button string="تجاهل" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- All actions -->
|
||||
<record id="takaful_sponsor_action" model="ir.actions.act_window">
|
||||
<field name="name">The Sponsor</field>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('is_sponsor_portal', '=', True), ('company_type', '=', 'person')]</field>
|
||||
<field name="context">
|
||||
{
|
||||
'default_company_type': 'person',
|
||||
'default_is_sponsor_portal': True,
|
||||
'default_is_donor': True,
|
||||
'sponsor_contact': True
|
||||
}
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_takaful_sponsor_action_form" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="act_window_id" ref="takaful_sponsor_action"/>
|
||||
<field name="view_id" ref="view_takaful_sponsor_form"/>
|
||||
</record>
|
||||
|
||||
<record id="action_takaful_sponsor_action_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="act_window_id" ref="takaful_sponsor_action"/>
|
||||
<field name="view_id" ref="takaful_sponsor_tree"/>
|
||||
</record>
|
||||
|
||||
<record id="active_sponsor_report_pivot_view" model="ir.ui.view">
|
||||
<field name="name">active.sponsors.count.pivot</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Active Sponsors Count" disable_linking="True">
|
||||
<field name="active_counts" type="col"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_active_sponsor_report" model="ir.actions.server">
|
||||
<field name="name">Active Sponsors Count</field>
|
||||
<field name="type">ir.actions.server</field>
|
||||
<field name="model_id" ref="base.model_res_partner"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">
|
||||
action = model.show_active_sponsor_report_report()
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Unarchive Sponsor -->
|
||||
<record id="activate_sponsor_multi" model="ir.actions.server">
|
||||
<field name="name">Make Active</field>
|
||||
<field name="binding_model_id" ref="base.model_res_partner"/>
|
||||
<field name="model_id" ref="base.model_res_partner"/>
|
||||
<field name='groups_id' eval="[(4, ref('odex_takaful.group_can_activate_sponsor'))]"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">records.on_activate_sponsor_multi()</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import takaful_reports_wizards
|
||||
from . import benefit_month_payment_wiz
|
||||
from . import refund_payment_wizard
|
||||
from . import add_details_wizard
|
||||
from . import orphan_replacement_wizard
|
||||
from . import transfer_deduction_wizard
|
||||
from . import donation_extension_wizard
|
||||
from . import replace_sponsor_wizard
|
||||
from . import add_benefit_wizard
|
||||
from . import account_payment_register
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
from odoo import api, fields, models, _
|
||||
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AccountRegisterPayment(models.TransientModel):
|
||||
_inherit = 'account.payment.register'
|
||||
|
||||
@api.model
|
||||
def _default_payment_method_id(self):
|
||||
payment_method = self.env['takaful.payment.method'].sudo().search(
|
||||
[('payment_method', '=', 'cash')],
|
||||
limit=1
|
||||
)
|
||||
return payment_method.id if payment_method else False
|
||||
|
||||
takaful_sponsorship_id = fields.Many2one('takaful.sponsorship')
|
||||
takaful_payment_method_id = fields.Many2one('takaful.payment.method', string="Payment Method", required=True, default=_default_payment_method_id)
|
||||
takaful_payment_method = fields.Selection([
|
||||
("cash", "Cash"),
|
||||
("bank", "Bank Transfer"),
|
||||
("direct_debit", "Direct Debit"),
|
||||
("check", "Check"),
|
||||
("network", "Network"),
|
||||
],
|
||||
compute="_compute_takaful_payment_method", string="Payment Method")
|
||||
is_refund_sponsorship = fields.Boolean(string='Is Refund Sponsorship')
|
||||
transaction_file_attachment = fields.Binary(string='Transaction Attachment', attachment=False)
|
||||
transaction_attachment_file_name = fields.Char('Transaction File Name', required=False)
|
||||
payment_method = fields.Selection(selection=[("cash", "Cash"), ("bank", "Bank Transfer"), ("check", "Check")], string="Payment Method", required=True, default="cash")
|
||||
machine_id = fields.Many2one('geidea.terminals' , 'الماكينة')
|
||||
check_number = fields.Char(string='Check Number')
|
||||
check_due_date = fields.Date(string='Check Due Date')
|
||||
sponsorship_payment = fields.Boolean(string='Sponsorship Payment', default=False)
|
||||
|
||||
|
||||
@api.onchange("machine_id")
|
||||
def onchange_machine_id(self):
|
||||
for rec in self:
|
||||
if rec.machine_id:
|
||||
rec.journal_id = rec.machine_id.journal_id
|
||||
@api.onchange("takaful_payment_method_id")
|
||||
def onchange_takaful_payment_method_id(self):
|
||||
for rec in self:
|
||||
if rec.takaful_payment_method_id and rec.takaful_payment_method_id.journal_id:
|
||||
rec.journal_id = rec.takaful_payment_method_id.journal_id.id
|
||||
payment_method = rec.takaful_payment_method_id.payment_method
|
||||
j_type = ""
|
||||
if payment_method == "cash":
|
||||
j_type = "cash"
|
||||
elif payment_method in ("bank", "check","network"):
|
||||
j_type = "bank"
|
||||
if j_type:
|
||||
return {"domain": {"journal_id": [("type", "=", j_type)]}}
|
||||
|
||||
|
||||
@api.depends('source_amount', 'source_amount_currency', 'source_currency_id', 'company_id', 'currency_id', 'payment_date')
|
||||
def _compute_amount(self):
|
||||
if self.env.context.get('sponsorship_payment_skip_compute_amount'):
|
||||
self.amount = self.amount
|
||||
else:
|
||||
super(AccountRegisterPayment, self)._compute_amount()
|
||||
|
||||
@api.depends('takaful_payment_method_id')
|
||||
def _compute_takaful_payment_method(self):
|
||||
for rec in self:
|
||||
if rec.takaful_payment_method_id:
|
||||
if rec.takaful_payment_method_id.payment_method in ["cash", "direct_debit", "check", "network"]:
|
||||
rec.takaful_payment_method = rec.takaful_payment_method_id.payment_method
|
||||
else:
|
||||
rec.takaful_payment_method = "bank"
|
||||
else:
|
||||
rec.takaful_payment_method = "cash"
|
||||
|
||||
|
||||
def _create_payments(self):
|
||||
sponsorship_line_ids = self.env.context.get('sponsorship_line_ids')
|
||||
sponsorship_lines = self.env['donations.details.lines'].browse(sponsorship_line_ids).filtered(lambda r: r.display_type == False)
|
||||
sponsorship = self.env['takaful.sponsorship'].browse(self.env.context.get('sponsorship_id'))
|
||||
payments = super(AccountRegisterPayment, self)._create_payments()
|
||||
if sponsorship_lines:
|
||||
|
||||
for line in sponsorship_lines:
|
||||
state = ''
|
||||
if line.record_type == 'sponsorship':
|
||||
if not (line.benefit_id | line.benefit_ids):
|
||||
state = 'waiting'
|
||||
elif line.sponsorship_duration == 'temporary':
|
||||
state = 'active'
|
||||
else:
|
||||
state = 'paid'
|
||||
elif line.record_type == 'donation':
|
||||
if line.donation_mechanism == 'with_conditions':
|
||||
state = 'active'
|
||||
else:
|
||||
state = 'paid'
|
||||
line.write({'state': state})
|
||||
if self.env.context.get('schedule_line_payment'):
|
||||
schedule_line = self.env['sponsorship.scheduling.line'].browse(self.env.context.get('schedule_line_id'))
|
||||
schedule_line.sudo().write({'status': 'paid'})
|
||||
all_schedule_lines_paid = schedule_line.donation_detail_linked_id.sponsorship_scheduling_line_ids.filtered(
|
||||
lambda l: l.status == 'paid')
|
||||
if len(all_schedule_lines_paid) == len(
|
||||
schedule_line.donation_detail_linked_id.sponsorship_scheduling_line_ids):
|
||||
schedule_line.donation_detail_linked_id.state = 'paid'
|
||||
if sponsorship.record_type == 'donation' and sponsorship.donation_mechanism == 'with_conditions':
|
||||
benefit_journal_id = self.env.company.kafala_benefit_journal_id.id
|
||||
donation_line = schedule_line.donation_detail_linked_id
|
||||
family_id = donation_line.family_id
|
||||
|
||||
bill_values = {
|
||||
'takaful_sponsorship_id': sponsorship.id,
|
||||
'name': self.env['ir.sequence'].next_by_code('account.move.accrsp'),
|
||||
'move_type': 'in_invoice',
|
||||
'journal_id': benefit_journal_id,
|
||||
'date': fields.Date.today(),
|
||||
'invoice_date': fields.Date.today(),
|
||||
'partner_id': family_id.partner_id.id,
|
||||
'invoice_line_ids': [(0, 0, {
|
||||
'product_id': donation_line.product_id.id,
|
||||
'price_unit': schedule_line.amount,
|
||||
'quantity': 1,
|
||||
'name': _("Benefit Number %s %s") % (donation_line.sequence_no, f"Cheque Number: {self.check_number} Cheque Due Date: {self.check_due_date}" if self.takaful_payment_method == 'check' else " "),
|
||||
'analytic_account_id': sponsorship.branch_custom_id.branch.analytic_account_id.id,
|
||||
})]
|
||||
}
|
||||
|
||||
bill_id = self.env['account.move'].sudo().create(bill_values)
|
||||
for line in bill_id.invoice_line_ids:
|
||||
line.account_id = line._get_computed_account()
|
||||
taxes = line._get_computed_taxes()
|
||||
if taxes and line.move_id.fiscal_position_id:
|
||||
taxes = line.move_id.fiscal_position_id.map_tax(taxes, partner=line.partner_id)
|
||||
line.tax_ids = taxes
|
||||
line.product_uom_id = line._get_computed_uom()
|
||||
bill_id.action_post()
|
||||
for line in sponsorship_lines:
|
||||
if line.record_type != 'sponsorship':
|
||||
continue
|
||||
if line.sponsorship_type == 'group':
|
||||
line.benefit_ids.write({
|
||||
'sponsor_related_id': line.sponsorship_mechanism_id.sponsor_id.id,
|
||||
'sponsorship_id': line.sponsorship_mechanism_id.id,
|
||||
'sponsorship_end_date': line.end_date if line.end_date else False,
|
||||
'kafala_status': 'have_kafala',
|
||||
})
|
||||
if line.sponsorship_type == 'person':
|
||||
line.benefit_id.write({
|
||||
'sponsor_related_id': line.sponsorship_mechanism_id.sponsor_id.id,
|
||||
'sponsorship_id': line.sponsorship_mechanism_id.id,
|
||||
'sponsorship_end_date': line.end_date if line.end_date else False,
|
||||
'kafala_status': 'have_kafala',
|
||||
})
|
||||
line.sponsorship_mechanism_id.sponsor_id.sudo().is_sponsor_portal = True
|
||||
if self.env.context.get('is_direct_debit'):
|
||||
payments.write({'direct_debit': True})
|
||||
payments.move_id.write({
|
||||
'takaful_sponsorship_id': sponsorship.id
|
||||
})
|
||||
|
||||
if self.transaction_file_attachment:
|
||||
self.env['ir.attachment'].sudo().create({
|
||||
'name': f'{"/".join(sponsorship_lines.mapped("sequence_no"))} - {self.takaful_payment_method}',
|
||||
'datas': self.transaction_file_attachment,
|
||||
'res_model': 'account.payment',
|
||||
'res_id': payments[0].id,
|
||||
'type': 'binary',
|
||||
})
|
||||
|
||||
|
||||
return payments
|
||||
|
||||
@api.model
|
||||
def _get_line_batch_key(self, line):
|
||||
res = super(AccountRegisterPayment, self)._get_line_batch_key(line)
|
||||
if self.env.context.get('force_sponsorship_line_partner_id'):
|
||||
res['partner_id'] = self.env.context.get('force_sponsorship_line_partner_id')
|
||||
return res
|
||||
|
||||
def _create_payment_vals_from_wizard(self):
|
||||
res = super(AccountRegisterPayment, self)._create_payment_vals_from_wizard()
|
||||
if self.env.context.get('force_sponsorship_line_partner_id'):
|
||||
res['partner_id'] = self.env.context.get('force_sponsorship_line_partner_id')
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _get_batch_available_partner_banks(self, batch_result, journal):
|
||||
sponsorship_line_ids = self.env.context.get('sponsorship_line_ids')
|
||||
sponsorship_lines = self.env['donations.details.lines'].browse(sponsorship_line_ids).filtered(lambda r: r.display_type == False)
|
||||
|
||||
if sponsorship_lines:
|
||||
return sponsorship_lines.sponsor_id.bank_ids
|
||||
return super(AccountRegisterPayment, self)._get_batch_available_partner_banks(batch_result, journal)
|
||||
|
||||
def action_create_payments(self):
|
||||
res = super(AccountRegisterPayment, self).action_create_payments()
|
||||
|
||||
if self.env.context.get('dont_redirect_to_payments'):
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'title': _('Success'),
|
||||
'message': _('Payment registered successfully'),
|
||||
'type': 'success',
|
||||
'sticky': False,
|
||||
'next': {'type': 'ir.actions.act_window_close'}
|
||||
},
|
||||
}
|
||||
|
||||
return res
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="view_account_payment_register_form" model="ir.ui.view">
|
||||
<field name="name">account.payment.register.inherit.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='amount']" position="after">
|
||||
<field name="is_refund_sponsorship" invisible="1"/>
|
||||
</xpath>
|
||||
<!-- <xpath expr="//field[@name='amount']" position="attributes">-->
|
||||
<!-- <attribute name="attrs">{'readonly':[('group_payment','=',True)]}</attribute>-->
|
||||
<!-- </xpath>-->
|
||||
<xpath expr="//field[@name='journal_id']" position="attributes">
|
||||
<attribute name="attrs">{'readonly':[('is_refund_sponsorship','=',True)]}</attribute>
|
||||
<attribute name="string">Association Journal</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='partner_bank_id']" position="attributes">
|
||||
<attribute name="invisible">context.get('sponsorship_payment')</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='payment_method_line_id']" position="attributes">
|
||||
<attribute name="invisible">context.get('sponsorship_payment')</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='branch_id']" position="attributes">
|
||||
<attribute name="invisible">context.get('sponsorship_payment')</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='payment_date']" position="attributes">
|
||||
<attribute name="readonly">context.get('sponsorship_payment')</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='journal_id']" position="before">
|
||||
<field name="takaful_payment_method_id" attrs="{'invisible': [('sponsorship_payment', '=', False)]}" options="{'no_create': True, 'no_create_edit': True}"/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='partner_bank_id']" position="after">
|
||||
<field name="sponsorship_payment" invisible="1"/>
|
||||
<field name="takaful_payment_method" invisible="1"/>
|
||||
<!-- <field name="payment_method" attrs="{'invisible': [('sponsorship_payment', '=', False)]}"/>-->
|
||||
<field name="payment_method" invisible="1"/>
|
||||
<field name="check_number" attrs="{'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method','!=','check')], 'required': [('sponsorship_payment', '=', True), ('takaful_payment_method','=','check')]}"/>
|
||||
<field name="check_due_date" attrs="{'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method','!=','check')], 'required': [('sponsorship_payment', '=', True), ('takaful_payment_method','=','check')]}"/>
|
||||
<field name="partner_bank_id" context="{'form_view_ref': 'odex_takaful.res_partner_bank_view_form_quick_create', 'default_partner_id': context.get('force_sponsorship_line_partner_id')}" attrs="{'required': [('sponsorship_payment', '=', True), ('takaful_payment_method','=','bank')], 'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method','!=','bank')]}"/>
|
||||
<field name="transaction_file_attachment" widget="binary"
|
||||
filename="transaction_attachment_file_name"
|
||||
attrs="{'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method','not in',['bank', 'check'])], 'required': [('sponsorship_payment', '=', True), ('takaful_payment_method','=','bank')]}"/>
|
||||
<field name="transaction_attachment_file_name" invisible="1"/>
|
||||
</xpath>
|
||||
<!--<xpath expr="//group" position="after">-->
|
||||
<!-- <notebook>-->
|
||||
<!-- <page string="Sub Payments" attrs="{'invisible': [('group_payment', '=', False)]}">-->
|
||||
<!-- <field name="account_payment_register_ids" attrs="{'invisible': [('group_payment', '=', False)]}" nolabel="1">-->
|
||||
<!-- <tree editable="bottom" delete="true" create="true">-->
|
||||
<!-- <field name="sponsorship_payment" invisible="1"/>-->
|
||||
<!-- <field name="takaful_payment_method" invisible="1"/>-->
|
||||
<!-- <field name="available_partner_bank_ids" invisible="1"/>-->
|
||||
<!-- <field name="company_id" invisible="1"/>-->
|
||||
<!-- <field name="takaful_payment_method_id" options="{'no_create': True, 'no_create_edit': True}"/>-->
|
||||
<!-- <field name="journal_id" string="Association Journal"/>-->
|
||||
<!-- <field name="amount"/>-->
|
||||
<!-- <field name="check_number"-->
|
||||
<!-- attrs="{-->
|
||||
<!-- 'invisible': [-->
|
||||
<!-- ('takaful_payment_method','!=','check')-->
|
||||
<!-- ],-->
|
||||
<!-- 'required': [-->
|
||||
<!-- ('takaful_payment_method','=','check')-->
|
||||
<!-- ]-->
|
||||
<!-- }"-->
|
||||
<!-- optional="hide"/>-->
|
||||
<!-- <field name="check_due_date"-->
|
||||
<!-- attrs="{-->
|
||||
<!-- 'invisible': [-->
|
||||
<!-- ('takaful_payment_method','!=','check')-->
|
||||
<!-- ],-->
|
||||
<!-- 'required': [-->
|
||||
<!-- ('takaful_payment_method','=','check')-->
|
||||
<!-- ]-->
|
||||
<!-- }"-->
|
||||
<!-- optional="hide"/>-->
|
||||
<!-- <field name="partner_bank_id"-->
|
||||
<!-- context="{-->
|
||||
<!-- 'form_view_ref': 'odex_takaful.res_partner_bank_view_form_quick_create',-->
|
||||
<!-- 'default_partner_id': context.get('force_sponsorship_line_partner_id')-->
|
||||
<!-- }"-->
|
||||
<!-- attrs="{-->
|
||||
<!-- 'required': [-->
|
||||
<!-- ('takaful_payment_method','=','bank')-->
|
||||
<!-- ],-->
|
||||
<!-- 'invisible': [-->
|
||||
<!-- ('takaful_payment_method','!=','bank')-->
|
||||
<!-- ]-->
|
||||
<!-- }"-->
|
||||
<!-- readonly="0"-->
|
||||
<!-- optional="hide"/>-->
|
||||
<!-- <field name="transaction_file_attachment"-->
|
||||
<!-- widget="binary"-->
|
||||
<!-- filename="transaction_attachment_file_name"-->
|
||||
<!-- attrs="{-->
|
||||
<!-- 'invisible': [-->
|
||||
<!-- ('takaful_payment_method','not in',['bank', 'check'])-->
|
||||
<!-- ],-->
|
||||
<!-- 'required': ['|',-->
|
||||
<!-- ('takaful_payment_method','=','bank'),-->
|
||||
<!-- ('takaful_payment_method','=','check')-->
|
||||
<!-- ]-->
|
||||
<!-- }"-->
|
||||
<!-- optional="hide"/>-->
|
||||
<!-- </tree>-->
|
||||
<!-- </field>-->
|
||||
<!-- </page>-->
|
||||
<!-- </notebook>-->
|
||||
<!-- </xpath>-->
|
||||
<!-- <xpath expr="//footer/button[@name='action_create_payments']" position="after">-->
|
||||
<!-- <button name="action_register_all_lines"-->
|
||||
<!-- type="object"-->
|
||||
<!-- string="Register All Lines"-->
|
||||
<!-- class="btn-secondary"-->
|
||||
<!-- attrs="{'invisible': [('line_ids','=',False)]}"/>-->
|
||||
<!-- </xpath>-->
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class AddBenefitWizard(models.TransientModel):
|
||||
_name = 'add.benefit.wizard'
|
||||
_description = "Add Benefit"
|
||||
|
||||
donation_detail_id = fields.Many2one(
|
||||
'donations.details.lines',
|
||||
string='Donation Detail',
|
||||
readonly=True
|
||||
)
|
||||
members_domain_ids = fields.Many2many('family.member', related='donation_detail_id.members_domain_ids')
|
||||
|
||||
benefit_id = fields.Many2one('family.member', string='Beneficiary Name', ondelete='restrict',
|
||||
domain="[('id', 'in', members_domain_ids)]",required = True, tracking=True)
|
||||
|
||||
def action_add_benefit(self):
|
||||
"""
|
||||
Add Benefit on the donation detail line and post a message to the chatter
|
||||
"""
|
||||
self.ensure_one()
|
||||
|
||||
if not self.donation_detail_id:
|
||||
raise ValidationError(_("No donation detail line found."))
|
||||
|
||||
if not self.benefit_id:
|
||||
raise ValidationError(_("Please select a Benefit."))
|
||||
|
||||
donation_line = self.donation_detail_id
|
||||
new_benefit_name = self.benefit_id.name
|
||||
|
||||
# Get the sponsorship record (could be sponsorship_id or sponsorship_mechanism_id)
|
||||
sponsorship = donation_line.sponsorship_id or donation_line.sponsorship_mechanism_id
|
||||
|
||||
if not sponsorship:
|
||||
raise ValidationError(_("No sponsorship found for this donation detail line."))
|
||||
|
||||
# Update the Benefit on the donation detail line
|
||||
donation_line.write({
|
||||
'benefit_id': self.benefit_id.id,
|
||||
'benefit_ids': [(6, 0, [self.benefit_id.id])],
|
||||
})
|
||||
(donation_line.benefit_id | donation_line.benefit_ids).sudo().write({
|
||||
'sponsor_related_id': donation_line.sponsor_id.id,
|
||||
'kafala_status': 'have_kafala'
|
||||
})
|
||||
|
||||
# Post message to the donation detail line chatter
|
||||
message_body = _(
|
||||
"Add Benefit: %s"
|
||||
) % (new_benefit_name)
|
||||
|
||||
donation_line.message_post(
|
||||
body=message_body,
|
||||
subject=_("Add Benefit"),
|
||||
message_type='notification',
|
||||
)
|
||||
|
||||
_logger.info(
|
||||
"Add Benefit on donation line : %s",
|
||||
new_benefit_name
|
||||
)
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'title': _('Success'),
|
||||
'message': _('Benefit has been successfully %s') % (
|
||||
new_benefit_name
|
||||
),
|
||||
'type': 'success',
|
||||
'sticky': False,
|
||||
'next': {'type': 'ir.actions.act_window_close'}
|
||||
}
|
||||
}
|
||||
|
||||
def action_cancel(self):
|
||||
"""
|
||||
Cancel the wizard
|
||||
"""
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue