[ADD] odex25_benefit: ADD new branch

This commit is contained in:
younes 2025-11-25 12:43:10 +01:00
parent ed54a5fc39
commit e691b65939
19 changed files with 3289 additions and 0 deletions

View File

@ -0,0 +1,161 @@
import http
import json
import re
class client:
auth = ''
base = 'api.taqnyat.sa'
result=''
method=''
json ={}
error =''
def __init__(self, auth):
self.auth = auth
def checkUserInfo(self):
if self.auth:
self.json.update({'auth' : self.auth})
else:
self.error = 'Add Authentication'
return self.error
def sendMsg(self,body, recipients, sender , scheduled ):
self.checkUserInfo()
#getSendMethod
if not self.error:
data = {
'recipients': recipients,
'sender': sender,
'body': body,
'scheduled': scheduled,
}
self.json.update(data)
self.json = json.dumps(self.json)
conn = http.client.HTTPSConnection(self.base)
headers = {
'Authorization': 'Bearer ' + self.auth,
'Content-Type': 'application/json'
}
conn.request("POST", "/v1/messages", self.json, headers)
res = conn.getresponse()
data = res.read()
return data.decode("utf-8")
else:
return self.error
def sendStatus(self ):
self.checkUserInfo()
#getSendMethod
if not self.error:
data = {
}
self.json.update(data)
self.json = json.dumps(self.json)
conn = http.client.HTTPSConnection(self.base)
headers = {
'Authorization': 'Bearer ' + self.auth,
'Content-Type': 'application/json'
}
conn.request("GET", "/system/status", self.json, headers)
res = conn.getresponse()
data = res.read()
return data.decode("utf-8")
else:
return self.error
def balance(self ):
self.checkUserInfo()
#getSendMethod
if not self.error:
data = {
}
self.json.update(data)
self.json = json.dumps(self.json)
conn = http.client.HTTPSConnection(self.base)
headers = {
'Authorization': 'Bearer ' + self.auth,
'Content-Type': 'application/json'
}
conn.request("GET", "/account/balance", self.json, headers)
res = conn.getresponse()
data = res.read()
return data.decode("utf-8")
else:
return self.error
def senders(self ):
self.checkUserInfo()
#getSendMethod
if not self.error:
data = {
}
self.json.update(data)
self.json = json.dumps(self.json)
conn = http.client.HTTPSConnection(self.base)
headers = {
'Authorization': 'Bearer ' + self.auth,
'Content-Type': 'application/json'
}
conn.request("GET", "/v1/messages/senders", self.json, headers)
res = conn.getresponse()
data = res.read()
return data.decode("utf-8")
else:
return self.error
def deleteMsg(self , deleteKey ):
self.checkUserInfo()
#getSendMethod
if not self.error:
data = {
}
self.json.update(data)
self.json = json.dumps(self.json)
conn = http.client.HTTPSConnection(self.base)
headers = {
'Authorization': 'Bearer ' + self.auth,
'Content-Type': 'application/json'
}
conn.request("DELETE", "/v1/messages", self.json, headers)
res = conn.getresponse()
data = res.read()
return data.decode("utf-8")
else:
return self.error
def make_http_response(message):
try:
response = re.sub('(message)\s', '', message)
response = json.loads(response)
except Exception as e:
return {}
dict_response = {
"statusCode": response.get('statusCode', False),
"message": response.get('message', ''),
"totalCount": response.get('totalCount', 0),
"accepted": response.get('accepted', []),
"rejected": response.get('rejected', []),
}
return dict_response

