ultimatepos/Modules/Repair/Utils/RepairUtil.php

435 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Modules\Repair\Utils;
use App\Business;
use App\Charts\CommonChart;
use App\Utils\Util;
use Carbon\Carbon;
use DB;
use Modules\Repair\Entities\JobSheet;
use Modules\Repair\Notifications\RepairStatusUpdated;
use Notification;
class RepairUtil extends Util
{
public function replaceModuleTags($business_id, $data, $job_sheet)
{
$id = empty($job_sheet->repair_job_sheet_id) ? $job_sheet->id : $job_sheet->repair_job_sheet_id;
$job_sheet = JobSheet::with('customer', 'technician', 'Brand',
'Device', 'deviceModel', 'status')
->where('business_id', $business_id)
->findOrFail($id);
$business = Business::findOrFail($business_id);
foreach ($data as $key => $value) {
//replace customer name
if (strpos($value, '{customer_name}') !== false) {
$customer_name = $this->localizeValue($job_sheet->customer?->name);
$data[$key] = str_replace('{customer_name}', $customer_name, $data[$key]);
}
//Replace job sheet number
if (strpos($value, '{job_sheet_no}') !== false) {
$job_sheet_no = $this->localizeValue($job_sheet->job_sheet_no);
$data[$key] = str_replace('{job_sheet_no}', $job_sheet_no, $data[$key]);
}
//Replace status
if (strpos($value, '{status}') !== false) {
$status = $this->localizeValue($job_sheet->status?->name);
$data[$key] = str_replace('{status}', $status, $data[$key]);
}
//Replace serial number
if (strpos($value, '{serial_number}') !== false) {
$serial_number = $this->localizeValue($job_sheet->serial_no);
$data[$key] = str_replace('{serial_number}', $serial_number, $data[$key]);
}
//replace delivery_date
if (strpos($value, '{delivery_date}') !== false) {
$delivery_date = $job_sheet->delivery_date;
if (! empty($delivery_date)) {
$delivery_date = $this->formatLocalizedDate($delivery_date, true);
}
$data[$key] = str_replace('{delivery_date}', $delivery_date, $data[$key]);
}
//replace service staff name
if (strpos($value, '{service_staff}') !== false && ! empty($job_sheet->technician)) {
$service_staff = $this->localizeValue($job_sheet->technician?->user_full_name);
$data[$key] = str_replace('{service_staff}', $service_staff, $data[$key]);
}
//replace brand name
if (strpos($value, '{brand}') !== false && ! empty($job_sheet->Brand)) {
$brand = $this->localizeValue($job_sheet->Brand?->name);
$data[$key] = str_replace('{brand}', $brand, $data[$key]);
}
//replace device name
if (strpos($value, '{device}') !== false && ! empty($job_sheet->Device)) {
$device = $this->localizeValue($job_sheet->Device?->name);
$data[$key] = str_replace('{device}', $device, $data[$key]);
}
//replace device model name
if (strpos($value, '{device_model}') !== false && ! empty($job_sheet->deviceModel)) {
$device_model = $this->localizeValue($job_sheet->deviceModel?->name);
$data[$key] = str_replace('{device_model}', $device_model, $data[$key]);
}
//Replace business_name
if (strpos($value, '{business_name}') !== false) {
$business_name = $this->localizeValue($business->name);
$data[$key] = str_replace('{business_name}', $business_name, $data[$key]);
}
}
return $data;
}
public function repairWarrantyExpiresIn($repair)
{
$warranty = '';
if (! empty($repair->repair_completed_on)) {
$repair_completed_on = Carbon::parse($repair->repair_completed_on);
$warranty_expires_on = $repair_completed_on;
if ($repair->duration_type == 'months') {
$warranty_expires_on = $warranty_expires_on->addMonths($repair->duration);
} elseif ($repair->duration_type == 'years') {
$warranty_expires_on = $warranty_expires_on->addYears($repair->duration);
} elseif ($repair->duration_type == 'days') {
$warranty_expires_on = $warranty_expires_on->addDays($repair->duration);
}
if (app()->getLocale() === 'fa') {
$warranty_expires_on->locale('fa');
}
$warranty = format_relative_time($warranty_expires_on);
$warranty = $this->localizeValue($warranty);
}
return $warranty;
}
public function getRepairSettings($business_id)
{
$repair_settings = Business::where('id', $business_id)
->value('repair_settings');
$repair_settings = ! empty($repair_settings) ? json_decode($repair_settings, true) : [];
return $repair_settings;
}
public function getJobsheetPdfSettings($business_id)
{
$repair_jobsheet_settings = Business::where('id', $business_id)
->value('repair_jobsheet_settings');
$repair_jobsheet_settings = ! empty($repair_jobsheet_settings) ?
json_decode($repair_jobsheet_settings, true) : [];
return $repair_jobsheet_settings;
}
public function sendRepairUpdateNotification($sms_body, $transaction)
{
$business_id = $transaction->business_id;
$contact = $transaction->contact;
$notification_data['sms_body'] = $sms_body;
$tag_replaced_data = $this->replaceTags($business_id, $notification_data, $transaction);
$tag_replaced_data = $this->replaceModuleTags($business_id, $tag_replaced_data, $transaction);
$business = Business::findOrFail($business_id);
$data['sms_settings'] = $business->sms_settings;
$data['mobile_number'] = $contact->mobile;
$data['sms_body'] = $tag_replaced_data['sms_body'];
//Send sms
if (! empty($contact->mobile) && ! empty($data['sms_body'])) {
$response = $this->sendSms($data);
if (! empty($response) && $response->getStatusCode() == 200) {
$is_sent = __('repair::lang.sms_sent');
} else {
$is_sent = __('repair::lang.sms_not_sent');
}
//loging if notification sent
activity()
->performedOn($transaction)
->withProperties(['sms_body' => $data['sms_body'], 'mobile_number' => $data['mobile_number'], 'sent' => $is_sent])
->log('is_sent_notification');
return $response;
} else {
return null;
}
}
public function sendJobSheetUpdateSmsNotification($sms_body, $job_sheet)
{
$business_id = $job_sheet->business_id;
$customer = $job_sheet->customer;
$notification_data['sms_body'] = $sms_body;
//replace tag from template
$tag_replaced_data = $this->replaceModuleTags($business_id, $notification_data, $job_sheet);
$business = Business::findOrFail($business_id);
$data['sms_settings'] = $business->sms_settings;
$data['mobile_number'] = $customer->mobile;
$data['sms_body'] = $tag_replaced_data['sms_body'];
//Send sms
if (! empty($data['sms_settings']) && ! empty($customer->mobile) && ! empty($data['sms_body'])) {
$response = $this->sendSms($data);
if (! empty($response) && $response->getStatusCode() == 200) {
$is_sent = __('repair::lang.sms_sent');
} else {
$is_sent = __('repair::lang.sms_not_sent');
}
//loging if notification sent
activity()
->performedOn($job_sheet)
->withProperties(['sms_body' => $data['sms_body'], 'mobile_number' => $data['mobile_number'], 'sent' => $is_sent])
->log('is_sent_notification');
return $response;
} else {
return null;
}
}
public function sendJobSheetUpdateEmailNotification($notification_data, $job_sheet)
{
$business_id = $job_sheet->business_id;
$customer = $job_sheet->customer;
//replace tag from template
$tag_replaced_data = $this->replaceModuleTags($business_id, $notification_data, $job_sheet);
if (! empty($customer->email)) {
$customer->notify(new RepairStatusUpdated($tag_replaced_data));
}
}
public function getRepairStatusTemplateTags()
{
return [
'tags' => ['{customer_name}', '{job_sheet_no}', '{status}', '{serial_number}', '{delivery_date}', '{service_staff}', '{brand}', '{device}', '{device_model}', '{business_name}'],
'help_text' => __('lang_v1.available_tags'),
];
}
public function getRepairByStatus($business_id)
{
$job_sheets_by_status = JobSheet::join(
'repair_statuses as rs',
'repair_job_sheets.status_id',
'=',
'rs.id'
)
->where('repair_job_sheets.business_id', $business_id)
->select(
DB::raw('COUNT(repair_job_sheets.id) as total_job_sheets'),
'rs.name as status_name',
'rs.color',
'rs.sort_order'
)
->groupBy('rs.id')
->orderBy('sort_order', 'asc')
->get();
return $job_sheets_by_status;
}
public function getRepairByServiceStaff($business_id)
{
$job_sheets_by_service_staff = JobSheet::leftJoin(
'users', 'repair_job_sheets.service_staff',
'=',
'users.id'
)
->where('repair_job_sheets.business_id', $business_id)
->whereNotNull('repair_job_sheets.service_staff')
->select(DB::raw("CONCAT(COALESCE(surname, ''),' ',COALESCE(first_name, ''),' ',COALESCE(last_name,'')) as service_staff"),
DB::raw('COUNT(repair_job_sheets.id) as total_job_sheets')
)
->groupBy('repair_job_sheets.service_staff')
->get();
return $job_sheets_by_service_staff;
}
public function getTrendingRepairBrands($business_id)
{
$job_sheets = JobSheet::leftJoin('brands',
'repair_job_sheets.brand_id',
'=',
'brands.id')
->where('repair_job_sheets.business_id', $business_id)
->whereNotNull('repair_job_sheets.brand_id')
->select('brands.name as brand',
DB::raw('COUNT(repair_job_sheets.id) as job_sheets_brands')
)
->limit(5)
->groupBy('brands.id')
->orderBy('job_sheets_brands', 'desc')
->get();
$labels = [];
$values = [];
foreach ($job_sheets as $key => $job_sheet) {
$labels[] = $job_sheet['brand'];
$values[] = $job_sheet['job_sheets_brands'];
}
$chart = new CommonChart;
$chart->labels($labels)
->options($this->__chartOptions(__('repair::lang.total_unit_repaired')))
->dataset(__('repair::lang.total_unit_repaired'), 'column', $values);
return $chart;
}
private function __chartOptions($title)
{
return [
'yAxis' => [
'title' => [
'text' => $title,
],
],
'legend' => [
'align' => 'right',
'verticalAlign' => 'top',
'floating' => true,
'layout' => 'vertical',
],
];
}
public function getTrendingDevices($business_id)
{
$job_sheets = JobSheet::leftJoin('categories as CAT',
'repair_job_sheets.device_id',
'=',
'CAT.id')
->where('repair_job_sheets.business_id', $business_id)
->whereNotNull('repair_job_sheets.device_id')
->select('CAT.name as device',
DB::raw('COUNT(repair_job_sheets.id) as job_sheet_devices')
)
->limit(5)
->groupBy('CAT.id')
->orderBy('job_sheet_devices', 'desc')
->get();
$labels = [];
$values = [];
foreach ($job_sheets as $key => $job_sheet) {
$labels[] = $job_sheet['device'];
$values[] = $job_sheet['job_sheet_devices'];
}
$chart = new CommonChart;
$chart->labels($labels)
->options($this->__chartOptions(__('repair::lang.total_unit_repaired')))
->dataset(__('repair::lang.total_unit_repaired'), 'column', $values);
return $chart;
}
public function getTrendingDeviceModels($business_id)
{
$job_sheets = JobSheet::leftJoin('repair_device_models as RDM',
'repair_job_sheets.device_model_id',
'=',
'RDM.id')
->leftJoin('brands', 'RDM.brand_id',
'=', 'brands.id')
->leftJoin('categories as CAT',
'RDM.device_id',
'=',
'CAT.id')
->where('repair_job_sheets.business_id', $business_id)
->whereNotNull('repair_job_sheets.device_model_id')
->select('RDM.name as device_model', 'brands.name as brand',
DB::raw('COUNT(repair_job_sheets.id) as job_sheet_models'),
'CAT.name as device'
)
->limit(5)
->groupBy('RDM.id')
->orderBy('job_sheet_models', 'desc')
->get();
$labels = [];
$values = [];
foreach ($job_sheets as $key => $job_sheet) {
$label = $job_sheet['device_model'];
$brand = $job_sheet['brand'];
$device = $job_sheet['device'];
if (! empty($brand) && ! empty($device)) {
$label = $job_sheet['device_model'].' ('.$brand.' / '.$device.')';
} elseif (! empty($brand)) {
$label = $job_sheet['device_model'].' ('.$brand.')';
} elseif (! empty($device)) {
$label = $job_sheet['device_model'].' ('.$device.')';
}
$labels[] = $label;
$values[] = $job_sheet['job_sheet_models'];
}
$chart = new CommonChart;
$chart->labels($labels)
->options($this->__chartOptions(__('repair::lang.total_unit_repaired')))
->dataset(__('repair::lang.total_unit_repaired'), 'column', $values);
return $chart;
}
protected function formatLocalizedDate($date, bool $include_time = false): string
{
if (empty($date)) {
return '';
}
return parent::format_date($date, $include_time) ?? '';
}
protected function localizeValue($value)
{
if (app()->getLocale() !== 'fa') {
return $value ?? '';
}
if (is_null($value)) {
return '';
}
if (is_string($value) || is_numeric($value)) {
return $this->convertToPersianDigits((string) $value);
}
return $value;
}
protected function convertToPersianDigits(string $value): string
{
$englishDigits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
$persianDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
return str_replace($englishDigits, $persianDigits, $value);
}
}