generated from MokoConsulting/Template-Joomla
feat: second helper — core business logic for primary feature
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
namespace Moko\Plugin\System\MokoSuiteAuto\Helper;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\Database\DatabaseInterface;
|
||||
|
||||
/**
|
||||
* Deal management — sales deals, gross profit, F&I products, deal jacket.
|
||||
*/
|
||||
class DealHelper
|
||||
{
|
||||
/**
|
||||
* Create a new deal.
|
||||
*/
|
||||
public static function create(int $vehicleId, int $buyerContactId, int $salespersonId, float $salePrice): object
|
||||
{
|
||||
if ($salePrice <= 0) {
|
||||
throw new \InvalidArgumentException('Sale price must be positive.');
|
||||
}
|
||||
|
||||
$db = Factory::getContainer()->get(DatabaseInterface::class);
|
||||
|
||||
$deal = (object) [
|
||||
'vehicle_id' => $vehicleId,
|
||||
'buyer_contact_id'=> $buyerContactId,
|
||||
'salesperson_id' => $salespersonId,
|
||||
'sale_price' => round($salePrice, 2),
|
||||
'status' => 'negotiating',
|
||||
'created_at' => Factory::getDate()->toSql(),
|
||||
];
|
||||
|
||||
$db->insertObject('#__mokosuiteauto_deals', $deal, 'id');
|
||||
|
||||
return (object) ['success' => true, 'deal_id' => (int) $deal->id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate gross profit for a deal.
|
||||
*/
|
||||
public static function getGrossProfit(int $dealId): object
|
||||
{
|
||||
$db = Factory::getContainer()->get(DatabaseInterface::class);
|
||||
|
||||
$db->setQuery($db->getQuery(true)
|
||||
->select('d.sale_price, v.invoice_price, v.reconditioning_cost')
|
||||
->select('COALESCE(ti.appraisal_value, 0) AS trade_allowance')
|
||||
->from($db->quoteName('#__mokosuiteauto_deals', 'd'))
|
||||
->join('INNER', $db->quoteName('#__mokosuiteauto_vehicles', 'v') . ' ON v.id = d.vehicle_id')
|
||||
->join('LEFT', $db->quoteName('#__mokosuiteauto_trade_ins', 'ti') . ' ON ti.id = d.trade_in_id')
|
||||
->where('d.id = ' . (int) $dealId));
|
||||
$deal = $db->loadObject();
|
||||
|
||||
if (!$deal) {
|
||||
return (object) ['success' => false, 'error' => 'Deal not found'];
|
||||
}
|
||||
|
||||
$frontGross = (float) $deal->sale_price - (float) $deal->invoice_price
|
||||
- (float) ($deal->reconditioning_cost ?? 0);
|
||||
|
||||
// F&I back-end gross
|
||||
$db->setQuery($db->getQuery(true)
|
||||
->select('COALESCE(SUM(profit), 0) AS fi_gross')
|
||||
->from('#__mokosuiteauto_deal_fi_products')
|
||||
->where('deal_id = ' . (int) $dealId));
|
||||
$backGross = (float) $db->loadResult();
|
||||
|
||||
return (object) [
|
||||
'deal_id' => $dealId,
|
||||
'sale_price' => (float) $deal->sale_price,
|
||||
'invoice' => (float) $deal->invoice_price,
|
||||
'recon_cost' => (float) ($deal->reconditioning_cost ?? 0),
|
||||
'front_gross' => round($frontGross, 2),
|
||||
'back_gross' => round($backGross, 2),
|
||||
'total_gross' => round($frontGross + $backGross, 2),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sales dashboard — deals by status, monthly volume.
|
||||
*/
|
||||
public static function getSalesDashboard(): object
|
||||
{
|
||||
$db = Factory::getContainer()->get(DatabaseInterface::class);
|
||||
|
||||
$db->setQuery($db->getQuery(true)
|
||||
->select('COUNT(*) AS total_deals')
|
||||
->select('SUM(CASE WHEN status = ' . $db->quote('delivered') . ' THEN 1 ELSE 0 END) AS delivered')
|
||||
->select('SUM(CASE WHEN status = ' . $db->quote('negotiating') . ' THEN 1 ELSE 0 END) AS in_negotiation')
|
||||
->select('SUM(CASE WHEN status = ' . $db->quote('pending_finance') . ' THEN 1 ELSE 0 END) AS pending_finance')
|
||||
->select('SUM(CASE WHEN status = ' . $db->quote('delivered') . ' AND MONTH(delivered_at) = MONTH(NOW()) AND YEAR(delivered_at) = YEAR(NOW()) THEN sale_price ELSE 0 END) AS mtd_volume')
|
||||
->select('SUM(CASE WHEN status = ' . $db->quote('delivered') . ' AND MONTH(delivered_at) = MONTH(NOW()) AND YEAR(delivered_at) = YEAR(NOW()) THEN 1 ELSE 0 END) AS mtd_units')
|
||||
->from('#__mokosuiteauto_deals'));
|
||||
|
||||
$stats = $db->loadObject();
|
||||
$stats->mtd_volume = round((float) ($stats->mtd_volume ?? 0), 0);
|
||||
|
||||
return $stats;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user