View File

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

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
{
'name': 'Odex Takaful Core Management',
'version': '1',
'license': 'GPL-3',
'category': 'Odex25-Takaful/Odex25-Takaful',
'summary': 'Takaful Management',
'description': """
Takaful Mangement
""",
'author': 'Expert co.Ltd',
'website': 'exp-sa.com',
'depends': ['mail', 'base', 'account'],
'data': [
# 'security/ir.model.access.csv',
'data/server_action.xml',
'views/res_city_view.xml',
'views/config_view.xml',
'views/bank_transfer_payment_view.xml',
'views/takaful_account_move_view.xml',
'views/res_partner_title_views.xml',
'views/menus_and_actions.xml',
],
# 'installable': True,
# 'application': True,
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="action_migrate_partner_account_type" model="ir.actions.server">
<field name="name">Migrate Account Type to Booleans</field>
<field name="model_id" ref="base.model_ir_actions_server"/>
<field name="state">code</field>
<field name="code">
env['res.partner'].migrate_account_type_to_booleans()
</field>
</record>
</data>
</odoo>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,889 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * takaful_core
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-29 08:00+0000\n"
"PO-Revision-Date: 2022-11-29 10:01+0200\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: \n"
"X-Generator: Poedit 3.2.1\n"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_form
msgid "Accept"
msgstr "قبول"
#. module: takaful_core
#: selection:takaful.bank.transfer.payment,state:0
msgid "Accepted"
msgstr "مقبول"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_account_move
msgid "Account Entry"
msgstr "القيد"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_age
#: model:ir.model.fields,field_description:takaful_core.field_res_users_age
msgid "Age"
msgstr "العمر"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_amount
msgid "Amount"
msgstr "المبلغ"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_amount
msgid "Amount With Vat"
msgstr "المبلغ مع ضريبة القيمة المضافة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_amount_without_vat
msgid "Amount Without Vat"
msgstr "المبلغ بدون ضريبة القيمة المضافة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_transfer_attachment
msgid "Attachment"
msgstr "المرفقات"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_bank_id_4032
#: model:ir.model.fields,field_description:takaful_core.field_res_users_bank_id
msgid "Bank"
msgstr "البنك"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_res_partner_bank
#: model:ir.model.fields,field_description:takaful_core.field_res_company_bank_account_count
msgid "Bank Accounts"
msgstr "الحسابات البنكية"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.bank_account_image_add_view
msgid "Bank Image"
msgstr "صورة البنك"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_bank_bank_img
msgid "Bank Img"
msgstr "صورة البنك"
#. module: takaful_core
#: code:addons/takaful_core/models/takaful_account_move.py:48
#: model:ir.actions.act_window,name:takaful_core.act_takaful_bank_transfer_view
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_form
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_search
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_tree
#: selection:takaful.account.move,type:0
#, python-format
msgid "Bank Transfer"
msgstr "التحويل البنكي"
#. module: takaful_core
#: code:addons/takaful_core/models/bank_transfer_payment.py:46
#: code:addons/takaful_core/models/bank_transfer_payment.py:61
#: code:addons/takaful_core/models/bank_transfer_payment.py:71
#: code:addons/takaful_core/models/bank_transfer_payment.py:93
#, python-format
msgid "Bank Transfer State %s"
msgstr "حالة التحويل المصرفي %s"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_order_form_inherit_res_comapny
msgid "Bank account(s)"
msgstr "الحسابات البنكية"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_birth_date
#: model:ir.model.fields,field_description:takaful_core.field_res_users_birth_date
msgid "Birth Date"
msgstr "تاريخ الميلاد"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_form
msgid "Cancel"
msgstr "إلغاء"
#. module: takaful_core
#: selection:takaful.bank.transfer.payment,state:0
msgid "Canceled"
msgstr "ملغية"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:127
#, python-format
msgid "Cannot sending SMS verification %s "
msgstr " %s لم يتم إرسال الرسالة للجوال"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:204
#, python-format
msgid "Cannot sending email verification"
msgstr "لم يتم إرسال البريد الإلكتروني"
#. module: takaful_core
#: code:addons/takaful_core/models/res_partner.py:25
#, python-format
msgid "Charity"
msgstr "جهة خيرية"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_res_city_tree
msgid "Cities"
msgstr "المدن"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_city_id
#: model:ir.model.fields,field_description:takaful_core.field_res_users_city_id
#: model:ir.ui.view,arch_db:takaful_core.view_res_city_form
msgid "City"
msgstr "المدينة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_code
msgid "Code"
msgstr "الرمز"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_note
msgid "Comment"
msgstr "تعليق"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_res_company
msgid "Companies"
msgstr "الشركات"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_company_company_name
msgid "Company Name"
msgstr "اسم الشركة"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_res_partner
msgid "Contact"
msgstr "جهة الاتصال"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_country_id
msgid "Country"
msgstr "دولة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_create_uid
msgid "Created by"
msgstr "أنشئ بواسطة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_create_date
msgid "Created on"
msgstr "أنشئ في"
#. module: takaful_core
#: code:addons/takaful_core/models/takaful_account_move.py:47
#: selection:takaful.account.move,type:0
#, python-format
msgid "Credit Card"
msgstr "بطاقة ائتمانية"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_partner_id
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_partner_id
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_search
msgid "Customer"
msgstr "العميل"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_email
msgid "Customer Email"
msgstr "بريد العميل"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_name_of
msgid "Customer Name"
msgstr "اسم العميل "
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_date
msgid "Date"
msgstr "التاريخ"
#. module: takaful_core
#: code:addons/takaful_core/models/bank_transfer_payment.py:72
#, python-format
msgid "Dear %s,<br/<br/>Your bank transfer has been changed accepted. Please check your balance"
msgstr "عزيزي %s ، <br/<br/> تم تغيير التحويل المصرفي الخاص بك. يرجى التحقق من رصيدك"
#. module: takaful_core
#: code:addons/takaful_core/models/bank_transfer_payment.py:94
#, python-format
msgid "Dear %s,<br/<br/>Your bank transfer has been changed to canceled. Please check with your bank"
msgstr "عزيزي %s ، <br/<br/> تم تغيير التحويل المصرفي الخاص بك إلى إلغاء. يرجى التحقق من البنك الذي تتعامل معه"
#. module: takaful_core
#: code:addons/takaful_core/models/bank_transfer_payment.py:47
#, python-format
msgid "Dear %s,<br/><br/>Your bank transfer has been rejected."
msgstr "عزيزي %s ،<br/><br/> تم رفض التحويل المصرفي الخاص بك."
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:92
#, python-format
msgid ""
"Dear Customer,\n"
" %s is your one time password (OTP). Please enter the OTP to proceed.\n"
" Thank you,\n"
" Team Takaful"
msgstr ""
"عزيزنا العميل,\n"
" %s هو رمز التفعيل. الرجاء إدخال الرمز للمتابعة.\n"
" شكراً جزيلاً,\n"
" جمعية تكافل"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_company_form_inherit_otp
msgid "Default Vat Value"
msgstr "القيمة الافتراضية لضريبة القيمة المضافة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_display_name
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_display_name
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_display_name
msgid "Display Name"
msgstr "الاسم المعروض"
#. module: takaful_core
#: code:addons/takaful_core/models/res_partner.py:53
#: selection:res.partner,marital_status:0
#, python-format
msgid "Divorced"
msgstr "مطلقة"
#. module: takaful_core
#: selection:takaful.bank.transfer.payment,state:0
msgid "Draft"
msgstr "مسودة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_education_institution
#: model:ir.model.fields,field_description:takaful_core.field_res_users_education_institution
msgid "Education Institution"
msgstr "المؤسسة التعليمية"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_education_level
#: model:ir.model.fields,field_description:takaful_core.field_res_users_education_level
msgid "Educational level"
msgstr "مستوى التعليم"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:199
#, python-format
msgid "Email verification is successfully sent"
msgstr "تم ارسال بريد للتحقق بنجاح"
#. module: takaful_core
#: code:addons/takaful_core/models/res_partner.py:91
#, python-format
msgid "Enter a valid Saudi mobile number"
msgstr "أدخل رقم جوال سعودي بشكل صحيح"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:179
#, python-format
msgid "Exceeded the limit, please request after the clock %s"
msgstr "لقد جاوزت الحد المسموح، الرجاء الطلب بعد %s"
#. module: takaful_core
#: code:addons/takaful_core/models/takaful_account_move.py:54
#: selection:takaful.account.move,state:0
#, python-format
msgid "Failed"
msgstr "فشلت"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_family_name
#: model:ir.model.fields,field_description:takaful_core.field_res_users_family_name
msgid "Family Name"
msgstr "اسم العائلة"
#. module: takaful_core
#: selection:res.partner,gender:0
msgid "Female"
msgstr "أنثي"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_filename
msgid "Filename"
msgstr "اسم الملف"
#. module: takaful_core
#: selection:account.invoice,operation_type:0
#: selection:takaful.account.move,operation_type:0
msgid "Financial Donation"
msgstr "تبرعات مالية"
#. module: takaful_core
#: selection:account.invoice,operation_type:0
#: selection:takaful.account.move,operation_type:0
msgid "Financial Gift"
msgstr "إهداء مالي"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_first_name
#: model:ir.model.fields,field_description:takaful_core.field_res_users_first_name
msgid "First Name"
msgstr "الاسم الاول"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_gender
#: model:ir.model.fields,field_description:takaful_core.field_res_users_gender
msgid "Gender"
msgstr "الجنس"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_search
msgid "Group By..."
msgstr "تجميع حسب.."
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_health_status
#: model:ir.model.fields,field_description:takaful_core.field_res_users_health_status
msgid "Health Status"
msgstr "الحالة الصحية"
#. module: takaful_core
#: selection:res.partner,health_status:0
msgid "Healthy"
msgstr "سليم"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_iban
#: model:ir.model.fields,field_description:takaful_core.field_res_users_iban
msgid "IBAN"
msgstr "رقم الآي بان"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_id
msgid "ID"
msgstr "المعرف"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_id_expiry
#: model:ir.model.fields,field_description:takaful_core.field_res_users_id_expiry
msgid "Id Expiry Date"
msgstr "تاريخ انتهاء الهوية"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_id_number
#: model:ir.model.fields,field_description:takaful_core.field_res_users_id_number
msgid "Id Number"
msgstr "رقم الهوية"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_id_number_attach
#: model:ir.model.fields,field_description:takaful_core.field_res_users_id_number_attach
msgid "Id Number Attachment"
msgstr "مرفق الهوية"
#. module: takaful_core
#: selection:res.partner,education_level:0
msgid "Illiterate"
msgstr "أمي"
#. module: takaful_core
#: selection:account.invoice,operation_type:0
#: selection:takaful.account.move,operation_type:0
msgid "In-Kind Donation"
msgstr "تبرعات عينية"
#. module: takaful_core
#: code:addons/takaful_core/models/takaful_account_move.py:53
#: selection:takaful.account.move,state:0
#, python-format
msgid "Initiated"
msgstr "أنشئت"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:252
#, python-format
msgid "Invalid OTP, Reset Password Failed"
msgstr "رمز تفعيل غير صحيح، فشل في تغيير كلمة المرور"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:279
#, python-format
msgid "Invalid OTP, Verification Failed"
msgstr "رمز تفعيل غير صحيح، فشل في عملية التحقق"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:56
#, python-format
msgid "Invalid Saudi mobile number"
msgstr "أدخل رقم جوال سعودي بشكل صحيح"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_account_invoice
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_move_id
msgid "Invoice"
msgstr "الفاتورة"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.takaful_account_move_form
msgid "Invoice Number"
msgstr "رقم الفاتورة"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.takaful_account_move_tree_viewx
msgid "Invoices"
msgstr "الفواتير"
#. module: takaful_core
#: selection:res.partner,education_level:0
msgid "Kindergarten"
msgstr "روضة أطفال"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city___last_update
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move___last_update
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment___last_update
msgid "Last Modified on"
msgstr "آخر تعديل في"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_write_uid
msgid "Last Updated by"
msgstr "آخر تحديث بواسطة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_write_date
msgid "Last Updated on"
msgstr "آخر تحديث في"
#. module: takaful_core
#: selection:res.partner,gender:0
msgid "Male"
msgstr "ذكر"
#. module: takaful_core
#: code:addons/takaful_core/models/res_partner.py:54
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_marital_status
#: model:ir.model.fields,field_description:takaful_core.field_res_users_marital_status
#, python-format
msgid "Marital Status"
msgstr "الحالة الاجتماعية"
#. module: takaful_core
#: code:addons/takaful_core/models/res_partner.py:53
#: selection:res.partner,marital_status:0
#, python-format
msgid "Married"
msgstr "متزوج"
#. module: takaful_core
#: selection:res.partner,education_level:0
msgid "Middle"
msgstr "متوسطة"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:218
#, python-format
msgid "Missing Password Values or OTP"
msgstr "قيم كلمات المرور أو رمز التفعيل غير مكتملة"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:47
#: code:addons/takaful_core/models/res_users.py:153
#, python-format
msgid "Missing mobile number"
msgstr "لايوجد قيمة رقم الجوال"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_company_form_inherit_otp
msgid "Moyaser Integration"
msgstr "التكامل مع خدمة ميسر"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_company_moyaser_public_key
msgid "Moyaser Public Key"
msgstr "مفتاح خدمة ميسر"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_company_form_inherit_otp
msgid "Moyaser Publicy Key"
msgstr "المفتاح العام لخدمة ميسر"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_name
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_name
msgid "Name"
msgstr "الاسم"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_name_of
msgid "Name Of"
msgstr "اسم صاحب الحساب الذي تم التحويل منه"
#. module: takaful_core
#: selection:account.invoice,operation_type:0
#: selection:takaful.account.move,operation_type:0
msgid "Needs Contribution"
msgstr "مساهمة أحتياجات"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_number
msgid "Number"
msgstr "الرقم"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_users_otp
msgid "OTP"
msgstr "رمز التفعيل"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_users_otp_date
msgid "OTP Date"
msgstr "تأريخ رمز التفعيل"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_company_form_inherit_otp
msgid "OTP Information"
msgstr "معلومات رسائل التفعيل"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_company_otp_provider_token
msgid "OTP Provider Token"
msgstr "مفتاح مزود رمز التفعيل"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_users_otp_count
msgid "OTP Request Count"
msgstr "عدد طلبات رمز التفعيل"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_users_otp_password
msgid "OTP Reset Password"
msgstr "أعادة تعيين كلمة السر بواسطة رمز التفعيل"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_company_otp_sender_name
msgid "OTP Sender Name"
msgstr "اسم مرسل رمز التفعيل"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:82
#: code:addons/takaful_core/models/res_users.py:118
#, python-format
msgid "OTP code is successfully sent"
msgstr "لقد تم إرسال رمز التفعيل بنجاح"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:260
#: code:addons/takaful_core/models/res_users.py:295
#, python-format
msgid "OTP does not exist or expired, please request it again"
msgstr "رمز التفعيل غير صالح أو غير موجود، فضلاً أطلبه مرة أخرى"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_operation_id
msgid "Operation"
msgstr "عملية"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_account_invoice_operation_type
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_operation_type
msgid "Operation Type"
msgstr "نوع العملية"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_name
msgid "Order Name"
msgstr "اسم الطلب"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_remote_id
msgid "Order Number"
msgstr "رقم الطلب"
#. module: takaful_core
#: code:addons/takaful_core/models/takaful_account_move.py:56
#: selection:takaful.account.move,state:0
#, python-format
msgid "Paid"
msgstr "مدفوعة"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:247
#, python-format
msgid "Password is successfully reset"
msgstr "تم إعادة تعيين كلمة المرور بنجاح"
#. module: takaful_core
#: model:ir.actions.act_window,name:takaful_core.takaful_account_move_list_action
msgid "Paycards Account Moves"
msgstr "قيود فواتير السداد الإلكتروني"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_form
#: selection:takaful.bank.transfer.payment,state:0
msgid "Pending"
msgstr "معلق"
#. module: takaful_core
#: selection:res.partner,education_level:0
msgid "Postgraduate"
msgstr "دراسات عليا"
#. module: takaful_core
#: selection:res.partner,education_level:0
msgid "Primary"
msgstr "أساس"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_product_product
msgid "Product"
msgstr "المنتج"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_product_template
msgid "Product Template"
msgstr "قالب المنتج"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_company_form_inherit_otp
msgid "Publicy Key"
msgstr "المفتاح العام"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_qty_ordered
msgid "Qty Ordered"
msgstr "الكمية المطلوبة"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_sale_order
msgid "Quotation"
msgstr "التسعيرة"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_form
msgid "Reject"
msgstr "رفض"
#. module: takaful_core
#: code:addons/takaful_core/models/takaful_account_move.py:55
#: selection:takaful.account.move,state:0
#: selection:takaful.bank.transfer.payment,state:0
#, python-format
msgid "Rejected"
msgstr "مرفوض"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_company_form_inherit_otp
msgid "SMS Information"
msgstr "معلومات خدمة الرسائل القصيرة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_company_sms_provider_token
msgid "SMS Provider Token"
msgstr "اسم مزود خدمة الرسائل القصيرة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_company_sms_sender_name
msgid "SMS Sender Name"
msgstr "اسم مرسل الرسائل القصيرة"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:140
#, python-format
msgid "SMS service is unavilable"
msgstr "خدمة الرسائل غير متاحة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_second_name
#: model:ir.model.fields,field_description:takaful_core.field_res_users_second_name
msgid "Second Name"
msgstr "الاسم الثاني"
#. module: takaful_core
#: selection:res.partner,education_level:0
msgid "Secondary"
msgstr "ثانوي"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:131
#, python-format
msgid "Sender information does not exist"
msgstr "معلومات المرسل غير موجود"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_form
msgid "Set Draft"
msgstr "وضع كممسودة"
#. module: takaful_core
#: selection:res.partner,health_status:0
msgid "Sick"
msgstr "مريض"
#. module: takaful_core
#: code:addons/takaful_core/models/res_partner.py:53
#: selection:res.partner,marital_status:0
#, python-format
msgid "Single"
msgstr "عازب"
#. module: takaful_core
#: selection:account.invoice,operation_type:0
#: selection:takaful.account.move,operation_type:0
msgid "Sponsorship"
msgstr "الكفالة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_country_city_state_id
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_state
#: model:ir.ui.view,arch_db:takaful_core.view_takaful_bank_payment_transfer_search
msgid "State"
msgstr "المحافظة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_state
msgid "Status"
msgstr "الحالة "
#. module: takaful_core
#: selection:account.invoice,operation_type:0
#: selection:takaful.account.move,operation_type:0
msgid "Subscription"
msgstr "إشتراكات"
#. module: takaful_core
#: sql_constraint:res.partner:0
msgid "The Email Already Exist!"
msgstr "The Email Already Exist!"
#. module: takaful_core
#: sql_constraint:res.partner:0
msgid "The ID Number Already Exist!"
msgstr "The ID Number Already Exist!"
#. module: takaful_core
#: sql_constraint:res.partner:0
msgid "The Mobile Already Exist!"
msgstr "The Mobile Already Exist!"
#. module: takaful_core
#: sql_constraint:res.partner:0
msgid "The Phone Already Exist!"
msgstr "The Phone Already Exist!"
#. module: takaful_core
#: sql_constraint:res.partner:0
msgid "The User Already Exist!"
msgstr "The User Already Exist!"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:227
#, python-format
msgid "The entered password does not match"
msgstr "كلمة المرور المدخلة غير متطابقة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_partner_middle_name
#: model:ir.model.fields,field_description:takaful_core.field_res_users_middle_name
msgid "Third Name"
msgstr "الاسم الثالث"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_transfer_id
msgid "Transfer"
msgstr "التحويل البنكي"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_bank_transfer_payment_transfer_date
msgid "Transfer Date"
msgstr "Transfer Date"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_type
msgid "Type"
msgstr "النوع"
#. module: takaful_core
#: selection:res.partner,education_level:0
msgid "University"
msgstr "جامعي"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_company_use_otp_login
msgid "Use Otp Login"
msgstr "أستخدام رمز التفعيل للتسجيل"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_company_use_sms_notification
msgid "Use SMS Notifications"
msgstr "تنبيهات عبر الرسائل القصيرة"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_res_users
msgid "Users"
msgstr "المستخدمون"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_takaful_account_move_tax_amount
msgid "Vat"
msgstr "الضريبة المضافة"
#. module: takaful_core
#: model:ir.model.fields,field_description:takaful_core.field_res_company_vat_default_percent
msgid "Vat Percent"
msgstr "نسبة الضريبة المضافة"
#. module: takaful_core
#: code:addons/takaful_core/models/res_users.py:291
#, python-format
msgid "Verification is successful"
msgstr "تم التحقق بنجاح"
#. module: takaful_core
#: code:addons/takaful_core/models/res_partner.py:53
#: selection:res.partner,marital_status:0
#, python-format
msgid "Widower"
msgstr "أرملة"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_res_config_settings
msgid "res.config.settings"
msgstr "الدقة.التكوين.إعدادات"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_res_country_city
msgid "res.country.city"
msgstr "res.country.city"
#. module: takaful_core
#: model:ir.ui.view,arch_db:takaful_core.takaful_account_move_form
msgid "server"
msgstr "الخادم"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_takaful_account_move
msgid "takaful.account.move"
msgstr "takaful.account.move"
#. module: takaful_core
#: model:ir.model,name:takaful_core.model_takaful_bank_transfer_payment
msgid "takaful.bank.transfer.payment"
msgstr "takaful.bank.transfer.payment"

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
from . import res_city
from . import res_partner
from . import res_users
from . import res_config
from . import takaful_account_move
from . import bank_transfer_payment

View File

@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
from odoo.tools.translate import _
# from odoo.tools import SUPERUSER_ID
from datetime import datetime
class CompanyBank(models.Model):
_inherit = 'res.partner.bank'
bank_img = fields.Binary(attachment=True)
class BankPayment(models.Model):
_name = 'takaful.bank.transfer.payment'
_rec_name = 'number'
_order = 'id desc'
number = fields.Char(string='Number', defualt='/', readonly=True)
name = fields.Char(string='Name', required=True)
name_of = fields.Char(string='Name Of')
amount = fields.Float(string='Amount')
partner_id = fields.Many2one(comodel_name='res.partner', string='Customer', required=True)
transfer_attachment = fields.Binary(attachment=True, string='Attachment')
filename = fields.Char(string='Filename', size=256, readonly=True)
state = fields.Selection(selection=[('draft', 'Draft'), ('pending', 'Pending'), ('reject', 'Rejected'),
('accept', 'Accepted'), ('cancel', 'Canceled')], string='State', default='draft')
move_id = fields.Many2one(comodel_name='takaful.account.move', string='Invoice')
transfer_date=fields.Date()
@api.model
def create(self, vals):
res = super(BankPayment, self).create(vals)
res.write({'number': self.env['ir.sequence'].sudo().next_by_code('bank.payment.transfer')})
return res
# @api.multi
def action_pending(self):
self.write({'state': 'pending'})
# @api.multi
def action_rejected(self):
context = {'lang':self.partner_id.lang}
val_msg = {
'name': _("Bank Transfer State %s")%self.number,
'body': _("Dear %s,<br/><br/>Your bank transfer has been rejected.")%self.partner_id.name,
'partner_ids': [(6, 0, [self.partner_id.id])],
# 'author_id': self.env['res.users'].sudo().browse(SUPERUSER_ID).partner_id.id,
'author_id': self.env['res.users'].sudo()._is_admin().partner_id.id,
'date': datetime.now(),
'state': 'sent',
}
# val_mg
self.write({'state': 'reject'})
# @api.multi
def action_accepted(self):
if not self.move_id:
vals = {
'name':_("Bank Transfer State %s")%self.number,
'partner_id': self.partner_id.id,
'amount': self.amount,
# 'operation_type': 'xxx',
'type': 'transfert',
}
move = self.env['takaful.account.move'].sudo().create(vals)
self.write({'move_id': move.id})
context = {'lang': self.partner_id.lang}
val_msg = {
'name': _("Bank Transfer State %s")%self.number,
'body': _("Dear %s,<br/<br/>Your bank transfer has been changed accepted. "
"Please check your balance")%self.partner_id.name,
'partner_ids': [(6, 0, [self.partner_id.id])],
# 'author_id': self.env['res.users'].sudo().browse(SUPERUSER_ID).partner_id.id,
'author_id': self.env['res.users'].sudo()._is_admin().partner_id.id,
'date': datetime.now(),
'state': 'sent',
}
# val_msg
self.move_id.write({'state': 'paid'})
self.write({'state': 'accept'})
# @api.multi
def action_reset_to_draft(self):
self.write({'state': 'draft'})
# @api.multi
def action_canceled(self):
self.move_id.write({'state': 'rejected'})
context = {'lang': self.partner_id.lang}
val_msg = {
'name': _("Bank Transfer State %s")%self.number,
'body': _("Dear %s,<br/<br/>Your bank transfer has been changed to canceled. "
"Please check with your bank")%self.partner_id.name,
'partner_ids': [(6, 0, [self.partner_id.id])],
# 'author_id': self.env['res.users'].sudo().browse(SUPERUSER_ID).partner_id.id,
'author_id': self.env['res.users'].sudo()._is_admin().partner_id.id,
'date': datetime.now(),
'state': 'sent',
}
# val_msg
self.write({'state': 'cancel'})

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from odoo import api, models, fields, _
class City(models.Model):
_name = 'res.country.city'
@api.depends('code', 'name')
def _load_country_id(self):
for r in self:
if r.code and r.name:
r.country_id = self.env.ref('base.sa')
code = fields.Char(string='Code')
name = fields.Char(string='Name')
state_id = fields.Many2one('res.country.state', string='State')
country_id = fields.Many2one('res.country', string='Country', )
active = fields.Boolean(default=True)

View File

@ -0,0 +1,32 @@
# Customize settings for Takaful configrations.
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from ast import literal_eval
class ResCompany(models.Model):
_inherit = 'res.company'
use_otp_login = fields.Boolean(string="Use Otp Login")
otp_provider_token = fields.Char(string="OTP Provider Token")
otp_sender_name = fields.Char(string="OTP Sender Name")
use_sms_notification = fields.Boolean(string="Use SMS Notifications")
sms_provider_token = fields.Char(string="SMS Provider Token")
sms_sender_name = fields.Char(string="SMS Sender Name")
# Moyaser
moyaser_public_key = fields.Char(string='Moyaser Public Key')
vat_default_percent=fields.Float(string='Vat Percent')
bank_account_count = fields.Integer(compute='_compute_bank_count', string="Bank Accounts")
company_name=fields.Char(string='Company Name',translate=True)
# @api.multi
def _compute_bank_count(self):
bank_data = self.env['res.partner.bank'].read_group([('company_id', 'in', self.ids)], ['company_id'],
['company_id'])
mapped_data = dict([(bank['company_id'][0], bank['company_id_count']) for bank in bank_data])
for company in self:
company.bank_account_count = mapped_data.get(company.id, 0)

View File

@ -0,0 +1,221 @@
# -*- coding: utf-8 -*-
from ..TaqnyatSms import client, make_http_response
from odoo import models, fields, api, _
from datetime import datetime, date
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from dateutil.relativedelta import relativedelta as rd
from odoo.osv import expression
from odoo.exceptions import UserError, ValidationError, Warning
import re
import logging
_logger = logging.getLogger(__name__)
SAUDI_MOBILE_PATTERN = "(^(05|5)(5|0|3|6|4|9|1|8|7)([0-9]{7})$)"
class Partner(models.Model):
_inherit = 'res.partner'
def get_default_country(self):
country = self.env["res.country"].search([('code','=','SA')],limit=1)
return country.id
def get_default_state(self):
country = self.env["res.country.state"].search([('code','=','001')],limit=1)
return country.id
@api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
if not args:
args = []
# Extend the domain filter with custom search conditions
if name and hasattr(self, 'identification_number') and 'identification_number' in self._fields:
args = expression.OR([args, [('identification_number', operator, name)]])
return super(Partner, self)._name_search(name, args, operator, limit, name_get_uid)
account_type = fields.Selection(
string='',
selection=[('family', 'Family'),
('sponsor', 'sponsor'),
('benefit', 'Benefit'),
('member', 'Member'),
('vendor', 'Vendor'),
('donor', 'Donor')],
required=False, )
is_family = fields.Boolean()
is_sponsor_portal = fields.Boolean(string='Is Sponsor')
is_benefit = fields.Boolean()
is_vendor = fields.Boolean()
is_donor = fields.Boolean()
code = fields.Char(string="Code", copy=False)
sponsor_title = fields.Many2one('res.partner.title',string='Title')
suffix_title_id = fields.Many2one('res.partner.title',string='Suffix Title')
company_type = fields.Selection(selection_add=[('charity', _('Charity'))])
first_name = fields.Char(string="First Name", tracking=True)
second_name = fields.Char(string="Second Name", tracking=True)
middle_name = fields.Char(string="Third Name", tracking=True)
family_name = fields.Char(string="Family Name", tracking=True)
father_name = fields.Char(string="Father First Name", tracking=True)
father_second_name = fields.Char(string="Father Second Name", tracking=True)
father_third_name = fields.Char(string="Father Third Name", tracking=True)
father_family_name = fields.Char(string="Father Family Name")
birth_date = fields.Date()
age = fields.Integer(string="Age", compute='_compute_get_age_date', store=True)
iban = fields.Char("IBAN")
bank_id = fields.Many2one('res.bank')
id_number = fields.Char(string="Id Number", tracking=True)
id_expiry = fields.Date(string="Id Expiry Date")
gender = fields.Selection(selection=[('male', 'Male'), ('female', 'Female')], string="Gender")
id_number_attach = fields.Binary(string="Id Number Attachment")
health_status = fields.Selection(string='Health Status', selection=[('healthy', 'Healthy'), ('sick', 'Sick')])
education_level = fields.Selection(
string='Educational level',
selection=[
('illiterate', 'Illiterate'),
('kindergarten', 'Kindergarten'),
('primary', 'Primary'),
('middle', 'Middle'),
('secondary', 'Secondary'),
('university', 'University'),
('postgraduate', 'Postgraduate'),
])
education_institution = fields.Char()
country_id = fields.Many2one('res.country',default=get_default_country)
state_id = fields.Many2one('res.country.state',default=get_default_state)
city_id = fields.Many2one('res.country.city',domain=[('state_id.code','=','001')])
marital_status = fields.Selection(
[('single', _('Single')), ('married', _('Married')), ('widower', _('Widower')), ('divorced', _('Divorced'))],
_('Marital Status'))
activation_mode = fields.Selection([
('sms', 'SMS'),
('email', 'Email')])
user_type = fields.Selection([
('person', 'Person'),
('company', 'Company'),
('charity', 'Charity'),
])
_sql_constraints = [
('mobile_uniq', 'unique (mobile)', 'The Mobile Already Exist!'),
('phone_uniq', 'unique (phone)', 'The Phone Already Exist!'),
('user_id_uniq', 'unique (user_id)', 'The User Already Exist!'),
]
def get_partner_target_account_type(self, acc_type):
# Special mappings for account_type -> boolean field names
special_map = {
'sponsor': 'is_sponsor_portal',
}
# Determine the target boolean field name
target_field = special_map.get(acc_type, f'is_{acc_type}')
return target_field
def set_partner_account_type(self, acc_type):
self.ensure_one()
# Determine the target boolean field name
target_field = self.get_partner_target_account_type(acc_type)
# Validate that acc_type is one of the selection values and field exists
valid_types = {key for key, _ in self._fields['account_type'].selection}
if target_field in self._fields and (acc_type in valid_types or target_field == 'is_sponsor_portal'):
update_vals = {target_field: True}
self.write(update_vals)
def migrate_account_type_to_booleans(self):
"""
Server action method to migrate the old `account_type` selection
to the new `is_<type>` boolean fields for the given recordset.
"""
records = self.search([])
_logger.info(f"-> Starting account type migration for {len(records)} partner(s).")
for partner in records:
acc_type = partner.account_type
if not acc_type:
continue
partner.set_partner_account_type(acc_type)
_logger.info("-> Partner account type migration finished.")
return True
# Function Get age by birthdate
@api.depends('birth_date')
def _compute_get_age_date(self):
for rec in self:
if rec.birth_date:
today = date.today()
day = datetime.strptime(str(rec.birth_date), DEFAULT_SERVER_DATE_FORMAT)
age = rd(today, day)
rec.age = age.years
# Validate mobile ..
# @api.constrains('mobile')
# def check_mobile_value(self):
# if self.mobile:
# if re.match(SAUDI_MOBILE_PATTERN, self.mobile) == None:
# raise ValidationError(
# _('Enter a valid Saudi mobile number'))
@api.onchange('mobile', 'country_id', 'company_id')
def _onchange_mobile_validation(self):
if self.mobile:
if self.mobile.startswith('+966'):
mobile = self.mobile[4:]
self.mobile = mobile
if re.match(SAUDI_MOBILE_PATTERN, self.mobile) == None:
raise ValidationError(
_('Enter a valid Saudi mobile number'))
# @api.multi
def send_sms_notification(self, body=None, phone=None):
self.ensure_one()
if not phone:
phone = self.mobile
if not all([phone, body]):
return False
if re.match(SAUDI_MOBILE_PATTERN, str(phone)) == None:
return False
company_id = self.env.user.company_id or self.env['res.company'].sudo().search([('id', '=', 1)])
if company_id and company_id.use_sms_notification:
token = company_id.sms_provider_token or ''
sender = company_id.sms_sender_name or ''
if token and sender:
taqnyt = client(token)
mobile = '966' + str(phone).lstrip('0')
recipients = [mobile]
scheduled = ''
# Sending a SMS for a Notification
message = taqnyt.sendMsg(body, recipients, sender, scheduled)
result = make_http_response(message)
code = int(result['statusCode'])
total_count = int(result['totalCount'])
msg = result['message']
if code == 201 and total_count >= 1:
return True
else:
return False
else:
return False
else:
return False
class PartnerTitle(models.Model):
_inherit = 'res.partner.title'
position = fields.Selection([('prefix', 'Prefix'), ('suffix', 'Suffix'),('both','Both')], default='prefix')

View File

@ -0,0 +1,310 @@
# -*- coding: utf-8 -*-
from ..TaqnyatSms import client, make_http_response
from odoo import models, fields, api, _
from datetime import datetime, date
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from dateutil.relativedelta import relativedelta as rd
from odoo.exceptions import UserError, ValidationError, Warning
from datetime import timedelta
from dateutil import parser
import pytz
import math
import random
import re
import logging
_logger = logging.getLogger(__name__)
SAUDI_MOBILE_PATTERN = "(^(05|5)(5|0|3|6|4|9|1|8|7)([0-9]{7})$)"
OTP_HOUR_LIMIT = 7
OTP_COUNT_LIMIT = 3
def generateOTP() :
digits = "0123456789"
OTP = ""
for i in range(4) :
OTP += digits[int(math.floor(random.random() * 10))]
return OTP
class ResUser(models.Model):
_inherit = 'res.users'
otp = fields.Char(string="OTP", required=False, readonly=True)
otp_password = fields.Char(string="OTP Reset Password", required=False, readonly=True)
otp_count = fields.Integer(string='OTP Request Count', required=False, readonly=True)
otp_date = fields.Datetime(string='OTP Date', required=False, readonly=True)
# @api.multi
def remove_access_groups(self):
""" Remove any access group from a user """
self.ensure_one()
groups_list = self.env['res.groups'].sudo().search([])
for group in groups_list:
if self in (group.users):
# Remove the access group
self.sudo().write({'groups_id': [(3, group.id)]})
# << Send OTP >>
# @api.multi
def send_otp(self, mobile):
self.ensure_one()
if not mobile:
error_descrip = _('Missing mobile number')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'missing_data',
'error_descrip': error_descrip,
}
if re.match(SAUDI_MOBILE_PATTERN, str(mobile)) == None:
error_descrip = _('Invalid Saudi mobile number')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'invalid_mobile',
'error_descrip': error_descrip,
}
company_id = self.env['res.company'].sudo().search([('id','=',1)])
if company_id and company_id.use_otp_login:
token = company_id.otp_provider_token or ''
sender = company_id.otp_sender_name or ''
if token and sender:
otp = generateOTP()
# Start demo for test
self.otp = otp
self.otp_password = otp
self.otp_count = self.otp_count + 1
if int(self.otp_count) == 1:
self.otp_date = fields.Datetime.now()
return {
'code': 200,
'results': {
'message': _('OTP code is successfully sent'),
"mobile": mobile,
"otp": otp,
'note': "OTP returned just for test, will be removed!",
}
}
# End demo/test
taqnyt = client(token)
mobile = '966' + str(mobile).lstrip('0')
body = _("""Dear Customer,
%s is your one time password (OTP). Please enter the OTP to proceed.
Thank you,
Team Takaful""") % otp
recipients = [mobile]
scheduled=''
# Sending a SMS for Verification using OTP
message = taqnyt.sendMsg(body, recipients, sender,scheduled)
result = make_http_response(message)
code = int(result['statusCode'])
total_count = int(result['totalCount'])
msg = result['message']
if code == 201 and total_count >=1:
self.otp = otp
self.otp_password = otp
self.otp_count = self.otp_count + 1
if int(self.otp_count) == 1:
self.otp_date = fields.Datetime.now()
return {
'code': 200,
'results': {
'message': _('OTP code is successfully sent'),
"mobile": mobile,
}
}
else:
_logger.error(msg)
return {
'code': 424,
'error': 'failed_dependency',
'error_descrip': _('Cannot sending SMS verification %s ') %("\n" + msg),
}
else:
error_descrip = _('Sender information does not exist')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'does_not_exist',
'error_descrip': error_descrip,
}
else:
error_descrip = _('SMS service is unavilable')
_logger.error(error_descrip)
return {
'code': 424,
'error': 'failed_dependency',
'error_descrip': error_descrip,
}
# Request OPT
# @api.multi
def request_otp(self, mobile):
self.ensure_one()
if not mobile:
error_descrip = _('Missing mobile number')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'missing_data',
'error_descrip': error_descrip,
}
if self.otp and self.otp_date:
now = fields.Datetime.now()
otp_date = self.otp_date
otp_date_timte = parser.parse(str(self.otp_date))
current_date_timte = parser.parse(str(now))
limit_date_timte = otp_date_timte + timedelta(hours=OTP_HOUR_LIMIT)
counter = int(self.otp_count)
if current_date_timte > limit_date_timte and current_date_timte > otp_date_timte and counter >= OTP_COUNT_LIMIT:
self.otp_count = 0
counter = 0
if current_date_timte < limit_date_timte and counter >= OTP_COUNT_LIMIT:
tz = pytz.timezone('Asia/Riyadh')
remines = limit_date_timte.replace(tzinfo=tz).strftime("%I:%M")
error_descrip = _('Exceeded the limit, please request after the clock %s') % remines
_logger.error(error_descrip)
return {
'code': 400,
'error': 'exceeded_otp_limit',
'error_descrip': error_descrip,
}
return self.sudo().send_otp(mobile)
# Reset Password using email account
# @api.multi
def reset_password_using_email(self):
self.ensure_one()
# Reset Password using email.. login email of user!
try:
self.action_reset_password()
return {
'code': 200,
'results': {
'message': _('Email verification is successfully sent'),
"email": self.login,
}
}
except Exception as e:
error_descrip = _('Cannot sending email verification')
_logger.error(error_descrip)
return {
'code': 424,
'error': 'failed_dependency',
'error_descrip': error_descrip,
}
# Reset Password using Verified OTP
# @api.multi
def reset_password_using_otp(self, password1, password2, otp):
self.ensure_one()
# Reset Password using OTP processing..Should be verified otp!
if not all([password1, password2, otp]):
error_descrip = _('Missing Password Values or OTP')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'missing_data',
'error_descrip': error_descrip,
}
if password1 != password2:
error_descrip = _('The entered password does not match')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'password_not_match',
'error_descrip': error_descrip,
}
if self.otp_password:
otp_original = str(self.otp_password)
otp_customer = str(otp)
if otp_customer == otp_original:
# Reset password processing..
self.password = password1
self.otp_password = None
self.env.cr.commit()
return {
'code': 200,
'results': {
'message': _('Password is successfully reset'),
}
}
else:
error_descrip = _('Invalid OTP, Reset Password Failed')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'invalid_otp',
'error_descrip': error_descrip,
}
else:
error_descrip = _('OTP does not exist or expired, please request it again')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'expired_otp',
'error_descrip': error_descrip,
}
# Verify OTP
# @api.multi
def verify_otp(self, otp):
self.ensure_one()
# OTP verify processing..
if self.otp:
otp_original = str(self.otp)
otp_customer = str(otp)
if otp_customer != otp_original:
error_descrip = _('Invalid OTP, Verification Failed')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'invalid_otp',
'error_descrip': error_descrip,
}
else:
self.otp = None
return {
'code': 200,
'results': {
'message': _('Verification is successful'),
}
}
else:
error_descrip = _('OTP does not exist or expired, please request it again')
_logger.error(error_descrip)
return {
'code': 400,
'error': 'expired_otp',
'error_descrip': error_descrip,
}

