Files
crm.e5.pl/modules/EcmReports/BimIT-Reports/productionSchedule/productionSchedule.php
2025-10-07 17:54:59 +02:00

625 lines
23 KiB
PHP

<?php
//ini_set('display_errors', 1);
//ini_set('display_startup_errors', 1);
//error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
if (!isset($_GET['ajaxAction'])) {
if (isset($_GET['date_from'])) {
$dateFrom = date("Y-m-d", strtotime($_GET['date_from']));
} else {
$dateFrom = date("Y-m-d");
}
if (isset($_GET['date_to'])) {
$dateTo = date("Y-m-d", strtotime($_GET['date_to']));
} else {
$dateTo = date("Y-m-d", strtotime("+ 1 month"));
}
$data = loadSchedulers($dateFrom, $dateTo);
$smarty = new Sugar_Smarty();
$smarty->assign("data", $data);
$smarty->assign("dateFrom", $GLOBALS['timedate']->to_display_date($dateFrom));
$smarty->assign("dateTo", $GLOBALS['timedate']->to_display_date($dateTo));
echo $smarty->display('modules/EcmReports/BimIT-Reports/productionSchedule/productionSchedule.tpl');
} else {
switch ($_GET['ajaxAction']) {
case 'saveQty':
saveQty($_GET['id'], $_GET['qty']);
break;
case 'duplicatePositions':
duplicatePositions($_GET['ids']);
break;
case 'removePositions':
removePositions($_GET['ids']);
break;
case 'saveProductionDate':
saveProductionDate($_GET['id'], $_GET['date'], $_GET['time']);
break;
case 'saveProductDescription':
saveProductDescription($_GET['id'], $_GET['description']);
break;
case 'exportExcel':
exportExcel($_GET['ids']);
break;
case 'exportExcelWYSIWYG':
exportExcelWYSIWYG($_POST['tableData']);
break;
case 'exportPDF':
exportPDF($_GET['ids']);
break;
case 'getRawMaterials':
getRawMaterials($_POST['ids']);
break;
case 'updateProductionDate':
updateProductionDate($_GET['ids'], $_GET['hours']);
break;
}
}
function loadSchedulers($dateFrom = null, $dateTo = null, $ids = null)
{
$db = $GLOBALS['db'];
global $app_list_strings;
$query = "
SELECT s.id as orderId, s.document_no, s.status, s.parent_name, s.parent_id, s.send_date, s.type,
p.code, p.name, ps.ecmproduct_id, ps.description,
si.quantity, p.vendor_part_no as kind, p.brand, p.part_no as size, p.shape,
p.ems_qty_in_stock as stockState, si.id as item_id, s.shipping_address_name, ps.production_date,
ps.quantity as scheduledQuantity, ps.id as id,
ps.main_id,
ps_main.ecmproduct_id as main_product_id,
p_main.code as main_product_code,
a.id AS action_id,
a.indeks AS action_index,
a.category AS action_category,
a.performance AS action_performance
FROM productionScheduler AS ps
LEFT JOIN ecmsaleitems AS si
ON ps.ecmsaleitem_id = si.id
LEFT JOIN ecmsales AS s
ON ps.ecmsale_id = s.id
INNER JOIN ecmproducts AS p
ON ps.ecmproduct_id = p.id
LEFT JOIN productionScheduler AS ps_main
ON ps.main_id = ps_main.id
LEFT JOIN ecmproducts AS p_main
ON ps_main.ecmproduct_id = p_main.id
LEFT JOIN (
SELECT epa.ecmproduct_id, epa.ecmaction_id
FROM ecmproductactions epa
JOIN (
SELECT ecmproduct_id, MIN(position) AS min_pos
FROM ecmproductactions
GROUP BY ecmproduct_id
) m
ON m.ecmproduct_id = epa.ecmproduct_id
AND m.min_pos = epa.position
) pa_first
ON pa_first.ecmproduct_id = p.id
LEFT JOIN ecmactions a
ON a.id = pa_first.ecmaction_id
WHERE ps.deleted = 0 ";
if ($dateFrom != null && $dateTo != null) {
$query .= " AND (
(ps.production_date >= '$dateFrom' AND ps.production_date <= '$dateTo')
OR ps.production_date IS NULL OR ps.production_date = '0000-00-00')";
}
if ($ids != null) {
$query .= " AND ps.id IN ('" . join("','", $ids) . "')";
}
$query .= "GROUP BY ps.id, s.id, si.id, p.id, ps_main.id, p_main.id ";
$query .= "ORDER BY s.delivery_date, s.register_date, s.document_no;";
$rows = $db->query($query);
$data = array();
$i = 0;
while ($r = $db->fetchByAssoc($rows)) {
$row = array();
$i++;
$row['position'] = $i;
$row['id'] = $r['id'];
$row['productName'] = strlen($r['name']) > 55 ? substr($r['name'], 0, 55) . "..." : $r['name'];
$row['productFullName'] = $r['name'];
$row['productCode'] = strlen($r['code']) > 20 ? substr($r['code'], 0, 20) . "..." : $r['code'];
$row['productFullCode'] = $r['code'];
$row['productId'] = $r['ecmproduct_id'];
$row['productQty'] = $r['quantity'];
$row['qty'] = $r['scheduledQuantity'];
$row['productKind'] = $r['kind'];
$row['productSize'] = $r['size'];
$row['productShape'] = $app_list_strings['ecmproducts_shape_dom'][$r['shape']];
$row['productBrand'] = $app_list_strings['ecmproducts_brand_dom'][$r['brand']];
$row['orderNo'] = $r['document_no'];
$row['orderId'] = $r['orderId'];
$row['orderStatus'] = $app_list_strings['ecmsales_status_dom'][$r['status']];
$row['orderType'] = $app_list_strings['ecmsales_type_dom'][$r['type']];
$row['orderParent'] = $r['parent_name'];
$row['orderParentId'] = $r['parent_id'];
$row['orderSendDate'] = $r['send_date'];
$row['orderItemId'] = $r['item_id'];
$row['description'] = strlen($r['description']) > 0 ? substr($r['description'], 0, 30) : '';
$row['fullDescription'] = $r['description'];
$row['shippingTo'] = ($r['shipping_address_name'] == 'Adres korespondencyjny' ? '' : $r['shipping_address_name']);
$row['productionDate'] = $r['production_date'] == '0000-00-00 00:00:00' ? '' : substr($r['production_date'], 0, 10);
$row['productionTime'] = $r['production_date'] == '0000-00-00 00:00:00' ? '' : substr($r['production_date'], 11, 5);
$row['productStockState'] = $r['stockState'] | 0;
$row['mainProductId'] = $r['main_product_id'];
$row['mainProductCode'] = strlen($r['main_product_code']) > 20 ? substr($r['main_product_code'], 0, 20) . "..." : $r['main_product_code'];
$row['mainProductFullCode'] = $r['main_product_code'];
$row['action_id'] = $r['action_id'];
$row['action_index'] = $r['action_index'];
$row['action_category'] = $app_list_strings['ecmactions_category_dom'][$r['action_category']];
// check if action_performance is number and is not 0
if (is_numeric($r['action_performance']) && $r['action_performance'] != 0) {
$timeInHours = $r['scheduledQuantity'] / $r['action_performance'];
$hours = floor($timeInHours);
$minutes = round(($timeInHours - $hours) * 60);
$row['action_time'] = sprintf('%02d:%02d', $hours, $minutes);
} else {
$row['action_time'] = '---';
}
$data[] = $row;
}
return $data;
}
function getRawMaterials($ids)
{
$response = array();
$idsString = join("','", $ids);
$db = $GLOBALS['db'];
$res = $db->query("SELECT ecmproduct_id, SUM(quantity) AS quantity FROM productionScheduler WHERE id IN ('$idsString') GROUP BY ecmproduct_id");
$rawMaterials = array();
while ($p = $db->fetchByAssoc($res)) {
$rawMaterials = array_merge($rawMaterials, getProductRawMaterials($p['ecmproduct_id'], $p['quantity']));
}
$groupedRawMaterials = [];
foreach ($rawMaterials as $item) {
$productId = $item['ecmproduct_id'];
if (!isset($groupedRawMaterials[$productId])) {
$groupedRawMaterials[$productId] = [
'quantity' => 0,
'isComponent' => $item['isComponent']
];
}
$groupedRawMaterials[$productId]['quantity'] += $item['quantity'];
}
$rawMaterials = [];
foreach ($groupedRawMaterials as $productId => $data) {
$rawMaterials[] = [
'ecmproduct_id' => $productId,
'quantity' => $data['quantity'],
'isComponent' => $data['isComponent'] // Include isComponent in the final array
];
}
global $app_list_strings;
foreach ($rawMaterials as $raw) {
$product = $db->fetchByAssoc($db->query("
SELECT p.id, p.code, p.name, p.group_ks, p.unit_id, p.ems_qty_in_stock as stockState,
GROUP_CONCAT(s.stock_address SEPARATOR ', ') AS stock_addresses
FROM ecmproducts AS p
LEFT JOIN ecmproducts_stock_addresses s ON p.id = s.ecmproduct_id
WHERE p.id='" . $raw['ecmproduct_id'] . "'
GROUP BY p.id
"));
$result['id'] = $product['id'];
$result['name'] = strlen($product['name']) > 55 ? substr($product['name'], 0, 55) . "..." : $product['name'];
$result['fullName'] = $product['name'];
$result['code'] = strlen($product['code']) > 55 ? substr($product['code'], 0, 20) . "..." : $product['code'];
$result['fullCode'] = $product['code'];
$result['quantity'] = $raw['quantity'];
$result['isComponent'] = $raw['isComponent'];
$result['unit'] = $app_list_strings['ecmproducts_unit_dom'][$product['unit_id']];
$result['stockState'] = (!empty($product['stockState'])) ? $product['stockState'] : 0;
$result['stockAddress'] = (!empty($product['stock_addresses'])) ? $product['stock_addresses'] : "";
$response[] = $result;
}
echo json_encode($response);
}
function getProductRawMaterials($productId, $quantity)
{
$db = $GLOBALS['db'];
$response = array();
$componentsQuery = "SELECT
c.ecmcomponent_id,
c.quantity,
(
SELECT COUNT(*)
FROM ecmproductcomponents as nested
WHERE nested.ecmproduct_id = c.ecmcomponent_id
) as nested_components_count
FROM
ecmproductcomponents as c
WHERE
c.ecmproduct_id = '$productId'";
$crows = $db->query($componentsQuery);
while ($c = $db->fetchByAssoc($crows)) {
$response[] = array(
'ecmproduct_id' => $c['ecmcomponent_id'],
'quantity' => $quantity * $c['quantity'],
'isComponent' => $c['nested_components_count'] > 0
);
}
return $response;
}
function saveQty($id, $qty)
{
$db = $GLOBALS['db'];
$query = sprintf("UPDATE productionScheduler SET quantity='%d' WHERE id='%s'", $qty, $id);
$db->query($query);
}
function duplicatePositions($ids)
{
$db = $GLOBALS['db'];
global $current_user;
$ids = explode("|", $ids);
foreach ($ids as $id) {
$res = $db->fetchByAssoc($db->query("SELECT * FROM productionScheduler WHERE id ='$id'"));
$query = sprintf("INSERT INTO productionScheduler VALUES ('%s', '%s', '%s', '%s', '%d', NOW(), NOW(), '%s', '%s', 0, '%s', '%d', '%s', '%s');",
generateUuidV4(), $res['main_id'], $res['ecmsaleitem_id'], $res['ecmsale_id'], $res['quantity'], $current_user->id, $current_user->id, $res['ecmproduct_id'],
$res['is_component'], $res['production_date'], $res['description']);
$db->query($query);
}
}
function removePositions($ids)
{
$db = $GLOBALS['db'];
global $current_user;
$ids = explode("|", $ids);
$query = sprintf("UPDATE productionScheduler SET deleted=1, modified_user_id='%s', date_modified=NOW() WHERE id IN ('%s')",
$current_user->id, join("','", $ids));
$db->query($query);
}
function saveProductionDate($id, $date, $time)
{
$db = $GLOBALS['db'];
$parsedDate = date("Y-m-d", strtotime($date));
if ($parsedDate == '1970-01-01') {
$db->query("UPDATE productionScheduler SET production_date=NULL WHERE id='$id'");
} else {
$parsetDateTime = date("Y-m-d H:i", strtotime($date . ' ' . $time));
$db->query("UPDATE productionScheduler SET production_date='$parsetDateTime' WHERE id='$id'");
}
}
function saveProductDescription($id, $description)
{
$db = $GLOBALS['db'];
$description = mysql_escape_string($description);
$db->query("UPDATE productionScheduler SET description='$description' WHERE id='$id'");
echo "UPDATE productionScheduler SET description='$description' WHERE id='$id'";
}
function exportExcel($ids)
{
$headers = [
'Indeks', 'Nazwa', 'Data produkcji', 'Ilość', 'Ilość ZS', 'Stan', 'ZS E5', 'Typ',
'Status', 'Produkt główny', 'Odbiorca', 'Forma', 'Marka', 'Data wysyłki', 'Uwagi'
];
$sheetData = [$headers];
$ids = explode("|", $ids);
$data = loadSchedulers(null, null, $ids);
foreach ($data as $row) {
$sheetRow = [];
$sheetRow[] = $row['productFullCode'];
$sheetRow[] = $row['productFullName'];
$sheetRow[] = $row['productionDate'];
$sheetRow[] = $row['qty'];
$sheetRow[] = $row['productQty'];
$sheetRow[] = $row['productStockState'];
$sheetRow[] = $row['orderNo'];
$sheetRow[] = $row['orderType'];
$sheetRow[] = $row['orderStatus'];
$sheetRow[] = $row['mainProductCode'];
$sheetRow[] = $row['shippingTo'];
$sheetRow[] = $row['productShape'];
$sheetRow[] = $row['productBrand'];
$sheetRow[] = $row['orderSendDate'];
$sheetRow[] = $row['fullDescription'];
$sheetData[] = $sheetRow;
}
require_once 'modules/EcmReports/BimIT-Reports/lib/xlsxGenerator.php';
$xlsx = Shuchkin\SimpleXLSXGen::fromArray($sheetData);
$xlsx_content = (string)$xlsx;
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'fileContent' => base64_encode($xlsx_content),
'fileName' => 'harmonogram_produkcji.xlsx'
]);
}
function exportPDF($ids)
{
require_once 'modules/EcmReports/BimIT-Reports/lib/tcpdf/tcpdf.php';
$pdf = new TCPDF('L', 'mm', 'A4', true, 'UTF-8');
$pdf->SetCreator('CRM E5');
$pdf->SetAuthor('System E5');
$pdf->SetTitle('Harmonogram produkcji');
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$pdf->SetFont('dejavusans', '', 5);
$headers = [
'Indeks', 'Nazwa', 'Data produkcji', 'Ilość', 'Ilość ZS', 'Stan', 'ZS E5', 'Typ',
'Status', 'Produkt główny', 'Odbiorca', 'Forma', 'Marka', 'Data wysyłki', 'Uwagi'
];
$ids = explode("|", $ids);
$data = loadSchedulers(null, null, $ids);
$widths = [20, 30, 20, 15, 15, 15, 15, 15, 20, 20, 25, 15, 15, 20, 20];
$pdf->SetFillColor(224, 224, 224);
$pdf->SetFont('dejavusans', 'B', 5);
$pdf->Cell($widths[0], 10, $headers[0], 1, 0, 'C', 1);
$pdf->Cell($widths[1], 10, $headers[1], 1, 0, 'C', 1);
$pdf->Cell($widths[2], 10, $headers[2], 1, 0, 'C', 1);
$pdf->Cell($widths[3], 10, $headers[3], 1, 0, 'C', 1);
$pdf->Cell($widths[4], 10, $headers[4], 1, 0, 'C', 1);
$pdf->Cell($widths[5], 10, $headers[5], 1, 0, 'C', 1);
$pdf->Cell($widths[6], 10, $headers[6], 1, 0, 'C', 1);
$pdf->Cell($widths[7], 10, $headers[7], 1, 0, 'C', 1);
$pdf->Cell($widths[8], 10, $headers[8], 1, 0, 'C', 1);
$pdf->Cell($widths[9], 10, $headers[9], 1, 0, 'C', 1);
$pdf->Cell($widths[10], 10, $headers[10], 1, 0, 'C', 1);
$pdf->Cell($widths[11], 10, $headers[11], 1, 0, 'C', 1);
$pdf->Cell($widths[12], 10, $headers[12], 1, 0, 'C', 1);
$pdf->Cell($widths[13], 10, $headers[13], 1, 0, 'C', 1);
$pdf->Cell($widths[14], 10, $headers[14], 1, 1, 'C', 1);
$pdf->SetFont('dejavusans', '', 5);
$pdf->SetFillColor(255, 255, 255);
foreach ($data as $row) {
if ($pdf->getY() > 250) {
$pdf->AddPage();
$pdf->SetFont('dejavusans', 'B', 10);
$pdf->SetFillColor(224, 224, 224);
$pdf->Cell($widths[0], 10, $headers[0], 1, 0, 'C', 1);
$pdf->Cell($widths[1], 10, $headers[1], 1, 0, 'C', 1);
$pdf->Cell($widths[2], 10, $headers[2], 1, 0, 'C', 1);
$pdf->Cell($widths[3], 10, $headers[3], 1, 0, 'C', 1);
$pdf->Cell($widths[4], 10, $headers[4], 1, 0, 'C', 1);
$pdf->Cell($widths[5], 10, $headers[5], 1, 0, 'C', 1);
$pdf->Cell($widths[6], 10, $headers[6], 1, 0, 'C', 1);
$pdf->Cell($widths[7], 10, $headers[7], 1, 0, 'C', 1);
$pdf->Cell($widths[8], 10, $headers[8], 1, 0, 'C', 1);
$pdf->Cell($widths[9], 10, $headers[9], 1, 0, 'C', 1);
$pdf->Cell($widths[10], 10, $headers[10], 1, 0, 'C', 1);
$pdf->Cell($widths[11], 10, $headers[11], 1, 0, 'C', 1);
$pdf->Cell($widths[12], 10, $headers[12], 1, 0, 'C', 1);
$pdf->Cell($widths[13], 10, $headers[13], 1, 0, 'C', 1);
$pdf->Cell($widths[14], 10, $headers[14], 1, 1, 'C', 1);
$pdf->SetFont('dejavusans', '', 9);
$pdf->SetFillColor(255, 255, 255);
}
$startY = $pdf->GetY();
$currentPage = $pdf->getPage();
$pdf->MultiCell($widths[0], 10, $row['productFullCode'], 1, 'L', 1, 0);
if ($currentPage != $pdf->getPage()) {
$startY = $pdf->GetY();
$currentPage = $pdf->getPage();
}
$pdf->SetXY($pdf->GetX(), $startY);
$pdf->MultiCell($widths[1], 10, $row['productFullName'], 1, 'L', 1, 0);
$pdf->SetXY($pdf->GetX(), $startY);
$pdf->Cell($widths[2], 10, $row['productionDate'], 1, 0, 'L', 1);
$pdf->Cell($widths[3], 10, $row['qty'], 1, 0, 'R', 1);
$pdf->Cell($widths[4], 10, $row['productQty'], 1, 0, 'R', 1);
$pdf->Cell($widths[5], 10, $row['productStockState'], 1, 0, 'R', 1);
$pdf->Cell($widths[6], 10, $row['orderNo'], 1, 0, 'L', 1);
$pdf->Cell($widths[7], 10, $row['orderType'], 1, 0, 'L', 1);
$pdf->Cell($widths[8], 10, $row['orderStatus'], 1, 0, 'L', 1);
$pdf->Cell($widths[9], 10, $row['mainProductCode'], 1, 0, 'L', 1);
$pdf->Cell($widths[10], 10, $row['shippingTo'], 1, 0, 'L', 1);
$pdf->Cell($widths[11], 10, $row['productShape'], 1, 0, 'L', 1);
$pdf->Cell($widths[12], 10, $row['productBrand'], 1, 0, 'L', 1);
$pdf->Cell($widths[13], 10, $row['orderSendDate'], 1, 0, 'L', 1);
$pdf->Cell($widths[14], 10, $row['fullDescription'], 1, 1, 'L', 1);
}
$pdf_content = $pdf->Output('', 'S');
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'fileContent' => base64_encode($pdf_content),
'fileName' => 'harmonogram_produkcji.pdf'
]);
}
function generateUuidV4()
{
$data = openssl_random_pseudo_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
function exportExcelWYSIWYG($tableDataJson)
{
if (function_exists('from_html')) {
$tableDataJson = from_html($tableDataJson);
}
$json = getJSONobj();
$rawData = $json->decode($tableDataJson);
if (isset($rawData['jsonObject']) && is_array($rawData['jsonObject'])) {
$tableData = $rawData['jsonObject'];
} else {
$tableData = $rawData;
}
if (empty($tableData) || !is_array($tableData)) {
header('Content-Type: application/json');
echo json_encode(array(
'success' => false,
'error' => 'Failed to decode table data. Type: ' . gettype($tableData)
));
return;
}
require_once 'modules/EcmReports/BimIT-Reports/lib/xlsxGenerator.php';
$xlsx = Shuchkin\SimpleXLSXGen::fromArray($tableData);
$xlsx_content = (string)$xlsx;
header('Content-Type: application/json');
echo json_encode(array(
'success' => true,
'fileContent' => base64_encode($xlsx_content),
'fileName' => 'harmonogram_produkcji.xlsx'
));
}
function updateProductionDate($ids, $hours) {
$db = $GLOBALS['db'];
$ids = explode("|", $ids);
foreach ($ids as $id) {
$res = $db->fetchByAssoc($db->query("SELECT production_date FROM productionScheduler WHERE id ='$id'"));
if ($res['production_date'] && $res['production_date'] != '0000-00-00 00:00:00') {
$newDate = calculateProductionDate($res['production_date'], $hours);
$db->query("UPDATE productionScheduler SET production_date='$newDate:00' WHERE id='$id'");
}
}
}
function calculateProductionDate($currentDateTime, $hoursToAdd) {
$WORK_START = 6 * 60;
$WORK_END = 14 * 60 + 30;
$date = new DateTime($currentDateTime);
$totalMinutesToAdd = $hoursToAdd * 60;
if ($totalMinutesToAdd > 0) {
while ($totalMinutesToAdd > 0) {
$dayOfWeek = $date->format('w');
if ($dayOfWeek == 0 || $dayOfWeek == 6) {
$date = getNextWorkDay($date);
continue;
}
$currentMinutes = $date->format('H') * 60 + $date->format('i');
if ($currentMinutes < $WORK_START) {
$date->setTime(6, 0, 0);
continue;
}
if ($currentMinutes >= $WORK_END) {
$date = getNextWorkDay($date);
continue;
}
$remainingMinutesToday = $WORK_END - $currentMinutes;
if ($totalMinutesToAdd <= $remainingMinutesToday) {
$date->modify('+' . $totalMinutesToAdd . ' minutes');
$totalMinutesToAdd = 0;
} else {
$totalMinutesToAdd -= $remainingMinutesToday;
$date = getNextWorkDay($date);
}
}
}
else if ($totalMinutesToAdd < 0) {
$totalMinutesToAdd = abs($totalMinutesToAdd);
while ($totalMinutesToAdd > 0) {
$dayOfWeek = $date->format('w');
if ($dayOfWeek == 0 || $dayOfWeek == 6) {
$date = getPreviousWorkDay($date);
continue;
}
$currentMinutes = $date->format('H') * 60 + $date->format('i');
if ($currentMinutes > $WORK_END) {
$date->setTime(14, 30, 0);
continue;
}
if ($currentMinutes <= $WORK_START) {
$date = getPreviousWorkDay($date);
continue;
}
$minutesFromStart = $currentMinutes - $WORK_START;
if ($totalMinutesToAdd <= $minutesFromStart) {
$date->modify('-' . $totalMinutesToAdd . ' minutes');
$totalMinutesToAdd = 0;
} else {
$totalMinutesToAdd -= $minutesFromStart;
$date = getPreviousWorkDay($date);
}
}
}
return $date->format('Y-m-d H:i');
}
function getNextWorkDay($date) {
$nextDay = clone $date;
$nextDay->modify('+1 day');
$nextDay->setTime(6, 0, 0);
while ($nextDay->format('w') == 0 || $nextDay->format('w') == 6) {
$nextDay->modify('+1 day');
}
return $nextDay;
}
function getPreviousWorkDay($date) {
$prevDay = clone $date;
$prevDay->modify('-1 day');
$prevDay->setTime(14, 30, 0);
while ($prevDay->format('w') == 0 || $prevDay->format('w') == 6) {
$prevDay->modify('-1 day');
}
return $prevDay;
}