162 lines
5.0 KiB
PHP
162 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace Modules\AssetExchange\Services;
|
|
|
|
use App\Business;
|
|
use App\Contact;
|
|
use App\Utils\Util;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Modules\AssetExchange\Models\Commission;
|
|
use Modules\AssetExchange\Models\Deal;
|
|
use Modules\AssetExchange\Models\Listing;
|
|
|
|
class AssetExchangeCrmBridgeService
|
|
{
|
|
public function __construct(
|
|
protected Util $commonUtil
|
|
) {
|
|
}
|
|
|
|
public function createLeadFromListing(Business $business, Listing $listing): ?Contact
|
|
{
|
|
if (! Schema::hasTable('contacts')) {
|
|
throw new \RuntimeException('جدول مخاطبین موجود نیست.');
|
|
}
|
|
|
|
if (! $this->isCrmAvailable()) {
|
|
return null;
|
|
}
|
|
|
|
$listing->loadMissing('seller');
|
|
|
|
if ($listing->seller_contact_id && $listing->seller) {
|
|
return $this->promoteContactToLead($listing->seller, $listing);
|
|
}
|
|
|
|
$contact = Contact::create([
|
|
'business_id' => $business->id,
|
|
'type' => 'lead',
|
|
'name' => $listing->title,
|
|
'mobile' => null,
|
|
'crm_lead_title' => $listing->title,
|
|
'crm_lead_description' => $listing->description,
|
|
'crm_lead_value' => $this->commonUtil->num_f($listing->asking_price, false),
|
|
'crm_source' => $this->resolveAexSourceId($business->id),
|
|
'crm_life_stage' => $this->resolveDefaultLifeStageId($business->id),
|
|
'created_by' => auth()->id(),
|
|
]);
|
|
|
|
$listing->update(['seller_contact_id' => $contact->id]);
|
|
|
|
return $contact;
|
|
}
|
|
|
|
public function syncCommissions(Business $business, Deal $deal): int
|
|
{
|
|
if (! Schema::hasTable('aex_commissions')) {
|
|
return 0;
|
|
}
|
|
|
|
$deal->loadMissing('commissions', 'listing');
|
|
|
|
if ($deal->status !== 'completed') {
|
|
throw new \RuntimeException('فقط معاملات تکمیلشده قابل همگامسازی کمیسیون هستند.');
|
|
}
|
|
|
|
$synced = 0;
|
|
|
|
return DB::transaction(function () use ($business, $deal, &$synced) {
|
|
foreach ($deal->commissions as $commission) {
|
|
if ($commission->status === 'paid' && $commission->crm_commission_id) {
|
|
continue;
|
|
}
|
|
|
|
$crmId = $this->syncCommissionToCrm($business, $deal, $commission);
|
|
if ($crmId) {
|
|
$commission->update([
|
|
'crm_commission_id' => $crmId,
|
|
'status' => 'synced',
|
|
]);
|
|
$synced++;
|
|
}
|
|
}
|
|
|
|
return $synced;
|
|
});
|
|
}
|
|
|
|
protected function promoteContactToLead(Contact $contact, Listing $listing): Contact
|
|
{
|
|
$contact->update([
|
|
'type' => $contact->type === 'supplier' ? 'supplier' : 'lead',
|
|
'crm_lead_title' => $listing->title,
|
|
'crm_lead_description' => $listing->description,
|
|
'crm_lead_value' => $this->commonUtil->num_f($listing->asking_price, false),
|
|
'crm_source' => $contact->crm_source ?: $this->resolveAexSourceId($contact->business_id),
|
|
'crm_life_stage' => $contact->crm_life_stage ?: $this->resolveDefaultLifeStageId($contact->business_id),
|
|
]);
|
|
|
|
return $contact->fresh();
|
|
}
|
|
|
|
protected function syncCommissionToCrm(Business $business, Deal $deal, Commission $commission): ?int
|
|
{
|
|
if (! class_exists(\Modules\Crm\Entities\CrmContactPersonCommission::class)) {
|
|
return null;
|
|
}
|
|
|
|
if (! Schema::hasTable('crm_contact_person_commissions')) {
|
|
return null;
|
|
}
|
|
|
|
if (! $commission->user_id || ! $deal->transaction_sell_id) {
|
|
return null;
|
|
}
|
|
|
|
$record = \Modules\Crm\Entities\CrmContactPersonCommission::updateOrCreate(
|
|
[
|
|
'contact_person_id' => $commission->user_id,
|
|
'transaction_id' => $deal->transaction_sell_id,
|
|
],
|
|
[
|
|
'commission_amount' => $commission->amount,
|
|
]
|
|
);
|
|
|
|
return $record->id;
|
|
}
|
|
|
|
protected function isCrmAvailable(): bool
|
|
{
|
|
return Schema::hasColumn('contacts', 'crm_source')
|
|
&& Schema::hasColumn('contacts', 'crm_life_stage');
|
|
}
|
|
|
|
protected function resolveAexSourceId(int $businessId): ?string
|
|
{
|
|
if (! Schema::hasTable('categories')) {
|
|
return 'aex_listing';
|
|
}
|
|
|
|
$source = \App\Category::where('business_id', $businessId)
|
|
->where('category_type', 'source')
|
|
->where('name', 'like', '%AssetExchange%')
|
|
->value('id');
|
|
|
|
return $source ? (string) $source : 'aex_listing';
|
|
}
|
|
|
|
protected function resolveDefaultLifeStageId(int $businessId): ?string
|
|
{
|
|
if (! Schema::hasTable('categories')) {
|
|
return null;
|
|
}
|
|
|
|
return \App\Category::where('business_id', $businessId)
|
|
->where('category_type', 'life_stage')
|
|
->orderBy('id')
|
|
->value('id');
|
|
}
|
|
}
|