Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
Clubphp
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Clubphp
Commits
ca7312ce
Commit
ca7312ce
authored
Apr 07, 2026
by
Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update 1 files via Son of Anton
parent
44998953
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
110 deletions
+107
-110
SpouseController.php
app/Modules/Spouses/Controllers/SpouseController.php
+107
-110
No files found.
app/Modules/Spouses/Controllers/SpouseController.php
View file @
ca7312ce
...
...
@@ -22,21 +22,29 @@ class SpouseController extends Controller
return
$this
->
redirect
(
'/members'
)
->
withError
(
'العضو غير موجود'
);
}
// BLOCK: membership_value must be set
$membershipValue
=
$member
[
'membership_value'
]
??
'0.00'
;
if
(
bccomp
(
$membershipValue
,
'0.01'
,
2
)
<
0
)
{
return
$this
->
redirect
(
'/members/'
.
$memberId
)
->
withError
(
'⚠ يجب ملء الاستمارة وتحديد المؤهل أولاً لحساب قيمة العضوية قبل إضافة زوج/ة'
);
}
$qualifications
=
$db
->
select
(
"SELECT id, name_ar FROM qualifications WHERE is_active = 1 ORDER BY sort_order"
);
$countries
=
$db
->
select
(
"SELECT nationality_ar FROM countries WHERE is_active = 1 ORDER BY name_ar"
);
$
currentSpouseCount
=
Spouse
::
countActiveForMemb
er
((
int
)
$memberId
);
$
spouseOrder
=
Spouse
::
getNextOrd
er
((
int
)
$memberId
);
//
Check max spouses
$
maxSpouses
=
(
$member
[
'gender'
]
===
'male'
)
?
4
:
1
;
if
(
$currentSpouseCount
>=
$maxSpouses
)
{
return
$this
->
redirect
(
'/members/'
.
$memberId
)
->
withError
(
'تم الوصول للحد الأقصى لعدد الأزواج'
);
}
//
Pre-calculate fee estimate for display
$
feeEstimate
=
SpouseFeeCalculator
::
calculate
((
int
)
$memberId
,
[
'nationality'
=>
'مصري'
,
'marriage_date'
=>
date
(
'Y-m-d'
),
]);
return
$this
->
view
(
'Spouses.Views.create'
,
[
'member'
=>
$member
,
'qualifications'
=>
$qualifications
,
'countries'
=>
$countries
,
'spouseOrder'
=>
$currentSpouseCount
+
1
,
'spouseOrder'
=>
$spouseOrder
,
'feeEstimate'
=>
$feeEstimate
,
]);
}
...
...
@@ -48,22 +56,28 @@ class SpouseController extends Controller
return
$this
->
redirect
(
'/members'
)
->
withError
(
'العضو غير موجود'
);
}
// BLOCK: membership_value must be set
$membershipValue
=
$member
[
'membership_value'
]
??
'0.00'
;
if
(
bccomp
(
$membershipValue
,
'0.01'
,
2
)
<
0
)
{
return
$this
->
redirect
(
'/members/'
.
$memberId
)
->
withError
(
'⚠ يجب تحديد قيمة العضوية قبل إضافة زوج/ة'
);
}
$data
=
$request
->
all
();
unset
(
$data
[
'_csrf_token'
]);
$errors
=
[];
// Required fields
if
(
empty
(
trim
(
$data
[
'full_name_ar'
]
??
''
)))
$errors
[]
=
'اسم الزوج/الزوجة مطلوب'
;
if
(
empty
(
trim
(
$data
[
'full_name_ar'
]
??
''
)))
$errors
[]
=
'اسم الزوج/ة مطلوب'
;
if
(
empty
(
$data
[
'date_of_birth'
]
??
''
))
$errors
[]
=
'تاريخ الميلاد مطلوب'
;
if
(
empty
(
$data
[
'gender'
]
??
''
))
$errors
[]
=
'النوع مطلوب'
;
if
(
empty
(
$data
[
'marriage_date'
]
??
''
))
$errors
[]
=
'تاريخ الزواج مطلوب'
;
//
Check max spouses
$
current
Count
=
Spouse
::
countActiveForMember
((
int
)
$memberId
);
//
Max spouse check
$
existing
Count
=
Spouse
::
countActiveForMember
((
int
)
$memberId
);
$maxSpouses
=
(
$member
[
'gender'
]
===
'male'
)
?
4
:
1
;
if
(
$
current
Count
>=
$maxSpouses
)
{
$errors
[]
=
'تم
الوصول للحد الأقصى لعدد الأزواج
('
.
$maxSpouses
.
')'
;
if
(
$
existing
Count
>=
$maxSpouses
)
{
$errors
[]
=
'تم
بلوغ الحد الأقصى لعدد الزوجات
('
.
$maxSpouses
.
')'
;
}
// Parse NID if provided
...
...
@@ -79,35 +93,33 @@ class SpouseController extends Controller
$data
[
'gender'
]
=
$parsed
[
'gender'
];
}
// Cannot be
own spouse
// Cannot be
the member themselves
if
(
$nid
===
(
$member
[
'national_id'
]
??
''
))
{
$errors
[]
=
'لا يمكن إضافة العضو نفسه كزوج'
;
$errors
[]
=
'لا يمكن إضافة العضو نفسه كزوج
/ة
'
;
}
//
Duplicate NID check
//
Check duplicate
$dup
=
Spouse
::
nidExistsForOtherMember
(
$nid
,
(
int
)
$memberId
);
if
(
$dup
)
{
$dupName
=
$dup
[
'data'
][
'full_name_ar'
]
??
''
;
$dupNum
=
$dup
[
'data'
][
'membership_number'
]
??
''
;
$errors
[]
=
"الرقم القومي مسجل بالفعل:
{
$dupName
}
(
{
$dupNum
}
)"
;
$errors
[]
=
'الرقم القومي مسجل بالفعل: '
.
(
$dup
[
'data'
][
'full_name_ar'
]
??
''
);
}
}
// Marriage date validation
if
(
!
empty
(
$data
[
'marriage_date'
]))
{
// Calculate age
if
(
!
empty
(
$data
[
'date_of_birth'
])
&&
empty
(
$data
[
'age_years'
]))
{
$age
=
age_from_dob
(
$data
[
'date_of_birth'
]);
$data
[
'age_years'
]
=
$age
[
'years'
];
$data
[
'age_months'
]
=
$age
[
'months'
];
}
// Both must be at least 18 at marriage
if
(
!
empty
(
$data
[
'date_of_birth'
])
&&
!
empty
(
$data
[
'marriage_date'
]))
{
$dobTs
=
strtotime
(
$data
[
'date_of_birth'
]);
$marriageTs
=
strtotime
(
$data
[
'marriage_date'
]);
if
(
$marriageTs
>
time
())
{
$errors
[]
=
'تاريخ الزواج لا يمكن أن يكون في المستقبل'
;
}
// Both must be >= 18 at marriage
if
(
!
empty
(
$data
[
'date_of_birth'
])
&&
!
empty
(
$member
[
'date_of_birth'
]))
{
$spouseAgeAtMarriage
=
(
int
)
(((
new
\DateTime
(
$data
[
'date_of_birth'
]))
->
diff
(
new
\DateTime
(
$data
[
'marriage_date'
])))
->
y
);
$memberAgeAtMarriage
=
(
int
)
(((
new
\DateTime
(
$member
[
'date_of_birth'
]))
->
diff
(
new
\DateTime
(
$data
[
'marriage_date'
])))
->
y
);
if
(
$spouseAgeAtMarriage
<
18
)
{
$errors
[]
=
'عمر الزوج/الزوجة عند الزواج يجب أن يكون 18 سنة على الأقل'
;
}
if
(
$memberAgeAtMarriage
<
18
)
{
$errors
[]
=
'عمر العضو عند الزواج يجب أن يكون 18 سنة على الأقل'
;
if
(
$marriageTs
&&
$dobTs
)
{
$ageAtMarriage
=
(
int
)
((
$marriageTs
-
$dobTs
)
/
(
365.25
*
86400
));
if
(
$ageAtMarriage
<
18
)
{
$errors
[]
=
'يجب أن يكون عمر الزوج/ة 18 سنة على الأقل وقت الزواج'
;
}
}
}
...
...
@@ -119,77 +131,82 @@ class SpouseController extends Controller
return
$this
->
redirect
(
"/members/
{
$memberId
}
/spouses/create"
);
}
// Calculate age
if
(
!
empty
(
$data
[
'date_of_birth'
])
&&
empty
(
$data
[
'age_years'
]))
{
$age
=
age_from_dob
(
$data
[
'date_of_birth'
]);
$data
[
'age_years'
]
=
$age
[
'years'
];
$data
[
'age_months'
]
=
$age
[
'months'
];
}
// Determine classification
$spouseAge
=
(
int
)
(
$data
[
'age_years'
]
??
0
);
$classification
=
$spouseAge
>=
21
?
'working'
:
'dependent'
;
// Calculate fee
$feeCalc
=
SpouseFeeCalculator
::
calculate
((
int
)
$memberId
,
$data
);
$spouseOrder
=
$feeCalc
[
'spouse_order'
]
??
(
$currentCount
+
1
);
if
(
!
empty
(
$feeCalc
[
'error'
]))
{
return
$this
->
redirect
(
"/members/
{
$memberId
}
/spouses/create"
)
->
withError
(
$feeCalc
[
'error'
]);
}
$spouseOrder
=
$feeCalc
[
'spouse_order'
]
??
Spouse
::
getNextOrder
((
int
)
$memberId
);
$joinDate
=
date
(
'Y-m-d'
);
$spouse
=
Spouse
::
create
([
'member_id'
=>
(
int
)
$memberId
,
'spouse_order'
=>
$spouseOrder
,
'full_name_ar'
=>
trim
(
$data
[
'full_name_ar'
]),
'full_name_en'
=>
trim
(
$data
[
'full_name_en'
]
??
''
),
'national_id'
=>
$nid
?:
null
,
'passport_number'
=>
$data
[
'passport_number'
]
??
null
,
'date_of_birth'
=>
$data
[
'date_of_birth'
],
'age_years'
=>
(
int
)
(
$data
[
'age_years'
]
??
0
),
'age_months'
=>
(
int
)
(
$data
[
'age_months'
]
??
0
),
'gender'
=>
$data
[
'gender'
],
'nationality'
=>
$data
[
'nationality'
]
??
'مصري'
,
'religion'
=>
$data
[
'religion'
]
??
null
,
'qualification_id'
=>
!
empty
(
$data
[
'qualification_id'
])
?
(
int
)
$data
[
'qualification_id'
]
:
null
,
'occupation'
=>
$data
[
'occupation'
]
??
null
,
'work_address'
=>
$data
[
'work_address'
]
??
null
,
'work_phone'
=>
$data
[
'work_phone'
]
??
null
,
'mobile'
=>
$data
[
'mobile'
]
??
null
,
'marriage_date'
=>
$data
[
'marriage_date'
],
'join_date'
=>
date
(
'Y-m-d'
)
,
'classification'
=>
$classification
,
'addition_fee'
=>
$feeCalc
[
'spouse
_fee'
]
??
'0.00'
,
'status'
=>
'active'
,
'member_id'
=>
(
int
)
$memberId
,
'spouse_order'
=>
$spouseOrder
,
'full_name_ar'
=>
trim
(
$data
[
'full_name_ar'
]),
'full_name_en'
=>
trim
(
$data
[
'full_name_en'
]
??
''
),
'national_id'
=>
$nid
?:
null
,
'passport_number'
=>
$data
[
'passport_number'
]
??
null
,
'date_of_birth'
=>
$data
[
'date_of_birth'
],
'age_years'
=>
(
int
)
(
$data
[
'age_years'
]
??
0
),
'age_months'
=>
(
int
)
(
$data
[
'age_months'
]
??
0
),
'gender'
=>
$data
[
'gender'
],
'nationality'
=>
$data
[
'nationality'
]
??
'مصري'
,
'religion'
=>
$data
[
'religion'
]
??
null
,
'qualification_id'
=>
(
$data
[
'qualification_id'
]
??
''
)
!==
''
?
(
int
)
$data
[
'qualification_id'
]
:
null
,
'occupation'
=>
$data
[
'occupation'
]
??
null
,
'work_address'
=>
$data
[
'work_address'
]
??
null
,
'work_phone'
=>
$data
[
'work_phone'
]
??
null
,
'mobile'
=>
$data
[
'mobile'
]
??
null
,
'marriage_date'
=>
$data
[
'marriage_date'
],
'join_date'
=>
$joinDate
,
'classification'
=>
'working'
,
'addition_fee'
=>
$feeCalc
[
'total
_fee'
]
??
'0.00'
,
'status'
=>
'active'
,
]);
EventBus
::
dispatch
(
'spouse.added'
,
[
'member_id'
=>
(
int
)
$memberId
,
'spouse_id'
=>
(
int
)
$spouse
->
id
,
'fee'
=>
$feeCalc
[
'spouse_fee'
]
??
'0.00'
,
'member_id'
=>
(
int
)
$memberId
,
'spouse_id'
=>
(
int
)
$spouse
->
id
,
'spouse_order'
=>
$spouseOrder
,
'fee'
=>
$feeCalc
[
'total_fee'
]
??
'0.00'
,
]);
// Build success message with full breakdown
$breakdown
=
$feeCalc
[
'breakdown'
]
??
[];
$breakdownText
=
!
empty
(
$breakdown
)
?
"
\n
"
.
implode
(
"
\n
"
,
$breakdown
)
:
''
;
$msg
=
'تم إضافة الزوج/الزوجة بنجاح'
;
$msg
.=
' — الترتيب: #'
.
$spouseOrder
;
$msg
.=
' — الرسوم: '
.
money
(
$feeCalc
[
'total_fee'
]
??
'0'
);
if
(
!
empty
(
$feeCalc
[
'rule_applied'
]))
{
$msg
.=
' ('
.
$feeCalc
[
'rule_applied'
]
.
')'
;
}
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withSuccess
(
'تم إضافة الزوج/الزوجة بنجاح — الرسوم: '
.
money
(
$feeCalc
[
'spouse_fee'
]
??
'0.00'
)
);
->
withSuccess
(
$msg
);
}
public
function
show
(
Request
$request
,
string
$memberId
,
string
$id
)
:
Response
{
$spouse
=
Spouse
::
find
((
int
)
$id
);
if
(
!
$spouse
||
(
int
)
$spouse
->
member_id
!==
(
int
)
$memberId
)
{
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withError
(
'بيانات الزوج غير موجودة'
);
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withError
(
'بيانات الزوج
/ة
غير موجودة'
);
}
$db
=
App
::
getInstance
()
->
db
();
$member
=
$db
->
selectOne
(
"SELECT * FROM members WHERE id = ?"
,
[(
int
)
$memberId
]);
return
$this
->
view
(
'Spouses.Views.show'
,
[
'member'
=>
$member
,
'spouse'
=>
$spouse
,
]);
return
$this
->
view
(
'Spouses.Views.show'
,
[
'member'
=>
$member
,
'spouse'
=>
$spouse
]);
}
public
function
edit
(
Request
$request
,
string
$memberId
,
string
$id
)
:
Response
{
$spouse
=
Spouse
::
find
((
int
)
$id
);
if
(
!
$spouse
||
(
int
)
$spouse
->
member_id
!==
(
int
)
$memberId
)
{
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withError
(
'بيانات الزوج غير موجودة'
);
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withError
(
'بيانات الزوج
/ة
غير موجودة'
);
}
$db
=
App
::
getInstance
()
->
db
();
...
...
@@ -209,42 +226,35 @@ class SpouseController extends Controller
{
$spouse
=
Spouse
::
find
((
int
)
$id
);
if
(
!
$spouse
||
(
int
)
$spouse
->
member_id
!==
(
int
)
$memberId
)
{
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withError
(
'بيانات الزوج غير موجودة'
);
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withError
(
'بيانات الزوج
/ة
غير موجودة'
);
}
$data
=
$request
->
all
();
unset
(
$data
[
'_csrf_token'
]);
$updateFields
=
[
'full_name_en'
,
'religion'
,
'occupation'
,
'work_address'
,
'work_phone'
,
'mobile'
,
'qualification_id'
,
];
$updateData
=
[];
foreach
(
$updateFields
as
$field
)
{
foreach
(
[
'full_name_en'
,
'occupation'
,
'work_address'
,
'work_phone'
,
'mobile'
,
'religion'
]
as
$field
)
{
if
(
array_key_exists
(
$field
,
$data
))
{
$val
=
$data
[
$field
];
$updateData
[
$field
]
=
(
$val
===
''
||
$val
===
null
)
?
null
:
$val
;
}
}
if
(
isset
(
$data
[
'qualification_id'
]))
{
$updateData
[
'qualification_id'
]
=
(
$data
[
'qualification_id'
]
!==
''
)
?
(
int
)
$data
[
'qualification_id'
]
:
null
;
}
if
(
!
empty
(
$updateData
))
{
$spouse
->
update
(
$updateData
);
}
EventBus
::
dispatch
(
'spouse.updated'
,
[
'member_id'
=>
(
int
)
$memberId
,
'spouse_id'
=>
(
int
)
$id
,
]);
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withSuccess
(
'تم تحديث بيانات الزوج/الزوجة'
);
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withSuccess
(
'تم تحديث بيانات الزوج/ة'
);
}
public
function
archive
(
Request
$request
,
string
$memberId
,
string
$id
)
:
Response
{
$spouse
=
Spouse
::
find
((
int
)
$id
);
if
(
!
$spouse
||
(
int
)
$spouse
->
member_id
!==
(
int
)
$memberId
)
{
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withError
(
'بيانات الزوج غير موجودة'
);
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withError
(
'بيانات الزوج
/ة
غير موجودة'
);
}
$reason
=
trim
((
string
)
$request
->
post
(
'reason'
,
''
));
...
...
@@ -256,11 +266,11 @@ class SpouseController extends Controller
$db
=
App
::
getInstance
()
->
db
();
$db
->
update
(
'spouses'
,
[
'is_archived'
=>
1
,
'archived_at'
=>
date
(
'Y-m-d H:i:s'
),
'archived_by'
=>
$employee
?
(
int
)
$employee
->
id
:
null
,
'status'
=>
'inactive'
,
'updated_at'
=>
date
(
'Y-m-d H:i:s'
),
'is_archived'
=>
1
,
'archived_at'
=>
date
(
'Y-m-d H:i:s'
),
'archived_by'
=>
$employee
?
(
int
)
$employee
->
id
:
null
,
'status'
=>
'inactive'
,
'updated_at'
=>
date
(
'Y-m-d H:i:s'
),
],
'`id` = ?'
,
[(
int
)
$id
]);
EventBus
::
dispatch
(
'spouse.removed'
,
[
...
...
@@ -269,19 +279,6 @@ class SpouseController extends Controller
'reason'
=>
$reason
,
]);
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withSuccess
(
'تم إزالة الزوج/الزوجة'
);
}
public
function
calculateFee
(
Request
$request
)
:
Response
{
$memberId
=
(
int
)
$request
->
post
(
'member_id'
,
0
);
$data
=
$request
->
all
();
if
(
$memberId
<=
0
)
{
return
$this
->
json
([
'error'
=>
'بيانات غير صالحة'
],
422
);
}
$result
=
SpouseFeeCalculator
::
calculate
(
$memberId
,
$data
);
return
$this
->
json
(
$result
);
return
$this
->
redirect
(
"/members/
{
$memberId
}
"
)
->
withSuccess
(
'تم إزالة الزوج/ة'
);
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment