fix share text to app and handle copy to clipboard daily report mechanic

This commit is contained in:
2025-07-11 16:31:37 +07:00
parent e3956ae0e4
commit 0b1589d173
2 changed files with 263 additions and 37 deletions

View File

@@ -117,22 +117,43 @@ class TransactionController extends Controller
->where('sa.dealer_id', Auth::user()->dealer_id)
->where('work_id', $work->id)
->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) {
$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();
$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;
// Add daily total even if no data
if (empty($tm1[$work['shortname']]['data'])) {
$tm1[$work['shortname']]['data'][] = "Tidak ada data:0";
}
$tm1[$work['shortname']]['total_body'] = $tm_month;
$tm1[$work['shortname']]['total_total'] = "*TOTAL : ". $sum_month_share_trx." Unit*";
// Remove monthly data section since this is daily report
// $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)) {
@@ -156,7 +177,29 @@ class TransactionController extends Controller
$sas = User::where('role_id', 4)->get();
$dealers = Dealer::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){

View File

@@ -249,22 +249,72 @@
$string = "*[Laporan Harian Mekanik ]*\n";
$string .= "*". Auth::user()->dealer->name ."*\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'];
foreach ($trx['total_body'] as $total) {
$string .= $total;
}
// Add KPI Achievement Information
if($kpiData['has_target']) {
$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
{!! $string !!}
</div>
@@ -335,23 +385,156 @@
<script>
$("#kt-table").DataTable()
const shareData = {
title: 'Dealer',
text: $("#shareThis").html()
// Check if Web Share API is supported
function isWebShareSupported() {
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>&times;</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 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) {
let form_action = $("#editTransaction"+id).attr("data-action")