110 lines
3.5 KiB
PHP
110 lines
3.5 KiB
PHP
<?php
|
|
require_once __DIR__ . '/BasePosting.php';
|
|
|
|
class PaymentPosting extends BasePosting
|
|
{
|
|
protected function getDocType(): string { return 'payment'; }
|
|
|
|
public function build(int $id, ?int $formula_id = null): array
|
|
{
|
|
$doc = $this->fetchDocument($id);
|
|
$formula = $this->resolveFormula($this->getDocType(), $formula_id);
|
|
$doc_date = $this->getDocDate($doc);
|
|
$period = substr($doc_date, 0, 7);
|
|
$dept_amounts = $this->getDepartmentAmounts($id);
|
|
|
|
$lines = [];
|
|
foreach ($dept_amounts as $dept_id => $amount) {
|
|
if (abs($amount) <= 0.0001) continue;
|
|
$is_negative = $amount < 0;
|
|
$line_amount = abs($amount);
|
|
|
|
foreach ($formula['items'] as $item) {
|
|
if ($item['amount_key'] === 'tax') continue;
|
|
|
|
$drcr = $item['drcr'];
|
|
if ($is_negative) {
|
|
$drcr = $drcr === 'D' ? 'C' : 'D';
|
|
}
|
|
|
|
$lines[] = [
|
|
'account_code' => $item['account_code'],
|
|
'department_id' => (int)$dept_id,
|
|
'debit' => $drcr === 'D' ? $line_amount : 0.0,
|
|
'credit' => $drcr === 'C' ? $line_amount : 0.0,
|
|
'description' => (string)($item['description'] ?? ''),
|
|
];
|
|
}
|
|
}
|
|
|
|
return [
|
|
'formula_id' => (int)$formula['id'],
|
|
'period' => $period,
|
|
'doc_date' => $doc_date,
|
|
'lines' => $lines,
|
|
];
|
|
}
|
|
|
|
protected function fetchDocument(int $id): array
|
|
{
|
|
$sth = $this->pdo->prepare(
|
|
"SELECT r.*, COALESCE(c.contact_name, '') AS contact_name
|
|
FROM td_payment r
|
|
LEFT JOIN md_contact c
|
|
ON c.company_id = r.company_id AND c.id = r.contact_id
|
|
WHERE r.company_id = :cid AND r.id = :id
|
|
LIMIT 1"
|
|
);
|
|
$sth->execute([':cid' => $this->companyId, ':id' => $id]);
|
|
$doc = $sth->fetch(PDO::FETCH_ASSOC);
|
|
if (!$doc) throw new Exception("Payment #{$id} not found.");
|
|
return $doc;
|
|
}
|
|
|
|
protected function getAmounts(array $doc): array
|
|
{
|
|
$amount = abs((float)$doc['amount']);
|
|
return [
|
|
'amount' => $amount,
|
|
'grand_total' => $amount,
|
|
'total' => $amount,
|
|
'tax' => 0.0,
|
|
];
|
|
}
|
|
|
|
protected function getDocDate(array $doc): string
|
|
{
|
|
return $doc['payment_date'] ?? date('Y-m-d');
|
|
}
|
|
|
|
private function getDepartmentAmounts(int $payment_id): array
|
|
{
|
|
$sth = $this->pdo->prepare(
|
|
"SELECT pi.department_id,
|
|
pi.doc_type,
|
|
pi.amount
|
|
FROM td_payment_item pi
|
|
WHERE pi.company_id = :cid
|
|
AND pi.payment_id = :payment_id"
|
|
);
|
|
$sth->execute([
|
|
':cid' => $this->companyId,
|
|
':payment_id' => $payment_id,
|
|
]);
|
|
|
|
$dept_amounts = [];
|
|
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $line) {
|
|
$dept_id = (int)($line['department_id'] ?? 0);
|
|
$amount = abs((float)($line['amount'] ?? 0));
|
|
if ($line['doc_type'] === 'supplier_credit_note') {
|
|
$amount *= -1;
|
|
}
|
|
$dept_amounts[$dept_id] = ($dept_amounts[$dept_id] ?? 0) + $amount;
|
|
}
|
|
|
|
if (!$dept_amounts) throw new Exception("Payment #{$payment_id} has no allocation lines for GL posting.");
|
|
|
|
return $dept_amounts;
|
|
}
|
|
}
|