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
a3fd26ba
Commit
a3fd26ba
authored
Apr 18, 2026
by
Mahmoud Aglan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
accounting bugs
parent
6d44324b
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
141 additions
and
123 deletions
+141
-123
BankAccountController.php
app/Modules/Accounting/Controllers/BankAccountController.php
+5
-4
BankReconciliationController.php
...s/Accounting/Controllers/BankReconciliationController.php
+7
-6
ChartOfAccountsController.php
...ules/Accounting/Controllers/ChartOfAccountsController.php
+7
-6
CostCenterController.php
app/Modules/Accounting/Controllers/CostCenterController.php
+6
-5
FiscalYearController.php
app/Modules/Accounting/Controllers/FiscalYearController.php
+7
-6
JournalEntryController.php
...Modules/Accounting/Controllers/JournalEntryController.php
+11
-10
PeriodClosingService.php
app/Modules/Accounting/Services/PeriodClosingService.php
+94
-82
accounts_payable.php
app/Modules/Accounting/Views/reports/accounts_payable.php
+1
-1
accounts_receivable.php
app/Modules/Accounting/Views/reports/accounts_receivable.php
+1
-1
general_ledger.php
app/Modules/Accounting/Views/reports/general_ledger.php
+1
-1
member_statement.php
app/Modules/Accounting/Views/reports/member_statement.php
+1
-1
No files found.
app/Modules/Accounting/Controllers/BankAccountController.php
View file @
a3fd26ba
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace
App\Modules\Accounting\Controllers
;
namespace
App\Modules\Accounting\Controllers
;
use
App\Core\Controller
;
use
App\Core\Controller
;
use
App\Core\Request
;
use
App\Core\App
;
use
App\Core\App
;
use
App\Core\Response
;
use
App\Core\Response
;
use
App\Modules\Accounting\Models\BankAccount
;
use
App\Modules\Accounting\Models\BankAccount
;
...
@@ -98,11 +99,11 @@ class BankAccountController extends Controller
...
@@ -98,11 +99,11 @@ class BankAccountController extends Controller
return
$this
->
redirect
(
'/accounting/bank-accounts'
);
return
$this
->
redirect
(
'/accounting/bank-accounts'
);
}
}
public
function
edit
(
int
$id
)
:
Response
public
function
edit
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.bank_account.manage'
);
$this
->
authorize
(
'accounting.bank_account.manage'
);
$account
=
BankAccount
::
findOrFail
(
$id
);
$account
=
BankAccount
::
findOrFail
(
(
int
)
$id
);
$glAccounts
=
Account
::
query
()
$glAccounts
=
Account
::
query
()
->
where
(
'is_archived'
,
'='
,
0
)
->
where
(
'is_archived'
,
'='
,
0
)
...
@@ -117,11 +118,11 @@ class BankAccountController extends Controller
...
@@ -117,11 +118,11 @@ class BankAccountController extends Controller
]);
]);
}
}
public
function
update
(
int
$id
)
:
Response
public
function
update
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.bank_account.manage'
);
$this
->
authorize
(
'accounting.bank_account.manage'
);
$account
=
BankAccount
::
findOrFail
(
$id
);
$account
=
BankAccount
::
findOrFail
(
(
int
)
$id
);
$data
=
$this
->
validate
(
$_POST
,
[
$data
=
$this
->
validate
(
$_POST
,
[
'account_name_ar'
=>
'required'
,
'account_name_ar'
=>
'required'
,
...
...
app/Modules/Accounting/Controllers/BankReconciliationController.php
View file @
a3fd26ba
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace
App\Modules\Accounting\Controllers
;
namespace
App\Modules\Accounting\Controllers
;
use
App\Core\Controller
;
use
App\Core\Controller
;
use
App\Core\Request
;
use
App\Core\App
;
use
App\Core\App
;
use
App\Core\Response
;
use
App\Core\Response
;
use
App\Modules\Accounting\Models\BankReconciliation
;
use
App\Modules\Accounting\Models\BankReconciliation
;
...
@@ -67,11 +68,11 @@ class BankReconciliationController extends Controller
...
@@ -67,11 +68,11 @@ class BankReconciliationController extends Controller
return
$this
->
redirect
(
'/accounting/bank-reconciliation/create'
);
return
$this
->
redirect
(
'/accounting/bank-reconciliation/create'
);
}
}
public
function
show
(
int
$id
)
:
Response
public
function
show
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.bank_recon.view'
);
$this
->
authorize
(
'accounting.bank_recon.view'
);
$recon
=
BankReconciliation
::
findOrFail
(
$id
);
$recon
=
BankReconciliation
::
findOrFail
(
(
int
)
$id
);
$items
=
$recon
->
items
();
$items
=
$recon
->
items
();
$bankAccount
=
BankAccount
::
find
((
int
)
$recon
->
bank_account_id
);
$bankAccount
=
BankAccount
::
find
((
int
)
$recon
->
bank_account_id
);
...
@@ -88,7 +89,7 @@ class BankReconciliationController extends Controller
...
@@ -88,7 +89,7 @@ class BankReconciliationController extends Controller
]);
]);
}
}
public
function
addItem
(
int
$id
)
:
Response
public
function
addItem
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.bank_recon.manage'
);
$this
->
authorize
(
'accounting.bank_recon.manage'
);
...
@@ -98,7 +99,7 @@ class BankReconciliationController extends Controller
...
@@ -98,7 +99,7 @@ class BankReconciliationController extends Controller
'amount'
=>
'required|numeric'
,
'amount'
=>
'required|numeric'
,
]);
]);
$result
=
BankReconciliationService
::
addItem
(
$id
,
$_POST
);
$result
=
BankReconciliationService
::
addItem
(
(
int
)
$id
,
$_POST
);
$session
=
App
::
getInstance
()
->
session
();
$session
=
App
::
getInstance
()
->
session
();
if
(
$result
[
'success'
])
{
if
(
$result
[
'success'
])
{
...
@@ -110,11 +111,11 @@ class BankReconciliationController extends Controller
...
@@ -110,11 +111,11 @@ class BankReconciliationController extends Controller
return
$this
->
redirect
(
'/accounting/bank-reconciliation/'
.
$id
);
return
$this
->
redirect
(
'/accounting/bank-reconciliation/'
.
$id
);
}
}
public
function
complete
(
int
$id
)
:
Response
public
function
complete
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.bank_recon.manage'
);
$this
->
authorize
(
'accounting.bank_recon.manage'
);
$result
=
BankReconciliationService
::
complete
(
$id
);
$result
=
BankReconciliationService
::
complete
(
(
int
)
$id
);
$session
=
App
::
getInstance
()
->
session
();
$session
=
App
::
getInstance
()
->
session
();
if
(
$result
[
'success'
])
{
if
(
$result
[
'success'
])
{
...
...
app/Modules/Accounting/Controllers/ChartOfAccountsController.php
View file @
a3fd26ba
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace
App\Modules\Accounting\Controllers
;
namespace
App\Modules\Accounting\Controllers
;
use
App\Core\Controller
;
use
App\Core\Controller
;
use
App\Core\Request
;
use
App\Core\App
;
use
App\Core\App
;
use
App\Core\Response
;
use
App\Core\Response
;
use
App\Modules\Accounting\Models\Account
;
use
App\Modules\Accounting\Models\Account
;
...
@@ -89,16 +90,16 @@ class ChartOfAccountsController extends Controller
...
@@ -89,16 +90,16 @@ class ChartOfAccountsController extends Controller
return
$this
->
redirect
(
'/accounting/chart-of-accounts'
);
return
$this
->
redirect
(
'/accounting/chart-of-accounts'
);
}
}
public
function
edit
(
int
$id
)
:
Response
public
function
edit
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.coa.manage'
);
$this
->
authorize
(
'accounting.coa.manage'
);
$account
=
Account
::
findOrFail
(
$id
);
$account
=
Account
::
findOrFail
(
(
int
)
$id
);
$parentAccounts
=
Account
::
query
()
$parentAccounts
=
Account
::
query
()
->
where
(
'is_archived'
,
'='
,
0
)
->
where
(
'is_archived'
,
'='
,
0
)
->
where
(
'is_header'
,
'='
,
1
)
->
where
(
'is_header'
,
'='
,
1
)
->
where
(
'id'
,
'!='
,
$id
)
->
where
(
'id'
,
'!='
,
(
int
)
$id
)
->
orderBy
(
'account_code'
,
'ASC'
)
->
orderBy
(
'account_code'
,
'ASC'
)
->
get
();
->
get
();
...
@@ -111,11 +112,11 @@ class ChartOfAccountsController extends Controller
...
@@ -111,11 +112,11 @@ class ChartOfAccountsController extends Controller
]);
]);
}
}
public
function
update
(
int
$id
)
:
Response
public
function
update
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.coa.manage'
);
$this
->
authorize
(
'accounting.coa.manage'
);
$account
=
Account
::
findOrFail
(
$id
);
$account
=
Account
::
findOrFail
(
(
int
)
$id
);
$data
=
$this
->
validate
(
$_POST
,
[
$data
=
$this
->
validate
(
$_POST
,
[
'name_ar'
=>
'required'
,
'name_ar'
=>
'required'
,
...
@@ -128,7 +129,7 @@ class ChartOfAccountsController extends Controller
...
@@ -128,7 +129,7 @@ class ChartOfAccountsController extends Controller
if
((
int
)
$account
->
is_system
===
1
&&
(
$_POST
[
'account_code'
]
??
''
)
!==
$account
->
account_code
)
{
if
((
int
)
$account
->
is_system
===
1
&&
(
$_POST
[
'account_code'
]
??
''
)
!==
$account
->
account_code
)
{
$session
=
App
::
getInstance
()
->
session
();
$session
=
App
::
getInstance
()
->
session
();
$session
->
flash
(
'_alerts'
,
[[
'type'
=>
'error'
,
'message'
=>
'لا يمكن تعديل كود حساب نظامي'
]]);
$session
->
flash
(
'_alerts'
,
[[
'type'
=>
'error'
,
'message'
=>
'لا يمكن تعديل كود حساب نظامي'
]]);
return
$this
->
redirect
(
'/accounting/chart-of-accounts/'
.
$id
.
'/edit'
);
return
$this
->
redirect
(
'/accounting/chart-of-accounts/'
.
(
int
)
$id
.
'/edit'
);
}
}
$account
->
update
([
$account
->
update
([
...
...
app/Modules/Accounting/Controllers/CostCenterController.php
View file @
a3fd26ba
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace
App\Modules\Accounting\Controllers
;
namespace
App\Modules\Accounting\Controllers
;
use
App\Core\Controller
;
use
App\Core\Controller
;
use
App\Core\Request
;
use
App\Core\App
;
use
App\Core\App
;
use
App\Core\Response
;
use
App\Core\Response
;
use
App\Modules\Accounting\Models\CostCenter
;
use
App\Modules\Accounting\Models\CostCenter
;
...
@@ -80,18 +81,18 @@ class CostCenterController extends Controller
...
@@ -80,18 +81,18 @@ class CostCenterController extends Controller
return
$this
->
redirect
(
'/accounting/cost-centers'
);
return
$this
->
redirect
(
'/accounting/cost-centers'
);
}
}
public
function
edit
(
int
$id
)
:
Response
public
function
edit
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.cost_center.manage'
);
$this
->
authorize
(
'accounting.cost_center.manage'
);
$center
=
CostCenter
::
findOrFail
(
$id
);
$center
=
CostCenter
::
findOrFail
(
(
int
)
$id
);
$db
=
App
::
getInstance
()
->
db
();
$db
=
App
::
getInstance
()
->
db
();
$branches
=
$db
->
select
(
"SELECT id, name_ar, name_en FROM branches WHERE is_active = 1 ORDER BY name_ar"
);
$branches
=
$db
->
select
(
"SELECT id, name_ar, name_en FROM branches WHERE is_active = 1 ORDER BY name_ar"
);
$parents
=
CostCenter
::
query
()
$parents
=
CostCenter
::
query
()
->
where
(
'is_archived'
,
'='
,
0
)
->
where
(
'is_archived'
,
'='
,
0
)
->
where
(
'id'
,
'!='
,
$id
)
->
where
(
'id'
,
'!='
,
(
int
)
$id
)
->
orderBy
(
'code'
,
'ASC'
)
->
orderBy
(
'code'
,
'ASC'
)
->
get
();
->
get
();
...
@@ -102,11 +103,11 @@ class CostCenterController extends Controller
...
@@ -102,11 +103,11 @@ class CostCenterController extends Controller
]);
]);
}
}
public
function
update
(
int
$id
)
:
Response
public
function
update
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.cost_center.manage'
);
$this
->
authorize
(
'accounting.cost_center.manage'
);
$center
=
CostCenter
::
findOrFail
(
$id
);
$center
=
CostCenter
::
findOrFail
(
(
int
)
$id
);
$data
=
$this
->
validate
(
$_POST
,
[
$data
=
$this
->
validate
(
$_POST
,
[
'name_ar'
=>
'required'
,
'name_ar'
=>
'required'
,
...
...
app/Modules/Accounting/Controllers/FiscalYearController.php
View file @
a3fd26ba
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace
App\Modules\Accounting\Controllers
;
namespace
App\Modules\Accounting\Controllers
;
use
App\Core\Controller
;
use
App\Core\Controller
;
use
App\Core\Request
;
use
App\Core\App
;
use
App\Core\App
;
use
App\Core\Response
;
use
App\Core\Response
;
use
App\Modules\Accounting\Models\FiscalYear
;
use
App\Modules\Accounting\Models\FiscalYear
;
...
@@ -92,12 +93,12 @@ class FiscalYearController extends Controller
...
@@ -92,12 +93,12 @@ class FiscalYearController extends Controller
return
$this
->
redirect
(
'/accounting/fiscal-years'
);
return
$this
->
redirect
(
'/accounting/fiscal-years'
);
}
}
public
function
show
(
int
$id
)
:
Response
public
function
show
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.fiscal_year.view'
);
$this
->
authorize
(
'accounting.fiscal_year.view'
);
$fy
=
FiscalYear
::
findOrFail
(
$id
);
$fy
=
FiscalYear
::
findOrFail
(
(
int
)
$id
);
$periods
=
PeriodClosingService
::
getPeriodSummary
(
$id
);
$periods
=
PeriodClosingService
::
getPeriodSummary
(
(
int
)
$id
);
return
$this
->
view
(
'Accounting/Views/fiscal_years/show'
,
[
return
$this
->
view
(
'Accounting/Views/fiscal_years/show'
,
[
'fiscal_year'
=>
$fy
->
toArray
(),
'fiscal_year'
=>
$fy
->
toArray
(),
...
@@ -105,11 +106,11 @@ class FiscalYearController extends Controller
...
@@ -105,11 +106,11 @@ class FiscalYearController extends Controller
]);
]);
}
}
public
function
close
(
int
$id
)
:
Response
public
function
close
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.fiscal_year.close'
);
$this
->
authorize
(
'accounting.fiscal_year.close'
);
$result
=
PeriodClosingService
::
closeFiscalYear
(
$id
);
$result
=
PeriodClosingService
::
closeFiscalYear
(
(
int
)
$id
);
$session
=
App
::
getInstance
()
->
session
();
$session
=
App
::
getInstance
()
->
session
();
if
(
$result
[
'success'
])
{
if
(
$result
[
'success'
])
{
...
@@ -118,6 +119,6 @@ class FiscalYearController extends Controller
...
@@ -118,6 +119,6 @@ class FiscalYearController extends Controller
$session
->
flash
(
'_alerts'
,
[[
'type'
=>
'error'
,
'message'
=>
$result
[
'error'
]]]);
$session
->
flash
(
'_alerts'
,
[[
'type'
=>
'error'
,
'message'
=>
$result
[
'error'
]]]);
}
}
return
$this
->
redirect
(
'/accounting/fiscal-years/'
.
$id
);
return
$this
->
redirect
(
'/accounting/fiscal-years/'
.
(
int
)
$id
);
}
}
}
}
app/Modules/Accounting/Controllers/JournalEntryController.php
View file @
a3fd26ba
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
...
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace
App\Modules\Accounting\Controllers
;
namespace
App\Modules\Accounting\Controllers
;
use
App\Core\Controller
;
use
App\Core\Controller
;
use
App\Core\Request
;
use
App\Core\App
;
use
App\Core\App
;
use
App\Core\Response
;
use
App\Core\Response
;
use
App\Modules\Accounting\Models\JournalEntry
;
use
App\Modules\Accounting\Models\JournalEntry
;
...
@@ -116,12 +117,12 @@ class JournalEntryController extends Controller
...
@@ -116,12 +117,12 @@ class JournalEntryController extends Controller
return
$this
->
redirect
(
'/accounting/journal-entries/create'
);
return
$this
->
redirect
(
'/accounting/journal-entries/create'
);
}
}
public
function
show
(
int
$id
)
:
Response
public
function
show
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.journal.view'
);
$this
->
authorize
(
'accounting.journal.view'
);
$entry
=
JournalEntry
::
findOrFail
(
$id
);
$entry
=
JournalEntry
::
findOrFail
(
(
int
)
$id
);
$lines
=
JournalEntryLine
::
getByJournalEntry
(
$id
);
$lines
=
JournalEntryLine
::
getByJournalEntry
(
(
int
)
$id
);
// Get employee names
// Get employee names
$db
=
App
::
getInstance
()
->
db
();
$db
=
App
::
getInstance
()
->
db
();
...
@@ -142,11 +143,11 @@ class JournalEntryController extends Controller
...
@@ -142,11 +143,11 @@ class JournalEntryController extends Controller
]);
]);
}
}
public
function
post
(
int
$id
)
:
Response
public
function
post
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.journal.post'
);
$this
->
authorize
(
'accounting.journal.post'
);
$result
=
JournalService
::
postEntry
(
$id
);
$result
=
JournalService
::
postEntry
(
(
int
)
$id
);
$session
=
App
::
getInstance
()
->
session
();
$session
=
App
::
getInstance
()
->
session
();
if
(
$result
[
'success'
])
{
if
(
$result
[
'success'
])
{
...
@@ -155,16 +156,16 @@ class JournalEntryController extends Controller
...
@@ -155,16 +156,16 @@ class JournalEntryController extends Controller
$session
->
flash
(
'_alerts'
,
[[
'type'
=>
'error'
,
'message'
=>
$result
[
'error'
]]]);
$session
->
flash
(
'_alerts'
,
[[
'type'
=>
'error'
,
'message'
=>
$result
[
'error'
]]]);
}
}
return
$this
->
redirect
(
'/accounting/journal-entries/'
.
$id
);
return
$this
->
redirect
(
'/accounting/journal-entries/'
.
(
int
)
$id
);
}
}
public
function
reverse
(
int
$id
)
:
Response
public
function
reverse
(
Request
$request
,
string
$id
)
:
Response
{
{
$this
->
authorize
(
'accounting.journal.reverse'
);
$this
->
authorize
(
'accounting.journal.reverse'
);
$reason
=
$
_POST
[
'reason'
]
??
'عكس قيد'
;
$reason
=
$
request
->
post
(
'reason'
,
'عكس قيد'
)
;
$result
=
JournalService
::
reverseEntry
(
$id
,
$reason
);
$result
=
JournalService
::
reverseEntry
(
(
int
)
$id
,
$reason
);
$session
=
App
::
getInstance
()
->
session
();
$session
=
App
::
getInstance
()
->
session
();
if
(
$result
[
'success'
])
{
if
(
$result
[
'success'
])
{
...
@@ -173,7 +174,7 @@ class JournalEntryController extends Controller
...
@@ -173,7 +174,7 @@ class JournalEntryController extends Controller
$session
->
flash
(
'_alerts'
,
[[
'type'
=>
'error'
,
'message'
=>
$result
[
'error'
]]]);
$session
->
flash
(
'_alerts'
,
[[
'type'
=>
'error'
,
'message'
=>
$result
[
'error'
]]]);
}
}
return
$this
->
redirect
(
'/accounting/journal-entries/'
.
$id
);
return
$this
->
redirect
(
'/accounting/journal-entries/'
.
(
int
)
$id
);
}
}
public
function
searchAccounts
()
:
Response
public
function
searchAccounts
()
:
Response
...
...
app/Modules/Accounting/Services/PeriodClosingService.php
View file @
a3fd26ba
...
@@ -180,11 +180,24 @@ final class PeriodClosingService
...
@@ -180,11 +180,24 @@ final class PeriodClosingService
}
}
// Check all monthly periods are closed
// Check all monthly periods are closed
$openPeriods
=
$db
->
selectOne
(
$startDate
=
$fiscalYear
->
start_date
;
"SELECT COUNT(*) as cnt FROM period_closings
$endDate
=
$fiscalYear
->
end_date
;
WHERE fiscal_year_id = ? AND status != 'closed' AND is_archived = 0"
,
$start
=
new
\DateTime
(
$startDate
);
[
$fiscalYearId
]
$end
=
new
\DateTime
(
$endDate
);
);
$unclosedPeriods
=
[];
while
(
$start
<=
$end
)
{
$period
=
$start
->
format
(
'Y-m'
);
if
(
!
PeriodClosing
::
isPeriodClosed
(
$fiscalYearId
,
$period
))
{
$unclosedPeriods
[]
=
$period
;
}
$start
->
modify
(
'first day of next month'
);
}
if
(
!
empty
(
$unclosedPeriods
))
{
return
[
'success'
=>
false
,
'error'
=>
'يوجد فترات غير مغلقة: '
.
implode
(
', '
,
$unclosedPeriods
)
.
' — يجب إغلاقها أولاً'
,
];
}
// Get income statement for the entire year
// Get income statement for the entire year
$incomeStatement
=
FinancialReportService
::
getIncomeStatement
(
$incomeStatement
=
FinancialReportService
::
getIncomeStatement
(
...
@@ -202,72 +215,72 @@ final class PeriodClosingService
...
@@ -202,72 +215,72 @@ final class PeriodClosingService
return
[
'success'
=>
false
,
'error'
=>
'حساب الأرباح المحتجزة (3102) غير موجود'
];
return
[
'success'
=>
false
,
'error'
=>
'حساب الأرباح المحتجزة (3102) غير موجود'
];
}
}
$db
->
beginTransaction
();
$lines
=
[];
try
{
$lines
=
[];
// Close revenue accounts (debit revenue accounts to zero them out)
foreach
(
$incomeStatement
[
'revenue'
]
as
$rev
)
{
if
(
bccomp
((
string
)
$rev
[
'balance'
],
'0.00'
,
2
)
!==
0
)
{
$lines
[]
=
[
'account_id'
=>
(
int
)
$rev
[
'id'
],
'debit'
=>
(
string
)
$rev
[
'balance'
],
'credit'
=>
'0.00'
,
'description_ar'
=>
'إقفال حساب إيرادات — '
.
$rev
[
'name_ar'
],
];
}
}
// Close expense accounts (credit expense accounts to zero them out)
// Close revenue accounts (debit revenue accounts to zero them out)
foreach
(
$incomeStatement
[
'expenses'
]
as
$exp
)
{
foreach
(
$incomeStatement
[
'revenue'
]
as
$rev
)
{
if
(
bccomp
((
string
)
$exp
[
'balance'
],
'0.00'
,
2
)
!==
0
)
{
if
(
bccomp
((
string
)
$rev
[
'balance'
],
'0.00'
,
2
)
!==
0
)
{
$lines
[]
=
[
$lines
[]
=
[
'account_id'
=>
(
int
)
$exp
[
'id'
],
'account_id'
=>
(
int
)
$rev
[
'id'
],
'debit'
=>
'0.00'
,
'debit'
=>
(
string
)
$rev
[
'balance'
],
'credit'
=>
(
string
)
$exp
[
'balance'
],
'credit'
=>
'0.00'
,
'description_ar'
=>
'إقفال حساب مصروفات — '
.
$exp
[
'name_ar'
],
'description_ar'
=>
'إقفال حساب إيرادات — '
.
$rev
[
'name_ar'
],
];
];
}
}
}
}
// Net income to retained earnings
// Close expense accounts (credit expense accounts to zero them out)
if
(
bccomp
(
$netIncome
,
'0.00'
,
2
)
>
0
)
{
foreach
(
$incomeStatement
[
'expenses'
]
as
$exp
)
{
// Profit: Cr. Retained Earnings
if
(
bccomp
((
string
)
$exp
[
'balance'
],
'0.00'
,
2
)
!==
0
)
{
$lines
[]
=
[
$lines
[]
=
[
'account_id'
=>
(
int
)
$
retainedEarnings
[
'id'
],
'account_id'
=>
(
int
)
$
exp
[
'id'
],
'debit'
=>
'0.00'
,
'debit'
=>
'0.00'
,
'credit'
=>
$netIncome
,
'credit'
=>
(
string
)
$exp
[
'balance'
],
'description_ar'
=>
'صافي ربح السنة المالية — أرباح محتجزة'
,
'description_ar'
=>
'إقفال حساب مصروفات — '
.
$exp
[
'name_ar'
],
];
}
elseif
(
bccomp
(
$netIncome
,
'0.00'
,
2
)
<
0
)
{
// Loss: Dr. Retained Earnings
$lines
[]
=
[
'account_id'
=>
(
int
)
$retainedEarnings
[
'id'
],
'debit'
=>
bcmul
(
$netIncome
,
'-1'
,
2
),
'credit'
=>
'0.00'
,
'description_ar'
=>
'صافي خسارة السنة المالية — أرباح محتجزة'
,
];
];
}
}
}
if
(
empty
(
$lines
))
{
// Net income to retained earnings
return
[
'success'
=>
false
,
'error'
=>
'لا توجد حسابات إيرادات أو مصروفات لإقفالها'
];
if
(
bccomp
(
$netIncome
,
'0.00'
,
2
)
>
0
)
{
}
// Profit: Cr. Retained Earnings
$lines
[]
=
[
'account_id'
=>
(
int
)
$retainedEarnings
[
'id'
],
'debit'
=>
'0.00'
,
'credit'
=>
$netIncome
,
'description_ar'
=>
'صافي ربح السنة المالية — أرباح محتجزة'
,
];
}
elseif
(
bccomp
(
$netIncome
,
'0.00'
,
2
)
<
0
)
{
// Loss: Dr. Retained Earnings
$lines
[]
=
[
'account_id'
=>
(
int
)
$retainedEarnings
[
'id'
],
'debit'
=>
bcmul
(
$netIncome
,
'-1'
,
2
),
'credit'
=>
'0.00'
,
'description_ar'
=>
'صافي خسارة السنة المالية — أرباح محتجزة'
,
];
}
$closingResult
=
JournalService
::
createEntry
([
if
(
empty
(
$lines
))
{
'entry_date'
=>
$fiscalYear
->
end_date
,
return
[
'success'
=>
false
,
'error'
=>
'لا توجد حسابات إيرادات أو مصروفات لإقفالها'
];
'description_ar'
=>
'قيد إقفال السنة المالية '
.
$fiscalYear
->
name_ar
,
}
'description_en'
=>
'Year-end closing entry — '
.
$fiscalYear
->
name_en
,
'reference_type'
=>
'closing'
,
// Step 1: Create closing journal entry (JournalService manages its own transaction)
'source_module'
=>
'accounting'
,
$closingResult
=
JournalService
::
createEntry
([
'is_auto_generated'
=>
1
,
'entry_date'
=>
$fiscalYear
->
end_date
,
],
$lines
,
true
);
'description_ar'
=>
'قيد إقفال السنة المالية '
.
$fiscalYear
->
name_ar
,
'description_en'
=>
'Year-end closing entry — '
.
$fiscalYear
->
name_en
,
if
(
!
$closingResult
[
'success'
])
{
'reference_type'
=>
'closing'
,
$db
->
rollBack
();
'source_module'
=>
'accounting'
,
return
$closingResult
;
'is_auto_generated'
=>
1
,
}
],
$lines
,
true
);
if
(
!
$closingResult
[
'success'
])
{
return
$closingResult
;
}
// Update fiscal year status
// Step 2: Update fiscal year status and create year-end period record
$db
->
beginTransaction
();
try
{
$db
->
update
(
'fiscal_years'
,
[
$db
->
update
(
'fiscal_years'
,
[
'status'
=>
'closed'
,
'status'
=>
'closed'
,
'is_current'
=>
0
,
'is_current'
=>
0
,
...
@@ -276,7 +289,6 @@ final class PeriodClosingService
...
@@ -276,7 +289,6 @@ final class PeriodClosingService
'updated_at'
=>
date
(
'Y-m-d H:i:s'
),
'updated_at'
=>
date
(
'Y-m-d H:i:s'
),
],
'`id` = ?'
,
[
$fiscalYearId
]);
],
'`id` = ?'
,
[
$fiscalYearId
]);
// Create year-end period closing record
$endPeriod
=
substr
(
$fiscalYear
->
end_date
,
0
,
7
);
$endPeriod
=
substr
(
$fiscalYear
->
end_date
,
0
,
7
);
$db
->
insert
(
'period_closings'
,
[
$db
->
insert
(
'period_closings'
,
[
'fiscal_year_id'
=>
$fiscalYearId
,
'fiscal_year_id'
=>
$fiscalYearId
,
...
@@ -294,29 +306,29 @@ final class PeriodClosingService
...
@@ -294,29 +306,29 @@ final class PeriodClosingService
]);
]);
$db
->
commit
();
$db
->
commit
();
EventBus
::
dispatch
(
'accounting.fiscal_year.closed'
,
[
'fiscal_year_id'
=>
$fiscalYearId
,
'net_income'
=>
$netIncome
,
'closing_entry'
=>
$closingResult
[
'journal_entry_id'
],
]);
Logger
::
info
(
"Fiscal year closed"
,
[
'fiscal_year_id'
=>
$fiscalYearId
,
'net_income'
=>
$netIncome
,
]);
return
[
'success'
=>
true
,
'net_income'
=>
$netIncome
,
'closing_entry_id'
=>
$closingResult
[
'journal_entry_id'
],
'closing_entry_num'
=>
$closingResult
[
'entry_number'
],
];
}
catch
(
\Throwable
$e
)
{
}
catch
(
\Throwable
$e
)
{
$db
->
rollBack
();
$db
->
rollBack
();
Logger
::
error
(
"Fiscal year
closing failed
: "
.
$e
->
getMessage
());
Logger
::
error
(
"Fiscal year
status update failed (closing entry already posted)
: "
.
$e
->
getMessage
());
return
[
'success'
=>
false
,
'error'
=>
'
فشل إقفال
السنة المالية: '
.
$e
->
getMessage
()];
return
[
'success'
=>
false
,
'error'
=>
'
تم ترحيل قيد الإقفال لكن فشل تحديث حالة
السنة المالية: '
.
$e
->
getMessage
()];
}
}
EventBus
::
dispatch
(
'accounting.fiscal_year.closed'
,
[
'fiscal_year_id'
=>
$fiscalYearId
,
'net_income'
=>
$netIncome
,
'closing_entry'
=>
$closingResult
[
'journal_entry_id'
],
]);
Logger
::
info
(
"Fiscal year closed"
,
[
'fiscal_year_id'
=>
$fiscalYearId
,
'net_income'
=>
$netIncome
,
]);
return
[
'success'
=>
true
,
'net_income'
=>
$netIncome
,
'closing_entry_id'
=>
$closingResult
[
'journal_entry_id'
],
'closing_entry_num'
=>
$closingResult
[
'entry_number'
],
];
}
}
/**
/**
...
...
app/Modules/Accounting/Views/reports/accounts_payable.php
View file @
a3fd26ba
...
@@ -50,7 +50,7 @@
...
@@ -50,7 +50,7 @@
</thead>
</thead>
<tbody>
<tbody>
<?php
foreach
(
$outstanding
as
$ap
)
:
?>
<?php
foreach
(
$outstanding
as
$ap
)
:
?>
<?php
$isOverdue
=
strtotime
(
$ap
[
'due_date'
])
<
time
();
?>
<?php
$isOverdue
=
!
empty
(
$ap
[
'due_date'
])
&&
strtotime
(
$ap
[
'due_date'
])
<
time
();
?>
<tr>
<tr>
<td>
<?=
e
(
$ap
[
'supplier_name'
]
??
'—'
)
?>
</td>
<td>
<?=
e
(
$ap
[
'supplier_name'
]
??
'—'
)
?>
</td>
<td
style=
"direction:ltr;text-align:right;"
>
<?=
e
(
$ap
[
'invoice_number'
])
?>
</td>
<td
style=
"direction:ltr;text-align:right;"
>
<?=
e
(
$ap
[
'invoice_number'
])
?>
</td>
...
...
app/Modules/Accounting/Views/reports/accounts_receivable.php
View file @
a3fd26ba
...
@@ -60,7 +60,7 @@
...
@@ -60,7 +60,7 @@
'membership_fee'
=>
'عضوية'
,
'membership_fee'
=>
'عضوية'
,
default
=>
$ar
[
'document_type'
]
??
'—'
,
default
=>
$ar
[
'document_type'
]
??
'—'
,
};
};
$isOverdue
=
strtotime
(
$ar
[
'due_date'
])
<
time
();
$isOverdue
=
!
empty
(
$ar
[
'due_date'
])
&&
strtotime
(
$ar
[
'due_date'
])
<
time
();
?>
?>
<tr>
<tr>
<td>
<?=
e
(
$ar
[
'member_name'
]
??
'—'
)
?>
</td>
<td>
<?=
e
(
$ar
[
'member_name'
]
??
'—'
)
?>
</td>
...
...
app/Modules/Accounting/Views/reports/general_ledger.php
View file @
a3fd26ba
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
<form
method=
"GET"
action=
"/accounting/reports/general-ledger"
style=
"display:flex;gap:10px;flex-wrap:wrap;align-items:end;"
>
<form
method=
"GET"
action=
"/accounting/reports/general-ledger"
style=
"display:flex;gap:10px;flex-wrap:wrap;align-items:end;"
>
<div
style=
"flex:2;"
>
<div
style=
"flex:2;"
>
<label
class=
"form-label"
style=
"font-size:12px;"
>
الحساب
</label>
<label
class=
"form-label"
style=
"font-size:12px;"
>
الحساب
</label>
<input
type=
"number"
name=
"account_id"
class=
"form-input"
value=
"
<?=
$account_id
?>
"
placeholder=
"رقم الحساب (ID)"
>
<input
type=
"number"
name=
"account_id"
class=
"form-input"
value=
"
<?=
e
(
$account_id
)
?>
"
placeholder=
"رقم الحساب (ID)"
>
</div>
</div>
<div>
<div>
<label
class=
"form-label"
style=
"font-size:12px;"
>
من تاريخ
</label>
<label
class=
"form-label"
style=
"font-size:12px;"
>
من تاريخ
</label>
...
...
app/Modules/Accounting/Views/reports/member_statement.php
View file @
a3fd26ba
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
<form
method=
"GET"
action=
"/accounting/reports/member-statement"
style=
"display:flex;gap:10px;flex-wrap:wrap;align-items:end;"
>
<form
method=
"GET"
action=
"/accounting/reports/member-statement"
style=
"display:flex;gap:10px;flex-wrap:wrap;align-items:end;"
>
<div>
<div>
<label
class=
"form-label"
style=
"font-size:12px;"
>
رقم العضو
</label>
<label
class=
"form-label"
style=
"font-size:12px;"
>
رقم العضو
</label>
<input
type=
"number"
name=
"member_id"
class=
"form-input"
value=
"
<?=
$member_id
?>
"
placeholder=
"ID العضو"
>
<input
type=
"number"
name=
"member_id"
class=
"form-input"
value=
"
<?=
e
(
$member_id
)
?>
"
placeholder=
"ID العضو"
>
</div>
</div>
<div>
<div>
<label
class=
"form-label"
style=
"font-size:12px;"
>
من تاريخ
</label>
<label
class=
"form-label"
style=
"font-size:12px;"
>
من تاريخ
</label>
...
...
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