View File

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
from odoo import api, models, fields, _
from odoo.addons import decimal_precision as dp
import logging
_logger = logging.getLogger(__name__)
class AccountInvoice(models.Model):
_inherit = "account.move"
operation_type = fields.Selection([
('in_kind_donation', 'In-Kind Donation'),
('financial_donation', 'Financial Donation'),
('subscription', 'Subscription'),
('sponsorship', 'Sponsorship'),
('financial_gift', 'Financial Gift'),
('need_contribution', 'Needs Contribution')],
string='Operation Type',
)
operation_id = fields.Integer(readonly=True)
class TakafulAccountMove(models.Model):
_name = 'takaful.account.move'
name = fields.Char(string='Order Name')
remote_id = fields.Char(string='Order Number')
partner_id = fields.Many2one('res.partner', string='Customer')
name_of = fields.Char(string='Customer Name', readonly=True)
email = fields.Char(string='Customer Email', readonly=True)
note = fields.Text(string='Comment')
amount = fields.Float(string='Amount With Vat')
operation_type = fields.Selection([
('in_kind_donation', 'In-Kind Donation'),
('financial_donation', 'Financial Donation'),
('subscription', 'Subscription'),
('sponsorship', 'Sponsorship'),
('financial_gift', 'Financial Gift'),
('need_contribution', 'Needs Contribution')],
string='Operation Type',
)
operation_id = fields.Integer(readonly=True)
type = fields.Selection(selection=[
('card', _('Credit Card')),
('transfer', _('Bank Transfer')),
], string='Type')
date = fields.Date('Date', default=fields.Date.context_today)
qty_ordered = fields.Float(string='Qty Ordered',default=1)
state = fields.Selection(selection=[
('initiated', _('Initiated')),
('failed', _('Failed')),
('rejected', _('Rejected')),
('paid', _('Paid')),
], default='paid', string='Status')
transfer_id = fields.Many2one('takaful.bank.transfer.payment', string='Transfer')
amount_without_vat = fields.Float(string='Amount Without Vat', compute='_get_vat_amount')
tax_amount = fields.Float(string='Vat', compute='_get_vat_amount',digits= dp.get_precision('Product Price'))
# @api.one
@api.depends('amount', 'type')
def _get_vat_amount(self):
for rec in self:
if not rec.type:
tax_percent = float(
self.env['ir.config_parameter'].sudo().get_param('vat_default_percent', default=0.0))
rec.amount_without_vat = rec.amount/(1+(tax_percent/100))
rec.tax_amount = round(rec.amount - rec.amount_without_vat,2)
else:
rec.amount_without_vat = rec.amount
rec.tax_amount = 0
def get_company(self):
return self.env.user.company_id
TakafulAccountMove()
"""
vals = {
'name': _('Server Update'),
'partner_id': request.env.user.partner_id.id,
'amount': diff,
'qty_ordered': num_months,
'operation_type': 'credit',
'state': 'paid',
}
request.env['takaful.account.move'].sudo().create(vals)
"""

View File

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="transfer_sequence_bank" model="ir.sequence">
<field name="name">Bank Transfer</field>
<field name="code">bank.payment.transfer</field>
<field name="prefix">Trans/</field>
<field name="padding">4</field>
</record>
<record id="view_order_form_inherit_res_comapny" model="ir.ui.view">
<field name="name">res.company.form</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="arch" type="xml">
<xpath expr="//h1" position="after">
<h2>
<field name="company_name"/>
</h2>
</xpath>
<!-- <xpath expr="//field[@name='report_footer']" position="after">-->
<!-- <div>-->
<!-- <label for="bank_account_count"/>-->
<!-- <button type="action" class="btn-link"-->
<!-- name="%(base.action_res_partner_bank_account_form)d"-->
<!-- context="{'search_default_company_id': active_id, 'default_company_id': active_id}">-->
<!-- <field string="Bank account(s)" name="bank_account_count" widget="statinfo"/>-->
<!-- </button>-->
<!-- </div>-->
<!-- </xpath>-->
</field>
</record>
<record id="bank_account_image_add_view" model="ir.ui.view">
<field name="name">res.partner.bank.form</field>
<field name="model">res.partner.bank</field>
<field name="inherit_id" ref="base.view_partner_bank_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='acc_number']" position="after">
<field name="bank_img" string="Bank Image" widget="image" class="oe_avatar"/>
</xpath>
</field>
</record>
<record id="view_takaful_bank_payment_transfer_tree" model="ir.ui.view">
<field name="name">takaful.bank.transfer.payment.tree</field>
<field name="model">takaful.bank.transfer.payment</field>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<tree string="Bank Transfer" decoration-muted="state in ('cancel','accept')"
decoration-danger="state in ('reject','pending')" decoration-info="state=='draft'">
<field name="partner_id"/>
<field name="number"/>
<field name="name"/>
<field name="name_of"/>
<field name="amount"/>
<field name="state"/>
</tree>
</field>
</record>
<record id="view_takaful_bank_payment_transfer_form" model="ir.ui.view">
<field name="name">takaful.bank.transfer.payment.form</field>
<field name="model">takaful.bank.transfer.payment</field>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<form string="Bank Transfer">
<header>
<button name="action_pending" string="Pending" states="draft" class="oe_highlight"
type="object"/>
<button name="action_accepted" string="Accept" states="pending,draft" class="oe_highlight"
type="object"/>
<button name="action_rejected" string="Reject" states="pending,draft" class="oe_highlight"
type="object"/>
<button name="action_canceled" string="Cancel" states="accept,reject" class="oe_highlight"
type="object"/>
<button name="action_reset_to_draft" string="Set Draft" states="cancel" class="oe_highlight"
type="object"/>
<field name="state" widget="statusbar" statusbar_visible="draft,pending,accept"/>
</header>
<sheet>
<div class="oe_title">
<h2>
<table>
<tr>
<td>
<field name="number" style="padding-right:10px"/>
</td>
</tr>
</table>
</h2>
</div>
<group>
<group>
<field name="partner_id"/>
<field name="name"/>
<field name="name_of"/>
<field name="transfer_date"/>
</group>
<group>
<field name="transfer_attachment" filename="filename"/>
<field name="filename" invisible="1"/>
<field name="move_id"/>
<field name="amount"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<!-- <record id="view_takaful_bank_payment_transfer_search" model="ir.ui.view">-->
<!-- <field name="name">takaful.bank.transfer.payment.search</field>-->
<!-- <field name="model">takaful.bank.transfer.payment</field>-->
<!-- <field name="priority" eval="8"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <search string="Bank Transfer">-->
<!-- <field name="partner_id"/>-->
<!-- <field name="number"/>-->
<!-- <field name="name"/>-->
<!-- <field name="name_of"/>-->
<!-- <field name="amount"/>-->
<!-- <field name="state"/>-->
<!-- <newline/>-->
<!-- <group expand="0" string="Group By...">-->
<!-- <filter string="Customer" domain="[]"-->
<!-- context="{'group_by':'partner_id'}"/>-->
<!-- <filter string="State" domain="[]"-->
<!-- context="{'group_by':'state'}"/>-->
<!-- </group>-->
<!-- </search>-->
<!-- </field>-->
<!-- </record>-->
<!-- <record model="ir.actions.act_window" id="act_takaful_bank_transfer_view">-->
<!-- <field name="name">Bank Transfer</field>-->
<!-- <field name="type">ir.actions.act_window</field>-->
<!-- <field name="res_model">takaful.bank.transfer.payment</field>-->
<!-- <field name="view_type">form</field>-->
<!-- <field name="view_mode">tree,form</field>-->
<!-- <field name="search_view_id" ref="view_takaful_bank_payment_transfer_search"/>-->
<!-- <field name="domain">[]</field>-->
<!-- <field name="context">{}</field>-->
<!-- </record>-->
<!-- <record model="ir.actions.act_window.view" id="act_takaful_bank_transfer_form">-->
<!-- <field name="act_window_id" ref="act_takaful_bank_transfer_view"/>-->
<!-- <field name="sequence" eval="20"/>-->
<!-- <field name="view_mode">form</field>-->
<!-- <field name="view_id" ref="view_takaful_bank_payment_transfer_form"/>-->
<!-- </record>-->
<!-- <record model="ir.actions.act_window.view" id="act_takaful_bank_transfer_tree">-->
<!-- <field name="act_window_id" ref="act_takaful_bank_transfer_view"/>-->
<!-- <field name="sequence" eval="10"/>-->
<!-- <field name="view_mode">tree</field>-->
<!-- <field name="view_id" ref="view_takaful_bank_payment_transfer_tree"/>-->
<!-- </record>-->
</odoo>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_company_form_inherit_otp" model="ir.ui.view">
<field name="name">res.company.form.default</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="arch" type="xml">
<xpath expr="//page" position="after">
<page string="OTP Information">
<group>
<field name="use_otp_login" style="margin-bottom:10px; margin-left:10px;"/>
<field name="otp_provider_token" attrs="{'required':[('use_otp_login','=',True)],'invisible':[('use_otp_login','!=',True)]}" style="margin-bottom:10px; margin-left:10px;" password="True"/>
<field name="otp_sender_name" attrs="{'required':[('use_otp_login','=',True)],'invisible':[('use_otp_login','!=',True)]}" style="margin-bottom:10px; margin-left:10px;"/>
</group>
</page>
<page string="SMS Information">
<group>
<field name="use_sms_notification" style="margin-bottom:10px; margin-left:10px;" />
<field name="sms_provider_token" attrs="{'required':[('use_sms_notification','=',True)],'invisible':[('use_sms_notification','!=',True)]}" style="margin-bottom:10px; margin-left:10px;" password="True" />
<field name="sms_sender_name" attrs="{'required':[('use_sms_notification','=',True)],'invisible':[('use_sms_notification','!=',True)]}" style="margin-bottom:10px; margin-left:10px;" />
</group>
</page>
<page string="Moyaser Integration">
<group>
<label for="moyaser_public_key" string="Publicy Key" class="col-xs-3 col-md-3 o_light_label"/>
<field name="moyaser_public_key" placeholder="Moyaser Publicy Key" password="True" nolabel="1"/>
</group>
<label for="vat_default_percent" string="Default Vat Value"
class="col-xs-3 col-md-3 o_light_label"/>
<field name="vat_default_percent" placeholder="Default Vat Value" nolabel="1"/>
</page>
</xpath>
</field>
</record>
</odoo>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<menuitem id="takaful_online_paycard_menu" name="Takaful Online Payments" parent="account.menu_finance"/>
<!-- <menuitem id="online_paycard_menu" name="Online Payments" action="takaful_core.takaful_account_move_list_action" parent="account.menu_finance"/> -->
<menuitem sequence="1" id="takaful_account_move_menu" name="Invoices" parent="takaful_online_paycard_menu" action="takaful_core.takaful_account_move_list_action"/>
<!-- <menuitem sequence="2" id="takaful_bank_transfer_payment_menu" name="Bank Transfers" parent="takaful_online_paycard_menu" action="takaful_core.act_takaful_bank_transfer_view"/>-->
</data>
</odoo>

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Inherit Form res.partner View to add account Type -->
<record id="res_partner_data" model="ir.ui.view">
<field name="name">res.partner.account.type</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//div/h1" position="after">
<!-- Add your fields or attributes here -->
<group>
<!-- <field name="account_type" groups="odex_benefit.group_benefit_info"/> -->
<field name="code" groups="odex_benefit.group_benefit_info"/>
<field name="activation_mode" invisible="1"/>
<field name="user_type" invisible="1"/>
</group>
</xpath>
<xpath expr="//notebook" position="inside">
<page string="Account Type">
<group>
<group>
<field name="is_family" readonly="1"/>
<field name="is_sponsor_portal" readonly="1"/>
<field name="is_benefit" readonly="1"/>
</group>
<group>
<field name="is_vendor" readonly="1"/>
<field name="is_donor" readonly="1"/>
</group>
</group>
</page>
</xpath>
</field>
</record>
<record id="view_res_city_tree" model="ir.ui.view">
<field name="name">Odex - City tree</field>
<field name="model">res.country.city</field>
<field name="arch" type="xml">
<tree string="Cities">
<field name="code"/>
<field name="name"/>
<field name="state_id"/>
<field name="country_id"/>
</tree>
</field>
</record>
<record id="view_res_city_form" model="ir.ui.view">
<field name="name">Odex - City form</field>
<field name="model">res.country.city</field>
<field name="arch" type="xml">
<form string="City">
<sheet>
<group>
<group>
<field name="code" required="True"/>
<field name="state_id" domain="[('country_id', '=', country_id)]"
required="True"/>
</group>
<group>
<field name="name" required="True"/>
<field name="country_id"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_partner_title_inherit_tree" model="ir.ui.view">
<field name="name">res.partner.title.form.inherit</field>
<field name="model">res.partner.title</field>
<field name="inherit_id" ref="base.view_partner_title_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='shortcut']" position="after">
<field name="position"/>
</xpath>
</field>
</record>
</odoo>

View File

@ -0,0 +1,69 @@
<odoo>
<data>
<record id="takaful_account_move_tree_viewx" model="ir.ui.view">
<field name="name">takaful.account.move.tree</field>
<field name="model">takaful.account.move</field>
<field name="arch" type="xml">
<tree string="Invoices">
<field name="name"></field>
<field name="partner_id"></field>
<field name="email"></field>
<field name="operation_type"></field>
<field name="type"></field>
<field name="date"></field>
<field name="state"></field>
<field name="amount_without_vat"></field>
<field name="tax_amount"></field>
<field name="amount"></field>
</tree>
</field>
</record>
<record id="takaful_account_move_form" model="ir.ui.view">
<field name="name">takaful.account.move.form</field>
<field name="model">takaful.account.move</field>
<field name="arch" type="xml">
<form string="server">
<sheet>
<group>
<group>
<field name="id" string="Invoice Number"></field>
<field name="partner_id"></field>
<field name="name_of"></field>
<field name="email"></field>
<field name="operation_type"></field>
<field name="type"></field>
<field name="qty_ordered"></field>
<field name="amount_without_vat"></field>
</group>
<group>
<field name="date"></field>
<field name="state"></field>
<field name="amount"></field>
<field name="tax_amount"></field>
</group>
<group>
<field name="note"></field>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="takaful_account_move_list_action">
<field name="name">Paycards Account Moves</field>
<field name="res_model">takaful.account.move</field>
<!-- <field name="view_type">form</field>-->
<field name="view_mode">tree,form</field>
</record>
<record model="ir.actions.act_window.view" id="takaful_account_move_list_action_tree">
<field name="act_window_id" ref="takaful_account_move_list_action"/>
<field name="sequence" eval="10"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="takaful_core.takaful_account_move_tree_viewx"/>
</record>
</data>
</odoo>