fix share text to app and handle copy to clipboard daily report mechanic
This commit is contained in:
@@ -117,22 +117,43 @@ class TransactionController extends Controller
|
|||||||
->where('sa.dealer_id', Auth::user()->dealer_id)
|
->where('sa.dealer_id', Auth::user()->dealer_id)
|
||||||
->where('work_id', $work->id)
|
->where('work_id', $work->id)
|
||||||
->whereDate('transactions.date', '=', date('Y-m-d'))->groupBy('transactions.user_sa_id')->get();
|
->whereDate('transactions.date', '=', date('Y-m-d'))->groupBy('transactions.user_sa_id')->get();
|
||||||
|
|
||||||
|
// Initialize data array for this work
|
||||||
|
$tm1[$work['shortname']]['data'] = [];
|
||||||
|
$daily_total = 0;
|
||||||
|
|
||||||
foreach($transaction_sas as $sa) {
|
foreach($transaction_sas as $sa) {
|
||||||
$tm1[$work['shortname']]['data'][] = $sa['sa_name'].":".$sa['qty'];
|
$tm1[$work['shortname']]['data'][] = $sa['sa_name'].":".$sa['qty'];
|
||||||
|
$daily_total += $sa['qty'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$month_share_data = Transaction::select(DB::raw('SUM(qty) as qty'), 'u.name')->join('users AS u', 'u.id', '=', 'transactions.user_sa_id')->where('transactions.dealer_id', Auth::user()->dealer->id)->whereMonth('date', date('m'))->whereYear('date', date('Y'))->where('work_id', $work->id)->groupBy('user_sa_id')->get();
|
// Add daily total even if no data
|
||||||
$tm1[$work['shortname']]['total_title'] = "*[PERIODE 1 - ". Carbon::now()->translatedFormat('d F Y') ."]*\n\n";
|
if (empty($tm1[$work['shortname']]['data'])) {
|
||||||
|
$tm1[$work['shortname']]['data'][] = "Tidak ada data:0";
|
||||||
$sum_month_share_trx = 0;
|
|
||||||
$tm_month = [];
|
|
||||||
foreach($month_share_data as $m_trx) {
|
|
||||||
$tm_month[] = $m_trx->name.":".$m_trx->qty." Unit\n";
|
|
||||||
$sum_month_share_trx += $m_trx->qty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$tm1[$work['shortname']]['total_body'] = $tm_month;
|
// Remove monthly data section since this is daily report
|
||||||
$tm1[$work['shortname']]['total_total'] = "*TOTAL : ". $sum_month_share_trx." Unit*";
|
// $month_share_data = Transaction::select(DB::raw('SUM(qty) as qty'), 'u.name')
|
||||||
|
// ->join('users AS u', 'u.id', '=', 'transactions.user_sa_id')
|
||||||
|
// ->where('transactions.dealer_id', Auth::user()->dealer->id)
|
||||||
|
// ->whereMonth('date', date('m'))
|
||||||
|
// ->whereYear('date', date('Y'))
|
||||||
|
// ->where('work_id', $work->id)
|
||||||
|
// ->groupBy('user_sa_id')
|
||||||
|
// ->get();
|
||||||
|
|
||||||
|
// Remove the period title since this is for daily report, not monthly
|
||||||
|
// $tm1[$work['shortname']]['total_title'] = "*[PERIODE 1 - ". Carbon::now()->translatedFormat('d F Y') ."]*\n\n";
|
||||||
|
|
||||||
|
// $sum_month_share_trx = 0;
|
||||||
|
// $tm_month = [];
|
||||||
|
// foreach($month_share_data as $m_trx) {
|
||||||
|
// $tm_month[] = $m_trx->name.":".$m_trx->qty." Unit\n";
|
||||||
|
// $sum_month_share_trx += $m_trx->qty;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $tm1[$work['shortname']]['total_body'] = $tm_month;
|
||||||
|
// $tm1[$work['shortname']]['total_total'] = "*TOTAL : ". $sum_month_share_trx." Unit*";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($request->date_start)) {
|
if(isset($request->date_start)) {
|
||||||
@@ -156,7 +177,29 @@ class TransactionController extends Controller
|
|||||||
$sas = User::where('role_id', 4)->get();
|
$sas = User::where('role_id', 4)->get();
|
||||||
$dealers = Dealer::all();
|
$dealers = Dealer::all();
|
||||||
$works = Work::all();
|
$works = Work::all();
|
||||||
return view('transaction.lists', compact('transaction_dealers', 'transaction_mechanics', 'mechanic', 'sas', 'dealers', 'works', 'date_start', 'date_end'));
|
|
||||||
|
// Get KPI data for current user using KPI service
|
||||||
|
$kpiService = app(\App\Services\KpiService::class);
|
||||||
|
|
||||||
|
// Auto-calculate current month KPI achievement including claimed transactions
|
||||||
|
$kpiService->calculateKpiAchievementWithClaims(Auth::user());
|
||||||
|
|
||||||
|
$kpiSummary = $kpiService->getKpiSummaryWithClaims(Auth::user());
|
||||||
|
|
||||||
|
// Get current month period name
|
||||||
|
$currentMonthName = now()->translatedFormat('F Y');
|
||||||
|
|
||||||
|
$kpiData = [
|
||||||
|
'target' => $kpiSummary['current_target'] ? $kpiSummary['current_target']->target_value : 0,
|
||||||
|
'actual' => $kpiSummary['current_achievement'] ? $kpiSummary['current_achievement']->actual_value : 0,
|
||||||
|
'percentage' => $kpiSummary['current_percentage'],
|
||||||
|
'status' => $kpiSummary['current_achievement'] ? $kpiSummary['current_achievement']->status : 'pending',
|
||||||
|
'status_color' => $kpiSummary['current_achievement'] ? $kpiSummary['current_achievement']->status_color : 'secondary',
|
||||||
|
'period' => $currentMonthName,
|
||||||
|
'has_target' => $kpiSummary['current_target'] ? true : false
|
||||||
|
];
|
||||||
|
|
||||||
|
return view('transaction.lists', compact('transaction_dealers', 'transaction_mechanics', 'mechanic', 'sas', 'dealers', 'works', 'date_start', 'date_end', 'kpiData'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function cmp($a, $b){
|
public function cmp($a, $b){
|
||||||
|
|||||||
@@ -249,22 +249,72 @@
|
|||||||
$string = "*[Laporan Harian Mekanik ]*\n";
|
$string = "*[Laporan Harian Mekanik ]*\n";
|
||||||
$string .= "*". Auth::user()->dealer->name ."*\n";
|
$string .= "*". Auth::user()->dealer->name ."*\n";
|
||||||
$string .= "*". $transaction_mechanics['today_date'] ."*\n\n\n";
|
$string .= "*". $transaction_mechanics['today_date'] ."*\n\n\n";
|
||||||
foreach ($transaction_mechanics['data'] as $shortname => $trx) {
|
|
||||||
$string .= $shortname."\n";
|
|
||||||
$total_qty = 0;
|
|
||||||
foreach ($trx['data'] as $item) {
|
|
||||||
$total_qty += explode(':', $item)[1];
|
|
||||||
$string .= $item."\n";
|
|
||||||
}
|
|
||||||
$string .= "*TOTAL".$total_qty."*\n\n";
|
|
||||||
|
|
||||||
$string .= $trx['total_title'];
|
// Add KPI Achievement Information
|
||||||
foreach ($trx['total_body'] as $total) {
|
if($kpiData['has_target']) {
|
||||||
$string .= $total;
|
$string .= "*=== KPI ACHIEVEMENT PROGRESS ===*\n";
|
||||||
}
|
$string .= "*Target ". $kpiData['period'] .": ". number_format($kpiData['target']) ." Pekerjaan*\n";
|
||||||
|
$string .= "*Pencapaian: ". number_format($kpiData['actual']) ." Pekerjaan*\n";
|
||||||
|
$string .= "*Progress: ". $kpiData['percentage'] ."%*\n";
|
||||||
|
|
||||||
$string .= $trx['total_total']."\n\n";
|
// Add status message
|
||||||
|
if($kpiData['status'] == 'exceeded') {
|
||||||
|
$string .= "*Status: ✅ Target tercapai!*\n";
|
||||||
|
} elseif($kpiData['status'] == 'good') {
|
||||||
|
$string .= "*Status: 🔵 Performa baik*\n";
|
||||||
|
} elseif($kpiData['status'] == 'fair') {
|
||||||
|
$string .= "*Status: 🟡 Perlu peningkatan*\n";
|
||||||
|
} elseif($kpiData['status'] == 'poor') {
|
||||||
|
$string .= "*Status: 🔴 Perlu perbaikan*\n";
|
||||||
|
} else {
|
||||||
|
$string .= "*Status: ⚪ Belum ada data*\n";
|
||||||
|
}
|
||||||
|
$string .= "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$overall_total = 0;
|
||||||
|
|
||||||
|
// Debug: Check if data exists
|
||||||
|
if (!empty($transaction_mechanics['data'])) {
|
||||||
|
foreach ($transaction_mechanics['data'] as $shortname => $trx) {
|
||||||
|
$string .= "*". $shortname ."*\n";
|
||||||
|
$total_qty = 0;
|
||||||
|
|
||||||
|
// Check if data array exists
|
||||||
|
if (isset($trx['data']) && is_array($trx['data'])) {
|
||||||
|
foreach ($trx['data'] as $item) {
|
||||||
|
$parts = explode(':', $item);
|
||||||
|
if (count($parts) >= 2) {
|
||||||
|
$qty = intval($parts[1]);
|
||||||
|
$total_qty += $qty;
|
||||||
|
}
|
||||||
|
$string .= $item."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$string .= "*TOTAL: ".$total_qty." Unit*\n\n";
|
||||||
|
$overall_total += $total_qty;
|
||||||
|
|
||||||
|
// Remove monthly data display since this is daily report
|
||||||
|
// if (isset($trx['total_body']) && is_array($trx['total_body'])) {
|
||||||
|
// foreach ($trx['total_body'] as $total) {
|
||||||
|
// $string .= $total;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (isset($trx['total_total'])) {
|
||||||
|
// $string .= $trx['total_total']."\n\n";
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$string .= "*Tidak ada data transaksi hari ini*\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add overall summary
|
||||||
|
$string .= "*=== RINGKASAN HARIAN ===*\n";
|
||||||
|
$string .= "*Tanggal: ". $transaction_mechanics['today_date'] ."*\n";
|
||||||
|
$string .= "*Dealer: ". Auth::user()->dealer->name ."*\n";
|
||||||
|
$string .= "*Total Keseluruhan: ". $overall_total ." Unit*\n";
|
||||||
@endphp
|
@endphp
|
||||||
{!! $string !!}
|
{!! $string !!}
|
||||||
</div>
|
</div>
|
||||||
@@ -335,23 +385,156 @@
|
|||||||
<script>
|
<script>
|
||||||
$("#kt-table").DataTable()
|
$("#kt-table").DataTable()
|
||||||
|
|
||||||
const shareData = {
|
// Check if Web Share API is supported
|
||||||
title: 'Dealer',
|
function isWebShareSupported() {
|
||||||
text: $("#shareThis").html()
|
return navigator.share && typeof navigator.share === 'function';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback function for copying to clipboard
|
||||||
|
function copyToClipboard(text) {
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
// Use modern clipboard API
|
||||||
|
return navigator.clipboard.writeText(text).then(() => {
|
||||||
|
return true;
|
||||||
|
}).catch(() => {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback for older browsers
|
||||||
|
try {
|
||||||
|
const textArea = document.createElement('textarea');
|
||||||
|
textArea.value = text;
|
||||||
|
textArea.style.position = 'fixed';
|
||||||
|
textArea.style.left = '-999999px';
|
||||||
|
textArea.style.top = '-999999px';
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
textArea.focus();
|
||||||
|
textArea.select();
|
||||||
|
const successful = document.execCommand('copy');
|
||||||
|
document.body.removeChild(textArea);
|
||||||
|
return Promise.resolve(successful);
|
||||||
|
} catch (err) {
|
||||||
|
return Promise.resolve(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main share function
|
||||||
|
async function shareData() {
|
||||||
|
const shareText = $("#shareThis").html();
|
||||||
|
|
||||||
|
if (isWebShareSupported()) {
|
||||||
|
// Use Web Share API
|
||||||
|
try {
|
||||||
|
await navigator.share({
|
||||||
|
title: 'Laporan Harian Mekanik',
|
||||||
|
text: shareText
|
||||||
|
});
|
||||||
|
console.log('Data berhasil dibagikan');
|
||||||
|
showSuccessMessage('Data berhasil dibagikan!');
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Share cancelled or failed:', err);
|
||||||
|
// Fallback to clipboard
|
||||||
|
await copyToClipboardFallback(shareText);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback for unsupported browsers
|
||||||
|
await copyToClipboardFallback(shareText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clipboard fallback function
|
||||||
|
async function copyToClipboardFallback(text) {
|
||||||
|
const success = await copyToClipboard(text);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
showSuccessMessage('Data berhasil disalin ke clipboard! Silakan paste di aplikasi yang diinginkan.');
|
||||||
|
} else {
|
||||||
|
showErrorMessage('Gagal menyalin data. Silakan copy manual dari bawah ini:');
|
||||||
|
showManualCopy(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show success message
|
||||||
|
function showSuccessMessage(message) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'success',
|
||||||
|
title: 'Berhasil!',
|
||||||
|
text: message,
|
||||||
|
timer: 3000,
|
||||||
|
showConfirmButton: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show error message
|
||||||
|
function showErrorMessage(message) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'warning',
|
||||||
|
title: 'Perhatian',
|
||||||
|
text: message,
|
||||||
|
confirmButtonText: 'OK'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show manual copy option
|
||||||
|
function showManualCopy(text) {
|
||||||
|
const modal = `
|
||||||
|
<div class="modal fade" id="manualCopyModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Copy Manual Data</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal">
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>Silakan copy data di bawah ini:</p>
|
||||||
|
<textarea class="form-control" rows="15" readonly style="font-family: monospace; font-size: 12px;">${text}</textarea>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Tutup</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="copyFromTextarea()">Copy</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Remove existing modal if any
|
||||||
|
$('#manualCopyModal').remove();
|
||||||
|
|
||||||
|
// Add modal to body
|
||||||
|
$('body').append(modal);
|
||||||
|
$('#manualCopyModal').modal('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy from textarea function
|
||||||
|
function copyFromTextarea() {
|
||||||
|
const textarea = document.querySelector('#manualCopyModal textarea');
|
||||||
|
textarea.select();
|
||||||
|
textarea.setSelectionRange(0, 99999); // For mobile devices
|
||||||
|
|
||||||
|
try {
|
||||||
|
const successful = document.execCommand('copy');
|
||||||
|
if (successful) {
|
||||||
|
showSuccessMessage('Data berhasil disalin!');
|
||||||
|
$('#manualCopyModal').modal('hide');
|
||||||
|
} else {
|
||||||
|
showErrorMessage('Gagal menyalin data. Silakan copy manual.');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
showErrorMessage('Gagal menyalin data. Silakan copy manual.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Share button click handler
|
||||||
const btn = $('#share');
|
const btn = $('#share');
|
||||||
const resultPara = $('.result');
|
const resultPara = $('.result');
|
||||||
// Share must be triggered by "user activation"
|
|
||||||
btn.click(async function() {
|
|
||||||
try {
|
|
||||||
await navigator.share(shareData)
|
|
||||||
console.log('Dealer shared successfully')
|
|
||||||
} catch(err) {
|
|
||||||
console.log('Error: ' + err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
btn.click(function() {
|
||||||
|
shareData();
|
||||||
|
});
|
||||||
|
|
||||||
function editTransaction(id) {
|
function editTransaction(id) {
|
||||||
let form_action = $("#editTransaction"+id).attr("data-action")
|
let form_action = $("#editTransaction"+id).attr("data-action")
|
||||||
|
|||||||
Reference in New Issue
Block a user