Fixes for tax summary

This commit is contained in:
David Bomba 2024-10-05 14:06:43 +10:00
parent a363831425
commit ebd77a5030
5 changed files with 68 additions and 15 deletions

View File

@ -452,6 +452,8 @@ class BaseExport
'billable' => 'task.billable',
'item_notes' => 'task.item_notes',
'time_log' => 'task.time_log',
'user' => 'task.user_id',
'assigned_user' => 'task.assigned_user_id',
];
protected array $forced_client_fields = [

View File

@ -22,7 +22,6 @@ class TaskDecorator extends Decorator implements DecoratorInterface
public function transform(string $key, mixed $entity): mixed
{
$task = false;
if($entity instanceof Task) {
$task = $entity;
} elseif($entity->task) {
@ -131,5 +130,13 @@ class TaskDecorator extends Decorator implements DecoratorInterface
return $task->project()->exists() ? $task->project->name : '';
}
public function assigned_user_id(Task $task)
{
return $task->assigned_user ? $task->assigned_user->present()->name() : '';
}
public function user_id(Task $task)
{
return $task->user ? $task->user->present()->name() : '';
}
}

View File

@ -78,6 +78,9 @@ class UpdateExpenseRequest extends Request
$input['currency_id'] = (string) $user->company()->settings->currency_id;
}
if(isset($input['exchange_rate']) && $input['exchange_rate'] == 0)
$input['exchnage_rate'] = 1;
/* Ensure the project is related */
if (array_key_exists('project_id', $input) && isset($input['project_id'])) {
$project = Project::withTrashed()->where('id', $input['project_id'])->company()->first();

View File

@ -46,7 +46,7 @@ trait ChartQueries
SUM(
CASE
WHEN expenses.currency_id = :company_currency THEN amount
ELSE expenses.amount * expenses.exchange_rate
ELSE expenses.amount * COALESCE(NULLIF(expenses.exchange_rate, 0), 1)
END
) AS amount
FROM expenses
@ -67,7 +67,7 @@ trait ChartQueries
SUM(
CASE
WHEN expenses.currency_id = :company_currency THEN amount
ELSE expenses.amount * expenses.exchange_rate
ELSE expenses.amount * COALESCE(NULLIF(expenses.exchange_rate, 0), 1)
END
) AS total,
expenses.date
@ -142,7 +142,7 @@ trait ChartQueries
$user_filter = $this->is_admin ? '' : 'AND payments.user_id = '.$this->user->id;
return DB::select("
SELECT sum((payments.amount - payments.refunded) / payments.exchange_rate) as amount,
SELECT sum((payments.amount - payments.refunded) / COALESCE(NULLIF(payments.exchange_rate, 0), 1)) as amount,
IFNULL(payments.currency_id, :company_currency) as currency_id
FROM payments
WHERE payments.company_id = :company_id
@ -166,7 +166,7 @@ trait ChartQueries
return DB::select("
SELECT
sum((payments.amount - payments.refunded) * payments.exchange_rate) as total,
sum((payments.amount - payments.refunded) * COALESCE(NULLIF(payments.exchange_rate, 0), 1)) as total,
payments.date
FROM payments
WHERE payments.company_id = :company_id
@ -243,7 +243,7 @@ trait ChartQueries
return DB::select("
SELECT
sum(invoices.balance / invoices.exchange_rate) as amount,
SUM(invoices.balance / COALESCE(NULLIF(invoices.exchange_rate, 0), 1)) as amount,
COUNT(invoices.id) as outstanding_count
FROM clients
JOIN invoices
@ -268,7 +268,7 @@ trait ChartQueries
return DB::select("
SELECT
sum((payments.amount - payments.refunded) * payments.exchange_rate) as paid_to_date
sum((payments.amount - payments.refunded) * COALESCE(NULLIF(payments.exchange_rate, 0), 1)) as paid_to_date
FROM payments
JOIN clients
ON payments.client_id=clients.id
@ -311,7 +311,7 @@ trait ChartQueries
return DB::select("
SELECT
SUM(invoices.amount / invoices.exchange_rate) as invoiced_amount
SUM(invoices.amount / COALESCE(NULLIF(invoices.exchange_rate, 0), 1)) as invoiced_amount
FROM clients
JOIN invoices ON invoices.client_id = clients.id
WHERE invoices.status_id IN (2,3,4)
@ -358,7 +358,7 @@ trait ChartQueries
return DB::select("
SELECT
SUM(invoices.balance / invoices.exchange_rate) as total,
SUM(invoices.balance / COALESCE(NULLIF(invoices.exchange_rate, 0), 1)) as total,
invoices.date
FROM clients
JOIN invoices
@ -412,7 +412,7 @@ trait ChartQueries
return DB::select("
SELECT
SUM(invoices.amount / invoices.exchange_rate) as total,
SUM(invoices.amount / COALESCE(NULLIF(invoices.exchange_rate, 0), 1)) as total,
invoices.date
FROM clients
JOIN invoices

View File

@ -96,6 +96,9 @@ class TaxSummaryReport extends BaseExport
$accrual_map = [];
$cash_map = [];
$accrual_invoice_map = [];
$cash_invoice_map = [];
foreach($query->cursor() as $invoice) {
$calc = $invoice->calc();
@ -105,12 +108,19 @@ class TaxSummaryReport extends BaseExport
//filter into two arrays for accrual + cash
foreach($taxes as $tax) {
$key = $tax['name'];
$tax_prorata = 0;
if(!isset($accrual_map[$key])) {
$accrual_map[$key]['tax_amount'] = 0;
}
$accrual_map[$key]['tax_amount'] += $tax['total'];
$accrual_invoice_map[] = [
'number' => ctrans('texts.invoice') . " " . $invoice->number,
'date' => $this->translateDate($invoice->date, $this->company->date_format(), $this->company->locale()),
'formatted' => Number::formatMoney($tax['total'], $this->company),
'tax' => Number::formatValue($tax['total'], $this->company->currency()),
];
//cash
$key = $tax['name'];
@ -123,10 +133,25 @@ class TaxSummaryReport extends BaseExport
try {
if($invoice->status_id == Invoice::STATUS_PAID) {
$tax_prorata = $tax['total'];
$cash_map[$key]['tax_amount'] += $tax['total'];
} else {
$cash_map[$key]['tax_amount'] += (($invoice->amount - $invoice->balance) / $invoice->balance) * $tax['total'] ?? 0;
$paid_amount = $invoice->amount - $invoice->balance;
$payment_ratio = $invoice->amount > 0 ? $paid_amount / $invoice->amount : 0;
$tax_prorata = round($payment_ratio * ($tax['total'] ?? 0),2);
$cash_map[$key]['tax_amount'] += $tax_prorata;
}
$cash_invoice_map[] = [
'number' => ctrans('texts.invoice') . " " . $invoice->number,
'date' => $this->translateDate($invoice->date, $this->company->date_format(), $this->company->locale()),
'formatted' => Number::formatMoney($tax_prorata, $this->company),
'tax' => Number::formatValue($tax_prorata, $this->company->currency()),
];
} catch(\DivisionByZeroError $e) {
$cash_map[$key]['tax_amount'] += 0;
}
@ -136,23 +161,39 @@ class TaxSummaryReport extends BaseExport
}
$this->csv->insertOne([]);
$this->csv->insertOne([ctrans('texts.cash_vs_accrual')]);
$this->csv->insertOne([ctrans('texts.cash_vs_accrual'), ctrans('texts.date'), ctrans('texts.amount'), ctrans('texts.amount')]);
$this->csv->insertOne($this->buildHeader());
foreach($accrual_map as $key => $value) {
$this->csv->insertOne([$key, Number::formatMoney($value['tax_amount'], $this->company)]);
$this->csv->insertOne([$key, Number::formatMoney($value['tax_amount'], $this->company), Number::formatValue($value['tax_amount'], $this->company->currency())]);
}
$this->csv->insertOne([]);
$this->csv->insertOne([ctrans('texts.cash_accounting')]);
$this->csv->insertOne([ctrans('texts.cash_accounting'), ctrans('texts.date'), ctrans('texts.amount'), ctrans('texts.amount')]);
$this->csv->insertOne($this->buildHeader());
foreach($cash_map as $key => $value) {
$this->csv->insertOne([$key, Number::formatMoney($value['tax_amount'], $this->company)]);
$this->csv->insertOne([$key, Number::formatMoney($value['tax_amount'], $this->company), Number::formatValue($value['tax_amount'], $this->company->currency())]);
}
$this->csv->insertOne([]);
$this->csv->insertOne([]);
$this->csv->insertOne([ctrans('texts.cash_vs_accrual')]);
foreach($accrual_invoice_map as $map){
$this->csv->insertOne($map);
}
$this->csv->insertOne([]);
$this->csv->insertOne([]);
$this->csv->insertOne([ctrans('texts.cash_accounting')]);
foreach($cash_invoice_map as $map){
$this->csv->insertOne($map);
}
return $this->csv->toString();
}