1742 lines
55 KiB
PHP
1742 lines
55 KiB
PHP
<?php
|
|
|
|
trait InstallAPI {
|
|
|
|
public function search_customer() {
|
|
$keyword = trim($_POST['keyword'] ?? '');
|
|
if ($keyword === '') {
|
|
echo $this->json([]);
|
|
return;
|
|
}
|
|
|
|
$keyword = addslashes($keyword);
|
|
$sql = "
|
|
SELECT
|
|
c.c_uid,
|
|
c.c_accountno,
|
|
c.c_name,
|
|
c.c_address,
|
|
c.c_city,
|
|
c.c_postal,
|
|
c.c_phone
|
|
FROM tbl_customer c
|
|
WHERE
|
|
(
|
|
c.c_accountno LIKE '%{$keyword}%'
|
|
OR c.c_name LIKE '%{$keyword}%'
|
|
)
|
|
AND NOT EXISTS (
|
|
SELECT 1
|
|
FROM tbl_install_waitlist iw
|
|
WHERE iw.iw_customer_uid = c.c_uid
|
|
AND iw.iw_status <> 'DELETED'
|
|
)
|
|
ORDER BY c.c_name
|
|
LIMIT 20
|
|
";
|
|
$res = qry($sql);
|
|
|
|
$rows = [];
|
|
while ($row = mysqli_fetch_assoc($res)) {
|
|
$rows[] = $row;
|
|
}
|
|
echo $this->json($rows);
|
|
}
|
|
|
|
public function install_wait_create_draft() {
|
|
$c_uid = $_POST['c_uid'] ?? 0;
|
|
$job_type = $_POST['job_type'] ?? '';
|
|
$driver_uid = $_POST['driver_uid'] ?? '';
|
|
$request_note = $_POST['request_note'] ?? '';
|
|
|
|
if (!$c_uid || !$job_type) {
|
|
echo $this->json(['ok' => 0, 'msg' => 'invalid params']);
|
|
return;
|
|
}
|
|
|
|
$sql = "
|
|
INSERT INTO tbl_install_waitlist (
|
|
iw_customer_uid,
|
|
iw_work_type,
|
|
iw_accountno,
|
|
iw_customer_name,
|
|
iw_address,
|
|
iw_city,
|
|
iw_postal,
|
|
iw_phone,
|
|
iw_lat,
|
|
iw_lng,
|
|
iw_status,
|
|
iw_request_source,
|
|
iw_request_by,
|
|
iw_request_note,
|
|
iw_request_at,
|
|
iw_created_by,
|
|
iw_created_at
|
|
)
|
|
SELECT
|
|
'{$c_uid}' AS iw_customer_uid,
|
|
'".addslashes($job_type)."' AS iw_work_type,
|
|
c.c_accountno AS iw_accountno,
|
|
c.c_name AS iw_customer_name,
|
|
c.c_address AS iw_address,
|
|
c.c_city AS iw_city,
|
|
c.c_postal AS iw_postal,
|
|
c.c_phone AS iw_phone,
|
|
c.c_geolat AS iw_lat,
|
|
c.c_geolon AS iw_lng,
|
|
'DRAFT' AS iw_status,
|
|
'MAP' AS iw_request_source,
|
|
'{$driver_uid}' AS iw_request_by,
|
|
'".addslashes($request_note)."' AS iw_request_note,
|
|
NOW() AS iw_request_at,
|
|
'{$driver_uid}' AS iw_created_by,
|
|
NOW() AS iw_created_at
|
|
FROM tbl_customer c
|
|
WHERE c.c_uid = '{$c_uid}'
|
|
";
|
|
|
|
qry($sql);
|
|
|
|
$iw_uid = mysqli_insert_id($GLOBALS['conn']); // or global db handle
|
|
|
|
echo $this->json([
|
|
'ok' => 1,
|
|
'iw_uid' => $iw_uid
|
|
]);
|
|
}
|
|
|
|
public function install_wait_update_draft() {
|
|
|
|
$iw_uid = intval($_POST['iw_uid'] ?? 0);
|
|
$job_type = addslashes($_POST['job_type'] ?? '');
|
|
$request_note = addslashes($_POST['request_note'] ?? '');
|
|
|
|
if (!$iw_uid) {
|
|
echo $this->json(['ok'=>0,'msg'=>'invalid iw_uid']);
|
|
return;
|
|
}
|
|
|
|
// DRAFT 상태만 수정 가능
|
|
$sqlCheck = "
|
|
SELECT iw_status
|
|
FROM tbl_install_waitlist
|
|
WHERE iw_uid = '{$iw_uid}'
|
|
LIMIT 1
|
|
";
|
|
$r = qry($sqlCheck);
|
|
$row = mysqli_fetch_assoc($r);
|
|
|
|
if (!$row || $row['iw_status'] !== 'DRAFT') {
|
|
echo $this->json(['ok'=>0,'msg'=>'cannot modify this request']);
|
|
return;
|
|
}
|
|
|
|
$sql = "
|
|
UPDATE tbl_install_waitlist
|
|
SET
|
|
iw_work_type = '{$job_type}',
|
|
iw_request_note = '{$request_note}',
|
|
iw_updated_at = NOW()
|
|
WHERE iw_uid = '{$iw_uid}'
|
|
LIMIT 1
|
|
";
|
|
|
|
qry($sql);
|
|
|
|
echo $this->json(['ok'=>1]);
|
|
}
|
|
|
|
public function install_wait_delete_draft() {
|
|
|
|
$iw_uid = intval($_POST['iw_uid'] ?? 0);
|
|
|
|
if (!$iw_uid) {
|
|
echo $this->json(['ok'=>0]);
|
|
return;
|
|
}
|
|
|
|
// 상태 확인
|
|
$sqlCheck = "
|
|
SELECT iw_status
|
|
FROM tbl_install_waitlist
|
|
WHERE iw_uid = '{$iw_uid}'
|
|
LIMIT 1
|
|
";
|
|
|
|
$r = qry($sqlCheck);
|
|
$row = mysqli_fetch_assoc($r);
|
|
|
|
if (!$row || $row['iw_status'] !== 'DRAFT') {
|
|
echo $this->json(['ok'=>0, 'msg'=>'cannot delete']);
|
|
return;
|
|
}
|
|
|
|
// Soft delete
|
|
$sql = "
|
|
UPDATE tbl_install_waitlist
|
|
SET iw_status = 'DELETED',
|
|
iw_deleted_at = NOW()
|
|
WHERE iw_uid = '{$iw_uid}'
|
|
LIMIT 1
|
|
";
|
|
|
|
qry($sql);
|
|
|
|
echo $this->json(['ok'=>1]);
|
|
}
|
|
|
|
|
|
|
|
public function install_wait_get_active() {
|
|
|
|
$c_uid = intval($_POST['c_uid'] ?? 0);
|
|
if (!$c_uid) {
|
|
echo $this->json(['ok'=>0,'msg'=>'invalid params']);
|
|
return;
|
|
}
|
|
|
|
// DRAFT/WAITING/ASSIGNED 중 최신 1개 (원하는 정책이면 ORDER를 상태 우선으로 바꿔도 됨)
|
|
$sql = "
|
|
SELECT
|
|
iw.iw_uid,
|
|
iw.iw_status,
|
|
iw.iw_work_type,
|
|
iw.iw_request_note,
|
|
CASE
|
|
WHEN iw.iw_request_by = 'Customer' THEN 'Customer'
|
|
ELSE CONCAT(IFNULL(m.m_firstname,''), ' ', IFNULL(m.m_lastname,''))
|
|
END AS iw_request_by_name,
|
|
iw.iw_request_by,
|
|
iw.iw_request_at,
|
|
iw.iw_created_at,
|
|
|
|
di.di_install_date,
|
|
di.di_install_time
|
|
|
|
FROM tbl_install_waitlist iw
|
|
LEFT JOIN tbl_daily_install di
|
|
ON di.di_wait_uid = iw.iw_uid
|
|
LEFT JOIN tbl_member m
|
|
ON iw.iw_request_by = m.m_uid
|
|
WHERE iw.iw_customer_uid = '{$c_uid}'
|
|
AND iw.iw_status IN ('DRAFT','WAITING','ASSIGNED')
|
|
ORDER BY iw.iw_uid DESC, di.di_uid DESC
|
|
LIMIT 1
|
|
";
|
|
|
|
$r = qry($sql);
|
|
if ($row = mysqli_fetch_assoc($r)) {
|
|
// (A) iw_uid에 연결된 사진 조회해서 붙이기
|
|
$iw_uid = (int)$row['iw_uid'];
|
|
$photos = [];
|
|
|
|
$sql_img = "
|
|
SELECT i_uid, i_filename, i_filepath
|
|
FROM tbl_customer_image
|
|
WHERE i_status = 'A'
|
|
AND i_type = 'install_order'
|
|
AND i_sourceuid = '{$iw_uid}'
|
|
ORDER BY i_uid ASC
|
|
";
|
|
|
|
$ri = qry($sql_img);
|
|
|
|
while ($img = mysqli_fetch_assoc($ri)) {
|
|
|
|
$imgPath = $img['i_filepath'] . $img['i_filename'];
|
|
|
|
$photos[] = [
|
|
'i_uid' => (int)$img['i_uid'],
|
|
'imgPath' => $imgPath
|
|
];
|
|
}
|
|
|
|
$row['photos'] = $photos;
|
|
|
|
echo $this->json([
|
|
'ok' => 1,
|
|
'exists' => 1,
|
|
'data' => $row
|
|
]);
|
|
return;
|
|
}
|
|
|
|
echo $this->json(['ok'=>1,'exists'=>0]);
|
|
}
|
|
|
|
|
|
public function install_wait_upsert_containers() {
|
|
|
|
$iw_uid = intval($_POST['iw_uid'] ?? 0);
|
|
$items = $_POST['items'] ?? [];
|
|
$action = $_POST['action'];
|
|
|
|
if (!$iw_uid) {
|
|
echo $this->json(['ok' => 0, 'msg' => 'no iw_uid']);
|
|
return;
|
|
}
|
|
|
|
// 기존 컨테이너 전부 삭제
|
|
qry("
|
|
DELETE FROM tbl_install_waitlist_container
|
|
WHERE iwc_wait_uid = '{$iw_uid}' AND iwc_action = '{$action}'
|
|
");
|
|
|
|
// 재 insert
|
|
if (is_array($items)) {
|
|
foreach ($items as $it) {
|
|
|
|
$action = addslashes($it['action'] ?? '');
|
|
$type = addslashes($it['type'] ?? '');
|
|
$capacity = isset($it['capacity']) && $it['capacity'] !== ''
|
|
? intval($it['capacity'])
|
|
: 'NULL';
|
|
$is_used = addslashes($it['is_used'] ?? 'N');
|
|
$owner_type = addslashes($it['owner_type'] ?? 'C');
|
|
$has_lock = addslashes($it['has_lock'] ?? 'N');
|
|
$has_wheel = addslashes($it['has_wheel'] ?? 'N');
|
|
$has_frame = addslashes($it['has_frame'] ?? 'N');
|
|
|
|
$sql = "
|
|
INSERT INTO tbl_install_waitlist_container
|
|
SET
|
|
iwc_wait_uid = '{$iw_uid}',
|
|
iwc_action = '{$action}',
|
|
iwc_type = '{$type}',
|
|
iwc_capacity = {$capacity},
|
|
iwc_is_used = '{$is_used}',
|
|
iwc_owner_type = '{$owner_type}',
|
|
iwc_has_lock = '{$has_lock}',
|
|
iwc_has_wheel = '{$has_wheel}',
|
|
iwc_has_woodframe = '{$has_frame}'
|
|
";
|
|
qry($sql);
|
|
}
|
|
}
|
|
|
|
echo $this->json(['ok' => 1]);
|
|
}
|
|
|
|
|
|
public function get_customer_containers_active() {
|
|
|
|
$c_uid = intval($_POST['c_uid'] ?? 0);
|
|
if (!$c_uid) {
|
|
echo $this->json([]);
|
|
return;
|
|
}
|
|
|
|
$sql = "
|
|
SELECT
|
|
cc_uid,
|
|
cc_type,
|
|
cc_capacity,
|
|
cc_owner_type,
|
|
cc_is_used,
|
|
cc_has_lock,
|
|
cc_has_wheel,
|
|
cc_has_woodframe
|
|
FROM tbl_customer_container
|
|
WHERE cc_customer_uid = '{$c_uid}'
|
|
AND cc_status = 'A'
|
|
ORDER BY cc_type, cc_capacity
|
|
";
|
|
|
|
$res = qry($sql);
|
|
|
|
$rows = [];
|
|
while ($row = mysqli_fetch_assoc($res)) {
|
|
$rows[] = $row;
|
|
}
|
|
|
|
echo $this->json($rows);
|
|
}
|
|
|
|
public function install_wait_delete() {
|
|
|
|
$iw_uid = intval($_POST['iw_uid'] ?? 0);
|
|
|
|
if (!$iw_uid) {
|
|
echo $this->json(['ok' => 0, 'msg' => 'ID is missing']);
|
|
return;
|
|
}
|
|
|
|
// qry() + fetch
|
|
$rs = qry("SELECT iw_status FROM tbl_install_waitlist WHERE iw_uid = '{$iw_uid}'");
|
|
$row = mysqli_fetch_assoc($rs);
|
|
|
|
if (!$row) {
|
|
echo $this->json(['ok' => 0, 'msg' => 'Item not found']);
|
|
return;
|
|
}
|
|
|
|
qry("START TRANSACTION");
|
|
// 지우지는 말자.
|
|
// $ok1 = qry("DELETE FROM tbl_install_waitlist_container WHERE iwc_wait_uid = '{$iw_uid}'");
|
|
if (!$this->update_waitlist_status($iw_uid, 'DELETED')) {
|
|
qry("ROLLBACK");
|
|
$fail('update_waitlist', 'failed', ['iw_uid'=>$iw_uid]);
|
|
}
|
|
|
|
qry("COMMIT");
|
|
echo $this->json(['ok' => 1]);
|
|
}
|
|
|
|
|
|
public function install_wait_complete() {
|
|
|
|
$iw_uid = intval($_POST['iw_uid'] ?? 0);
|
|
if (!$iw_uid) {
|
|
echo $this->json(['ok' => 0, 'msg' => 'no iw_uid']);
|
|
return;
|
|
}
|
|
|
|
// set parameters
|
|
$request_at = $_POST['request_at'] ?? null;
|
|
$due_date = $_POST['due_date'] ?? null;
|
|
$request_by = $_POST['request_by'] ?? null;
|
|
$request_note = $_POST['request_note'] ?? null;
|
|
$cs_note = $_POST['cs_note'] ?? null;
|
|
$work_note = $_POST['work_note'] ?? null;
|
|
|
|
$person_cnt = $_POST['person_cnt'] ?? null; // null or 2
|
|
$person_reason= $_POST['person_reason'] ?? null;
|
|
|
|
$scheduled = intval($_POST['scheduled'] ?? 0);
|
|
$cycle = intval($_POST['scheduled_cycle'] ?? 0);
|
|
|
|
// Two-person OFF = NULL
|
|
if (!$person_cnt) {
|
|
$person_cnt = null;
|
|
$person_reason = null;
|
|
}
|
|
|
|
// Recurring OFF = 0
|
|
if (!$scheduled) {
|
|
$cycle = 0;
|
|
}
|
|
|
|
qry("
|
|
UPDATE tbl_install_waitlist
|
|
SET
|
|
iw_request_at = ".($request_at ? "'{$request_at}'" : "NOW()").",
|
|
iw_requested_due_date = ".($due_date ? "'{$due_date}'" : "NULL").",
|
|
iw_request_by = ".($request_by ? "'{$request_by}'" : "NULL").",
|
|
iw_request_note = ".($request_note ? "'".addslashes($request_note)."'" : "NULL").",
|
|
iw_cs_note = ".($cs_note ? "'".addslashes($cs_note)."'" : "NULL").",
|
|
iw_work_note = ".($work_note ? "'".addslashes($work_note)."'" : "NULL").",
|
|
|
|
iw_required_person_cnt = ".($person_cnt !== null ? intval($person_cnt) : "NULL").",
|
|
iw_multi_person_reason = ".($person_reason ? "'".addslashes($person_reason)."'" : "NULL").",
|
|
|
|
iw_scheduled = '{$scheduled}',
|
|
iw_scheduled_cycle = '{$cycle}',
|
|
|
|
iw_status = 'WAITING'
|
|
WHERE iw_uid = '{$iw_uid}'
|
|
LIMIT 1
|
|
");
|
|
|
|
echo $this->json(['ok' => 1]);
|
|
}
|
|
|
|
// 수정을 위한
|
|
public function get_install_wait_detail() {
|
|
$iw_uid = intval($_POST['iw_uid'] ?? 0);
|
|
|
|
$rs = qry("
|
|
SELECT *
|
|
FROM tbl_install_waitlist
|
|
WHERE iw_uid = '{$iw_uid}'
|
|
LIMIT 1
|
|
");
|
|
$row = mysqli_fetch_assoc($rs);
|
|
|
|
echo json_encode($row ?: null);
|
|
}
|
|
|
|
public function get_install_wait_containers() {
|
|
$iw_uid = intval($_POST['iw_uid'] ?? 0);
|
|
|
|
$rows = [];
|
|
$rs = qry("
|
|
SELECT *
|
|
FROM tbl_install_waitlist_container
|
|
WHERE iwc_wait_uid = '{$iw_uid}'
|
|
ORDER BY iwc_action
|
|
");
|
|
while ($r = mysqli_fetch_assoc($rs)) {
|
|
$rows[] = $r;
|
|
}
|
|
|
|
echo json_encode($rows);
|
|
}
|
|
|
|
|
|
// =========================================
|
|
// install wait list - right
|
|
// =========================================
|
|
public function inq_daily_install_points() {
|
|
|
|
$di_install_date = trim($_POST['di_install_date'] ?? '');
|
|
$di_driver_uid = intval($_POST['di_driver_uid'] ?? 0);
|
|
|
|
if (!$di_install_date || !$di_driver_uid) {
|
|
echo $this->json([]);
|
|
return;
|
|
}
|
|
|
|
// install.php 스타일: addslashes / qry
|
|
$date = addslashes($di_install_date);
|
|
|
|
$sql = "
|
|
SELECT
|
|
di.di_uid,
|
|
di.di_order_seq,
|
|
di.di_driver_uid,
|
|
ifnull(mem.m_initial,'') as di_customer_driver_initial,
|
|
di.di_install_date,
|
|
di.di_install_time,
|
|
di.di_wait_uid,
|
|
di.di_customer_uid,
|
|
di.di_accountno,
|
|
di.di_phone,
|
|
di.di_address,
|
|
di.di_city,
|
|
di.di_postal,
|
|
di.di_lat,
|
|
di.di_lng,
|
|
di.di_work_type,
|
|
di.di_status,
|
|
c.c_name AS di_customer_name,
|
|
SUM(
|
|
CASE
|
|
WHEN dic.dic_action = 'REMOVE'
|
|
AND dic.dic_type = 'D'
|
|
THEN 1 ELSE 0
|
|
END
|
|
) AS remove_d_cnt,
|
|
SUM(
|
|
CASE
|
|
WHEN dic.dic_action = 'REMOVE'
|
|
AND dic.dic_type <> 'D'
|
|
THEN 1 ELSE 0
|
|
END
|
|
) AS remove_b_cnt,
|
|
SUM(
|
|
CASE
|
|
WHEN dic.dic_action = 'INSTALL'
|
|
AND dic.dic_type = 'D'
|
|
THEN 1 ELSE 0
|
|
END
|
|
) AS install_d_cnt,
|
|
SUM(
|
|
CASE
|
|
WHEN dic.dic_action = 'INSTALL'
|
|
AND dic.dic_type <> 'D'
|
|
THEN 1 ELSE 0
|
|
END
|
|
) AS install_b_cnt
|
|
|
|
FROM tbl_daily_install di
|
|
LEFT JOIN tbl_member mem
|
|
ON di.di_customer_driver_uid = mem.m_uid
|
|
LEFT JOIN tbl_customer c
|
|
ON c.c_uid = di.di_customer_uid
|
|
LEFT JOIN tbl_daily_install_container dic
|
|
ON dic.dic_di_uid = di.di_uid
|
|
WHERE di.di_status = 'A'
|
|
AND di.di_install_date = '{$date}'
|
|
AND di.di_driver_uid = '{$di_driver_uid}'
|
|
GROUP BY di.di_uid
|
|
ORDER BY di.di_order_seq ASC
|
|
|
|
";
|
|
|
|
$res = qry($sql);
|
|
|
|
$rows = [];
|
|
while ($row = mysqli_fetch_assoc($res)) {
|
|
$rows[] = $row;
|
|
}
|
|
|
|
echo $this->json($rows);
|
|
}
|
|
|
|
private function insert_daily_install_from_waitlist($iw_uid, $di_driver_uid, $di_install_date, $di_order_seq) {
|
|
|
|
$created_by = mysqli_real_escape_string($GLOBALS['conn'], $_SESSION['ss_UID'] ?? '');
|
|
$sql = "
|
|
INSERT INTO tbl_daily_install (
|
|
di_order_seq,
|
|
di_driver_uid,
|
|
di_install_date,
|
|
di_wait_uid,
|
|
di_customer_uid,
|
|
di_customer_name,
|
|
di_customer_driver_uid,
|
|
di_accountno,
|
|
di_phone,
|
|
di_address,
|
|
di_city,
|
|
di_postal,
|
|
di_lat,
|
|
di_lng,
|
|
di_work_type,
|
|
di_oil_pickup,
|
|
di_request_note,
|
|
di_work_note,
|
|
di_created_by
|
|
)
|
|
SELECT
|
|
'{$di_order_seq}',
|
|
'{$di_driver_uid}',
|
|
'{$di_install_date}',
|
|
iw.iw_uid,
|
|
iw.iw_customer_uid,
|
|
iw.iw_customer_name,
|
|
c.c_driveruid,
|
|
iw.iw_accountno,
|
|
iw.iw_phone,
|
|
iw.iw_address,
|
|
iw.iw_city,
|
|
iw.iw_postal,
|
|
iw.iw_lat,
|
|
iw.iw_lng,
|
|
iw.iw_work_type,
|
|
iw.iw_need_oil_pickup,
|
|
iw.iw_request_note,
|
|
iw.iw_work_note,
|
|
'{$created_by}'
|
|
FROM tbl_install_waitlist iw
|
|
LEFT JOIN tbl_customer c
|
|
ON c.c_uid = iw.iw_customer_uid
|
|
WHERE iw_uid = '{$iw_uid}'
|
|
";
|
|
|
|
if (!qry($sql)) {
|
|
return false;
|
|
}
|
|
|
|
return mysqli_insert_id($GLOBALS['conn']);
|
|
}
|
|
|
|
private function insert_daily_install_container_from_waitlist($di_uid, $iw_uid) {
|
|
|
|
$sql = "
|
|
INSERT INTO tbl_daily_install_container (
|
|
dic_di_uid,
|
|
dic_action,
|
|
dic_type,
|
|
dic_capacity,
|
|
dic_is_used,
|
|
dic_has_lock,
|
|
dic_has_wheel,
|
|
dic_has_woodframe,
|
|
dic_owner_type
|
|
)
|
|
SELECT
|
|
'{$di_uid}',
|
|
iwc_action,
|
|
iwc_type,
|
|
iwc_capacity,
|
|
iwc_is_used,
|
|
iwc_has_lock,
|
|
iwc_has_wheel,
|
|
iwc_has_woodframe,
|
|
iwc_owner_type
|
|
FROM tbl_install_waitlist_container
|
|
WHERE iwc_wait_uid = '{$iw_uid}'
|
|
";
|
|
|
|
// 0 row여도 정상
|
|
return qry($sql) !== false;
|
|
}
|
|
|
|
private function update_waitlist_status($iw_uid, $status) {
|
|
|
|
$status = mysqli_real_escape_string($GLOBALS['conn'], $status);
|
|
|
|
$sql = "
|
|
UPDATE tbl_install_waitlist
|
|
SET iw_status = '{$status}'
|
|
WHERE iw_uid = '{$iw_uid}'
|
|
";
|
|
|
|
return qry($sql);
|
|
}
|
|
|
|
public function confirm_daily_install() {
|
|
|
|
$trial_rows = $_POST['trial_rows'] ?? [];
|
|
$existing_rows = $_POST['existing_rows'] ?? [];
|
|
$di_driver_uid = intval($_POST['di_driver_uid'] ?? 0);
|
|
$di_install_date = $_POST['di_install_date'] ?? null;
|
|
|
|
$fail = function($stage, $msg, $extra = []) {
|
|
echo $this->json(array_merge([
|
|
'ok' => 0,
|
|
'stage' => $stage,
|
|
'msg' => $msg,
|
|
'db' => mysqli_error($GLOBALS['conn'])
|
|
], $extra));
|
|
exit;
|
|
};
|
|
|
|
if (!$di_driver_uid || !$di_install_date) {
|
|
$fail('validate', 'invalid params');
|
|
}
|
|
|
|
// 둘 다 비면 아무것도 할게 없음
|
|
if ((!is_array($trial_rows) || !count($trial_rows)) && (!is_array($existing_rows) || !count($existing_rows))) {
|
|
$fail('validate', 'nothing to confirm');
|
|
}
|
|
|
|
qry("START TRANSACTION");
|
|
|
|
/* =======================================================
|
|
A) 기존 daily_install 순서 업데이트
|
|
======================================================= */
|
|
if (is_array($existing_rows) && count($existing_rows)) {
|
|
foreach ($existing_rows as $idx => $row) {
|
|
$di_uid = intval($row['di_uid'] ?? 0);
|
|
$di_order_seq = intval($row['di_order_seq'] ?? 0);
|
|
|
|
if (!$di_uid || !$di_order_seq) {
|
|
qry("ROLLBACK");
|
|
$fail('validate_existing_row', 'invalid existing row', ['row'=>$row]);
|
|
}
|
|
|
|
// driver/date까지 같이 조건으로 걸면 더 안전함 (다른 날짜/driver 수정 방지)
|
|
$sql = "
|
|
UPDATE tbl_daily_install
|
|
SET di_order_seq = '{$di_order_seq}'
|
|
WHERE di_uid = '{$di_uid}'
|
|
AND di_driver_uid = '{$di_driver_uid}'
|
|
AND di_install_date = '{$di_install_date}'
|
|
LIMIT 1
|
|
";
|
|
|
|
if (!qry($sql)) {
|
|
qry("ROLLBACK");
|
|
$fail('update_existing_order', 'failed', ['di_uid'=>$di_uid]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* =======================================================
|
|
B) trial(waitlist) -> daily_install INSERT + status update
|
|
======================================================= */
|
|
if (is_array($trial_rows) && count($trial_rows)) {
|
|
foreach ($trial_rows as $idx => $row) {
|
|
|
|
$iw_uid = intval($row['iw_uid'] ?? 0);
|
|
$di_order_seq = intval($row['di_order_seq'] ?? 0);
|
|
|
|
if (!$iw_uid || !$di_order_seq) {
|
|
qry("ROLLBACK");
|
|
$fail('validate_trial_row', 'invalid trial row', ['row'=>$row]);
|
|
}
|
|
|
|
$di_uid = $this->insert_daily_install_from_waitlist(
|
|
$iw_uid,
|
|
$di_driver_uid,
|
|
$di_install_date,
|
|
$di_order_seq
|
|
);
|
|
|
|
if (!$di_uid) {
|
|
qry("ROLLBACK");
|
|
$fail('insert_daily_install', 'failed', ['iw_uid'=>$iw_uid]);
|
|
}
|
|
|
|
if (!$this->insert_daily_install_container_from_waitlist($di_uid, $iw_uid)) {
|
|
qry("ROLLBACK");
|
|
$fail('insert_container', 'failed', ['iw_uid'=>$iw_uid]);
|
|
}
|
|
|
|
if (!$this->update_waitlist_status($iw_uid, 'ASSIGNED')) {
|
|
qry("ROLLBACK");
|
|
$fail('update_waitlist', 'failed', ['iw_uid'=>$iw_uid]);
|
|
}
|
|
}
|
|
}
|
|
|
|
qry("COMMIT");
|
|
echo $this->json(['ok'=>1]);
|
|
exit;
|
|
}
|
|
|
|
|
|
public function unassign_daily_install() {
|
|
|
|
$di_uid = intval($_POST['di_uid'] ?? 0);
|
|
if (!$di_uid) {
|
|
echo $this->json(['ok'=>0,'msg'=>'invalid di_uid']);
|
|
return;
|
|
}
|
|
|
|
$fail = function($stage, $msg, $extra = []) {
|
|
echo $this->json(array_merge([
|
|
'ok' => 0,
|
|
'stage' => $stage,
|
|
'msg' => $msg,
|
|
'db' => mysqli_error($GLOBALS['conn'])
|
|
], $extra));
|
|
exit;
|
|
};
|
|
|
|
$qr = qry("SELECT di_wait_uid, di_driver_uid, di_install_date FROM tbl_daily_install WHERE di_uid = '{$di_uid}'");
|
|
$row = fetch_array($qr);
|
|
|
|
if (empty($row['di_wait_uid'])) {
|
|
$fail('select', 'daily_install not found', ['di_uid'=>$di_uid]);
|
|
}
|
|
|
|
$iw_uid = intval($row['di_wait_uid']);
|
|
$di_driver_uid = intval($row['di_driver_uid']);
|
|
$di_install_date = $row['di_install_date']; // ✅ 문자열 유지
|
|
|
|
qry("START TRANSACTION");
|
|
|
|
// container 삭제는 하지말자.
|
|
// if (qry("DELETE FROM tbl_daily_install_container WHERE dic_di_uid = '{$di_uid}'") === false) {
|
|
// qry("ROLLBACK");
|
|
// $fail('delete_container', 'failed', ['di_uid'=>$di_uid]);
|
|
// }
|
|
|
|
// daily_install 삭제
|
|
if (!qry("DELETE FROM tbl_daily_install WHERE di_uid = '{$di_uid}' LIMIT 1")) {
|
|
qry("ROLLBACK");
|
|
$fail('delete_daily_install', 'failed', ['di_uid'=>$di_uid]);
|
|
}
|
|
|
|
// waitlist WAITING 복귀
|
|
if (!$this->update_waitlist_status($iw_uid, 'WAITING')) {
|
|
qry("ROLLBACK");
|
|
$fail('update_waitlist', 'failed', ['iw_uid'=>$iw_uid]);
|
|
}
|
|
|
|
// seq 재정렬 (같은 driver/date)
|
|
if (!$this->resequence_daily_install($di_driver_uid, $di_install_date)) {
|
|
qry("ROLLBACK");
|
|
$fail('resequence', 'failed', ['di_driver_uid'=>$di_driver_uid,'di_install_date'=>$di_install_date]);
|
|
}
|
|
|
|
qry("COMMIT");
|
|
echo $this->json(['ok'=>1]);
|
|
}
|
|
|
|
public function resequence_daily_install($di_driver_uid, $di_install_date) {
|
|
|
|
$di_driver_uid = intval($di_driver_uid);
|
|
$di_install_date = mysqli_real_escape_string($GLOBALS['conn'], $di_install_date);
|
|
|
|
$qr = qry("
|
|
SELECT di_uid
|
|
FROM tbl_daily_install
|
|
WHERE di_driver_uid = '{$di_driver_uid}'
|
|
AND di_install_date = '{$di_install_date}'
|
|
AND di_status = 'A'
|
|
ORDER BY di_order_seq ASC, di_uid ASC
|
|
");
|
|
|
|
if (!$qr) return false;
|
|
|
|
$seq = 1;
|
|
while ($row = fetch_array($qr)) {
|
|
$di_uid = intval($row['di_uid']);
|
|
if (!qry("UPDATE tbl_daily_install SET di_order_seq = '{$seq}' WHERE di_uid = '{$di_uid}'")) {
|
|
return false;
|
|
}
|
|
$seq++;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function update_waitlist_latlng() {
|
|
|
|
$iw_uid = intval($_POST['iw_uid'] ?? 0);
|
|
$lat = $_POST['lat'] ?? null;
|
|
$lng = $_POST['lng'] ?? null;
|
|
|
|
if (!$iw_uid || !$lat || !$lng) {
|
|
echo $this->json(['ok'=>0,'msg'=>'invalid params']);
|
|
return;
|
|
}
|
|
|
|
$lat = floatval($lat);
|
|
$lng = floatval($lng);
|
|
|
|
$sql = "
|
|
UPDATE tbl_install_waitlist
|
|
SET
|
|
iw_lat = '{$lat}',
|
|
iw_lng = '{$lng}'
|
|
WHERE iw_uid = '{$iw_uid}'
|
|
LIMIT 1
|
|
";
|
|
|
|
if (!qry($sql)) {
|
|
echo $this->json([
|
|
'ok' => 0,
|
|
'msg'=> 'update failed',
|
|
'db' => mysqli_error($GLOBALS['conn'])
|
|
]);
|
|
return;
|
|
}
|
|
|
|
echo $this->json(['ok'=>1]);
|
|
}
|
|
|
|
public function get_customer_container_one(){
|
|
$cc_uid = intval($_POST['cc_uid']);
|
|
|
|
$r = mysqli_query($GLOBALS['conn'],"SELECT * FROM tbl_customer_container WHERE cc_uid='{$cc_uid}' LIMIT 1");
|
|
$row = mysqli_fetch_assoc($r);
|
|
|
|
if(!$row){
|
|
echo $this->json(['ok'=>0]);
|
|
return;
|
|
}
|
|
|
|
if(!$row){
|
|
echo $this->json(['ok'=>0]);
|
|
return;
|
|
}
|
|
echo $this->json(['ok'=>1,'row'=>$row]);
|
|
}
|
|
|
|
public function customer_container_save(){
|
|
|
|
$mode = $_POST['mode'] ?? 'ADD';
|
|
$cc_uid = intval($_POST['cc_uid'] ?? 0);
|
|
$c_uid = intval($_POST['c_uid'] ?? 0);
|
|
|
|
$type = addslashes($_POST['type'] ?? '');
|
|
$capacity = $_POST['capacity'] !== '' ? intval($_POST['capacity']) : "NULL";
|
|
$is_used = $_POST['is_used'] ?? 'N';
|
|
$has_lock = $_POST['has_lock'] ?? 'N';
|
|
$has_wheel = $_POST['has_wheel'] ?? 'N';
|
|
$has_frame = $_POST['has_frame'] ?? 'N';
|
|
$owner_type = $_POST['owner_type'] ?? 'C';
|
|
$install_date = $_POST['install_date'] ?? null;
|
|
$remove_date = $_POST['remove_date'] ?? null;
|
|
$install_note = addslashes($_POST['install_note'] ?? '');
|
|
$remove_note = addslashes($_POST['remove_note'] ?? '');
|
|
|
|
if($mode==='ADD'){
|
|
$sql = "
|
|
INSERT INTO tbl_customer_container
|
|
(cc_customer_uid,cc_type,cc_capacity,cc_is_used,
|
|
cc_has_lock,cc_has_wheel,cc_has_woodframe,cc_owner_type,
|
|
cc_status,cc_install_at,cc_install_note,
|
|
cc_createddate,cc_updateddate)
|
|
VALUES(
|
|
'{$c_uid}','{$type}',{$capacity},
|
|
'{$is_used}','{$has_lock}','{$has_wheel}','{$has_frame}','{$owner_type}',
|
|
'A','{$install_date}','{$install_note}',
|
|
DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),
|
|
DATE_FORMAT(NOW(),'%Y%m%d%H%i%s')
|
|
)
|
|
";
|
|
qry($sql);
|
|
}
|
|
|
|
if ($mode === 'EDIT') {
|
|
|
|
$result = qry("SELECT cc_status FROM tbl_customer_container WHERE cc_uid='{$cc_uid}'");
|
|
$row = mysqli_fetch_assoc($result);
|
|
|
|
if (!$row) {
|
|
echo $this->json(['ok'=>0,'msg'=>'invalid container']);
|
|
return;
|
|
}
|
|
|
|
$status = $row['cc_status'];
|
|
// 날짜 처리 (빈 값이면 NULL)
|
|
$install_at_sql = $install_date ? "'{$install_date} 00:00:00'" : "NULL";
|
|
$remove_at_sql = $remove_date ? "'{$remove_date} 00:00:00'" : "NULL";
|
|
|
|
// ===== ACTIVE 수정 =====
|
|
if ($status === 'A') {
|
|
$sql = "
|
|
UPDATE tbl_customer_container SET
|
|
cc_capacity={$capacity},
|
|
cc_is_used='{$is_used}',
|
|
cc_has_lock='{$has_lock}',
|
|
cc_has_wheel='{$has_wheel}',
|
|
cc_has_woodframe='{$has_frame}',
|
|
cc_owner_type='{$owner_type}',
|
|
cc_install_at={$install_at_sql},
|
|
cc_install_note='{$install_note}',
|
|
cc_modified_at=NOW(),
|
|
cc_updateddate=DATE_FORMAT(NOW(),'%Y%m%d%H%i%s')
|
|
WHERE cc_uid='{$cc_uid}'
|
|
";
|
|
qry($sql);
|
|
}
|
|
// ===== INACTIVE 수정 =====
|
|
else {
|
|
$sql = "
|
|
UPDATE tbl_customer_container SET
|
|
cc_remove_at={$remove_at_sql},
|
|
cc_remove_note='{$remove_note}',
|
|
cc_modified_at=NOW(),
|
|
cc_updateddate=DATE_FORMAT(NOW(),'%Y%m%d%H%i%s')
|
|
WHERE cc_uid='{$cc_uid}'
|
|
";
|
|
qry($sql);
|
|
}
|
|
}
|
|
|
|
if($mode==='REMOVE'){
|
|
$sql="
|
|
UPDATE tbl_customer_container SET
|
|
cc_status='I',
|
|
cc_remove_date='{$remove_date}',
|
|
cc_remove_note='{$remove_note}',
|
|
cc_remove_at=NOW(),
|
|
cc_updateddate=DATE_FORMAT(NOW(),'%Y%m%d%H%i%s')
|
|
WHERE cc_uid='{$cc_uid}'
|
|
";
|
|
qry($sql);
|
|
}
|
|
|
|
//
|
|
if ($install_date) {
|
|
|
|
$install_yyyymmdd = str_replace('-', '', $install_date);
|
|
|
|
// 현재 c_installdate 가져오기
|
|
$r = qry("SELECT c_installdate FROM tbl_customer WHERE c_uid='{$c_uid}'");
|
|
$row = mysqli_fetch_assoc($r);
|
|
$current = $row['c_installdate'];
|
|
|
|
if (!$current || $current === 'N/A' || $install_yyyymmdd < $current) {
|
|
|
|
qry("
|
|
UPDATE tbl_customer
|
|
SET c_installdate='{$install_yyyymmdd}'
|
|
WHERE c_uid='{$c_uid}'
|
|
");
|
|
}
|
|
}
|
|
|
|
if ($remove_date) {
|
|
|
|
$remove_yyyymmdd = str_replace('-', '', $remove_date);
|
|
|
|
$r = qry("SELECT c_removaldate FROM tbl_customer WHERE c_uid='{$c_uid}'");
|
|
$row = mysqli_fetch_assoc($r);
|
|
$current = $row['c_removaldate'];
|
|
|
|
if (!$current || $current === 'N/A' || $remove_yyyymmdd > $current) {
|
|
|
|
qry("
|
|
UPDATE tbl_customer
|
|
SET c_removaldate='{$remove_yyyymmdd}'
|
|
WHERE c_uid='{$c_uid}'
|
|
");
|
|
}
|
|
}
|
|
|
|
|
|
echo $this->json(['ok'=>1]);
|
|
}
|
|
|
|
// DAILY INSTALL
|
|
public function daily_install_update_status()
|
|
{
|
|
$di_uid = intval($_POST['di_uid'] ?? 0);
|
|
$member_uid = intval($_POST['member_uid'] ?? 0);
|
|
$newStatus = strtoupper(trim($_POST['status'] ?? ''));
|
|
$note = trim($_POST['install_note'] ?? '');
|
|
$oil_qty = intval($_POST['oil_qty'] ?? 0);
|
|
|
|
$allowed = ['P','M','X'];
|
|
|
|
$fail = function($stage, $msg) {
|
|
echo $this->json([
|
|
'ok' => 0,
|
|
'stage' => $stage,
|
|
'msg' => $msg,
|
|
'db' => mysqli_error($GLOBALS['conn'])
|
|
]);
|
|
exit;
|
|
};
|
|
|
|
if(!$di_uid || !$member_uid || !in_array($newStatus, $allowed)){
|
|
$fail('validate', 'invalid params');
|
|
}
|
|
|
|
// 1) install 조회
|
|
$qr = qry("
|
|
SELECT *
|
|
FROM tbl_daily_install
|
|
WHERE di_uid = '{$di_uid}'
|
|
LIMIT 1
|
|
");
|
|
$di = mysqli_fetch_assoc($qr);
|
|
if(!$di){
|
|
$fail('select_di', 'not found');
|
|
}
|
|
|
|
qry("START TRANSACTION");
|
|
|
|
try {
|
|
|
|
// 2) 상태 업데이트
|
|
$this->updateDailyInstallStatus($di_uid, $newStatus, $note, $oil_qty);
|
|
|
|
// 3) 컨테이너 반영
|
|
if ($di['di_status'] === 'A' && $newStatus === 'P') {
|
|
$this->apply_container_changes_for_di($di_uid, intval($di['di_customer_uid']));
|
|
}
|
|
|
|
// 4) oil pickup → daily
|
|
$this->saveDailyFromInstallIfNeeded($di_uid, $oil_qty);
|
|
|
|
// 5) waitlist 처리
|
|
$this->handleWaitlistAfterInstall($di, $newStatus, $member_uid, $note);
|
|
|
|
// 6) 순서 재정렬
|
|
$this->reorder_daily_install_sequence(
|
|
$di['di_driver_uid'],
|
|
$di['di_install_date']
|
|
);
|
|
|
|
qry("COMMIT");
|
|
echo $this->json(['ok'=>1]);
|
|
exit;
|
|
|
|
} catch (Exception $e) {
|
|
qry("ROLLBACK");
|
|
$fail('exception', $e->getMessage());
|
|
}
|
|
}
|
|
|
|
private function updateDailyInstallStatus(
|
|
int $di_uid,
|
|
string $newStatus,
|
|
string $note,
|
|
int $oil_qty
|
|
)
|
|
{
|
|
$conn = $GLOBALS['conn'];
|
|
|
|
$newStatus = mysqli_real_escape_string($conn, $newStatus);
|
|
$noteEsc = mysqli_real_escape_string($conn, $note);
|
|
$oil_qty = intval($oil_qty);
|
|
|
|
$sql = "
|
|
UPDATE tbl_daily_install
|
|
SET
|
|
di_status = '{$newStatus}',
|
|
di_install_note = '{$noteEsc}',
|
|
di_oil_pickup = '{$oil_qty}',
|
|
di_install_time = IF('{$newStatus}' <> 'A', CURTIME(), di_install_time)
|
|
WHERE di_uid = '{$di_uid}'
|
|
LIMIT 1
|
|
";
|
|
|
|
if (!qry($sql)) {
|
|
throw new Exception('daily install status update failed');
|
|
}
|
|
}
|
|
|
|
private function saveDailyFromInstallIfNeeded(int $di_uid, int $oil_qty): void
|
|
{
|
|
// 0이면 daily에 반영할 필요 없음
|
|
if ($oil_qty <= 0) return;
|
|
|
|
// payload 만들기
|
|
$payload = $this->buildDailyPayloadFromInstall($di_uid, $oil_qty);
|
|
|
|
// ************************************************* payload 에 아래 포함시켜라.
|
|
// $payload['d_jobtype'] = $payload['d_jobtype'] ?? 'INSTALL';
|
|
|
|
$this->saveDaily($payload, ['in_tx' => 1]);
|
|
}
|
|
|
|
private function handleWaitlistAfterInstall(array $di, string $newStatus, int $member_uid, string $note)
|
|
{
|
|
$wait_uid = intval($di['di_wait_uid']);
|
|
if ($wait_uid <= 0) return;
|
|
|
|
if (in_array($newStatus, ['P','M'])) {
|
|
|
|
$this->updateWaitlistStatus($wait_uid, 'COMPLETED');
|
|
|
|
$this->createNextScheduleIfNeeded(
|
|
$wait_uid,
|
|
$di['di_install_date'],
|
|
$member_uid
|
|
);
|
|
|
|
} elseif ($newStatus === 'X') {
|
|
|
|
$this->updateWaitlistStatus($wait_uid, 'WAITING', $member_uid, $note);
|
|
}
|
|
}
|
|
|
|
private function updateWaitlistStatus(
|
|
int $wait_uid,
|
|
string $status,
|
|
?int $member_uid = null,
|
|
?string $note = null
|
|
)
|
|
{
|
|
$status = strtoupper($status);
|
|
|
|
$allowed = ['COMPLETED', 'WAITING'];
|
|
if (!in_array($status, $allowed, true)) {
|
|
throw new Exception('invalid waitlist status');
|
|
}
|
|
|
|
$setParts = [];
|
|
$setParts[] = "iw_status = '{$status}'";
|
|
|
|
if ($status === 'COMPLETED') {
|
|
// 완료 시 cancel 정보 초기화
|
|
$setParts[] = "iw_cancel_note = NULL";
|
|
$setParts[] = "iw_cancel_at = NULL";
|
|
$setParts[] = "iw_cancel_by = NULL";
|
|
}
|
|
|
|
if ($status === 'WAITING') {
|
|
// 취소로 되돌릴 때
|
|
$noteEsc = mysqli_real_escape_string($GLOBALS['conn'], $note ?? '');
|
|
$member = intval($member_uid ?? 0);
|
|
|
|
$setParts[] = "iw_cancel_note = '{$noteEsc}'";
|
|
$setParts[] = "iw_cancel_at = NOW()";
|
|
$setParts[] = "iw_cancel_by = '{$member}'";
|
|
}
|
|
|
|
$sql = "
|
|
UPDATE tbl_install_waitlist
|
|
SET " . implode(',', $setParts) . "
|
|
WHERE iw_uid = '{$wait_uid}'
|
|
LIMIT 1
|
|
";
|
|
|
|
if (!qry($sql)) {
|
|
throw new Exception('waitlist status update failed');
|
|
}
|
|
}
|
|
|
|
private function createNextScheduleIfNeeded(int $wait_uid, string $installDate, int $member_uid)
|
|
{
|
|
$qr = qry("SELECT * FROM tbl_install_waitlist WHERE iw_uid = '{$wait_uid}' LIMIT 1");
|
|
$wait = mysqli_fetch_assoc($qr);
|
|
if (!$wait) {
|
|
throw new Exception('waitlist not found');
|
|
}
|
|
|
|
if (intval($wait['iw_scheduled']) !== 1) return;
|
|
|
|
$cycleDays = intval($wait['iw_scheduled_cycle']);
|
|
if ($cycleDays <= 0) return;
|
|
|
|
if (empty($installDate)) {
|
|
throw new Exception('install date missing');
|
|
}
|
|
|
|
$nextDate = date('Y-m-d', strtotime($installDate . " +{$cycleDays} days"));
|
|
|
|
//
|
|
$sql = "
|
|
INSERT INTO tbl_install_waitlist (
|
|
iw_customer_uid,
|
|
iw_accountno,
|
|
iw_customer_name,
|
|
iw_phone,
|
|
iw_address,
|
|
iw_city,
|
|
iw_postal,
|
|
iw_requested_due_date,
|
|
iw_work_type,
|
|
iw_status,
|
|
iw_priority,
|
|
iw_created_by,
|
|
iw_scheduled,
|
|
iw_scheduled_cycle,
|
|
iw_request_by,
|
|
iw_request_note,
|
|
iw_cs_note,
|
|
iw_request_source
|
|
) VALUES (
|
|
'{$wait['iw_customer_uid']}',
|
|
'{$wait['iw_accountno']}',
|
|
'".mysqli_real_escape_string($GLOBALS['conn'], $wait['iw_customer_name'])."',
|
|
'".mysqli_real_escape_string($GLOBALS['conn'], $wait['iw_phone'])."',
|
|
'".mysqli_real_escape_string($GLOBALS['conn'], $wait['iw_address'])."',
|
|
'".mysqli_real_escape_string($GLOBALS['conn'], $wait['iw_city'])."',
|
|
'".mysqli_real_escape_string($GLOBALS['conn'], $wait['iw_postal'])."',
|
|
'{$nextDate}',
|
|
'".mysqli_real_escape_string($GLOBALS['conn'], $wait['iw_work_type'])."',
|
|
'WAITING',
|
|
'{$wait['iw_priority']}',
|
|
'{$wait['iw_created_by']}',
|
|
1,
|
|
'{$cycleDays}',
|
|
'{$wait['iw_request_by']}',
|
|
'".mysqli_real_escape_string($GLOBALS['conn'], (string)$wait['iw_request_note'])."',
|
|
'".mysqli_real_escape_string($GLOBALS['conn'], (string)$wait['iw_cs_note'])."',
|
|
'AUTO'
|
|
)
|
|
";
|
|
|
|
if (!qry($sql)) {
|
|
throw new Exception('auto reschedule insert failed');
|
|
}
|
|
|
|
// 새 wait uid
|
|
$new_wait_uid = mysqli_insert_id($GLOBALS['conn']);
|
|
if (!$new_wait_uid) {
|
|
throw new Exception('auto reschedule insert id missing');
|
|
}
|
|
|
|
// 컨테이너 복사
|
|
$this->copyWaitContainers($wait_uid, (int)$new_wait_uid);
|
|
}
|
|
|
|
private function copyWaitContainers(int $from_wait_uid, int $to_wait_uid): void
|
|
{
|
|
$sql = "
|
|
INSERT INTO tbl_install_waitlist_container (
|
|
iwc_wait_uid,
|
|
iwc_action,
|
|
iwc_type,
|
|
iwc_capacity,
|
|
iwc_is_used,
|
|
iwc_has_lock,
|
|
iwc_has_wheel,
|
|
iwc_has_woodframe,
|
|
iwc_target_cc_uid,
|
|
iwc_owner_type
|
|
)
|
|
SELECT
|
|
'{$to_wait_uid}' AS iwc_wait_uid,
|
|
iwc_action,
|
|
iwc_type,
|
|
iwc_capacity,
|
|
iwc_is_used,
|
|
iwc_has_lock,
|
|
iwc_has_wheel,
|
|
iwc_has_woodframe,
|
|
iwc_target_cc_uid,
|
|
iwc_owner_type
|
|
FROM tbl_install_waitlist_container
|
|
WHERE iwc_wait_uid = '{$from_wait_uid}'
|
|
";
|
|
|
|
if (!qry($sql)) {
|
|
throw new Exception('container copy insert failed');
|
|
}
|
|
}
|
|
|
|
private function buildDailyPayloadFromInstall(int $di_uid, int $oil_qty): array
|
|
{
|
|
$qr = qry("SELECT * FROM tbl_daily_install WHERE di_uid='{$di_uid}' LIMIT 1");
|
|
$di = mysqli_fetch_assoc($qr);
|
|
if (!$di) throw new Exception('install not found');
|
|
|
|
$orderdate = date('Ymd', strtotime($di['di_install_date']));
|
|
$now14 = date('YmdHis');
|
|
|
|
$qrCus = qry("SELECT * FROM tbl_customer WHERE c_uid='{$di['di_customer_uid']}' LIMIT 1");
|
|
$customer = mysqli_fetch_assoc($qrCus);
|
|
if (!$customer) throw new Exception('customer not found');
|
|
|
|
$days = 0;
|
|
if (!empty($customer['c_lastpickupdate'])) {
|
|
$last = strtotime(substr($customer['c_lastpickupdate'],0,8));
|
|
$today = strtotime($orderdate);
|
|
$days = max(0, floor(($today-$last)/86400));
|
|
}
|
|
|
|
$estquantity = max(
|
|
0,
|
|
($customer['c_fullquantity'] - $customer['c_fullquantitydaily'])
|
|
+ ($days * $customer['c_fullquantitydaily'])
|
|
);
|
|
|
|
return [
|
|
'd_orderdate' => $orderdate,
|
|
'd_accountno' => $di['di_accountno'],
|
|
'd_customeruid' => $di['di_customer_uid'],
|
|
// 'd_driveruid' => $di['di_driver_uid'],
|
|
'd_driveruid' => 43, // 현재 E.X 로 고정, hard coding
|
|
'd_name' => $di['di_customer_name'],
|
|
'd_paymenttype' => $customer['c_paymenttype'],
|
|
'd_cycle' => $customer['c_paymentcycle'],
|
|
'd_rate' => $customer['c_rate'],
|
|
'd_status' => 'F',
|
|
'd_visit' => 'Y',
|
|
'd_visitdate' => $now14,
|
|
'd_quantity' => $oil_qty,
|
|
'd_estquantity' => $estquantity,
|
|
'd_inputdate' => $now14,
|
|
'd_createddate' => $now14,
|
|
'd_createruid' => $_SESSION['ss_UID'] ?? ''
|
|
];
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function upload_after_photo() {
|
|
|
|
$di_uid = intval($_POST['di_uid'] ?? 0);
|
|
$member_uid = intval($_POST['member_uid'] ?? 0);
|
|
$note = trim($_POST['note'] ?? '');
|
|
|
|
$fail = function($stage, $msg, $extra = []) {
|
|
echo $this->json(array_merge([
|
|
'ok' => 0,
|
|
'stage' => $stage,
|
|
'msg' => $msg,
|
|
'db' => mysqli_error($GLOBALS['conn'])
|
|
], $extra));
|
|
exit;
|
|
};
|
|
|
|
if(!$di_uid || !$member_uid){
|
|
$fail('validate', 'invalid params');
|
|
}
|
|
|
|
// daily_install 확인 (customer_uid 가져오기)
|
|
$qr = qry("
|
|
SELECT di_customer_uid
|
|
FROM tbl_daily_install
|
|
WHERE di_uid = '{$di_uid}'
|
|
LIMIT 1
|
|
");
|
|
$di = mysqli_fetch_assoc($qr);
|
|
if(!$di){
|
|
$fail('select_di', 'daily_install not found');
|
|
}
|
|
|
|
if(!isset($_FILES['after_photo']) || $_FILES['after_photo']['error'] !== 0){
|
|
$fail('file', 'no file');
|
|
}
|
|
|
|
$customer_uid = intval($di['di_customer_uid']);
|
|
$file = $_FILES['after_photo'];
|
|
|
|
$ok = $this->save_customer_image_single(
|
|
$customer_uid,
|
|
$member_uid,
|
|
'install',
|
|
$di_uid, // i_sourceuid = di_uid
|
|
$note,
|
|
$file
|
|
);
|
|
|
|
if(!$ok){
|
|
$fail('save_image', 'upload failed');
|
|
}
|
|
|
|
echo $this->json(['ok'=>1]);
|
|
exit;
|
|
}
|
|
|
|
private function save_customer_image_single($i_customeruid, $i_memberuid, $i_type, $i_sourceuid, $i_note, $file){
|
|
|
|
$conn = $GLOBALS['conn'];
|
|
|
|
$i_customeruid = intval($i_customeruid);
|
|
$i_memberuid = intval($i_memberuid);
|
|
$i_sourceuid = intval($i_sourceuid);
|
|
|
|
$i_type = mysqli_real_escape_string($conn, $i_type);
|
|
$i_noteEsc = mysqli_real_escape_string($conn, trim($i_note));
|
|
$i_createddate = date("YmdHis");
|
|
|
|
// 확장자 체크(최소 보안)
|
|
$allowed = ['jpg','jpeg','png','webp'];
|
|
$ext = strtolower(pathinfo($file['name'] ?? '', PATHINFO_EXTENSION));
|
|
if(!$ext || !in_array($ext, $allowed)){
|
|
return false;
|
|
}
|
|
|
|
// 작업 단위 1장 유지: (customeruid + type + sourceuid)
|
|
$qry_update = "
|
|
UPDATE tbl_customer_image
|
|
SET i_status = 'I'
|
|
WHERE i_customeruid = '{$i_customeruid}'
|
|
AND i_type = '{$i_type}'
|
|
AND i_sourceuid = '{$i_sourceuid}'
|
|
AND i_status = 'A'
|
|
";
|
|
if(qry($qry_update) === false) return false;
|
|
|
|
// 저장 폴더
|
|
$upload_folder = getenv("DOCUMENT_ROOT")."/upload/customer_image/".$i_customeruid;
|
|
if(!is_dir($upload_folder)){
|
|
mkdir($upload_folder, 0777, true);
|
|
}
|
|
|
|
$newFileName = "IMG_".$i_customeruid."_".time().rand(1000,9999)."_0.".$ext;
|
|
$savePath = $upload_folder . "/" . $newFileName;
|
|
|
|
if(!move_uploaded_file($file['tmp_name'], $savePath)){
|
|
return false;
|
|
}
|
|
|
|
$dbFilePath = "/upload/customer_image/".$i_customeruid."/";
|
|
|
|
$sqlIns = "
|
|
INSERT INTO tbl_customer_image (
|
|
i_customeruid,
|
|
i_memberuid,
|
|
i_createdby,
|
|
i_createddate,
|
|
i_type,
|
|
i_filename,
|
|
i_filepath,
|
|
i_status,
|
|
i_note,
|
|
i_sourceuid
|
|
) VALUES (
|
|
'{$i_customeruid}',
|
|
'{$i_memberuid}',
|
|
'{$i_memberuid}',
|
|
'{$i_createddate}',
|
|
'{$i_type}',
|
|
'{$newFileName}',
|
|
'{$dbFilePath}',
|
|
'A',
|
|
'{$i_noteEsc}',
|
|
'{$i_sourceuid}'
|
|
)
|
|
";
|
|
|
|
return qry($sqlIns) !== false;
|
|
}
|
|
|
|
private function apply_container_changes_for_di($di_uid, $customer_uid){
|
|
|
|
$containers = [];
|
|
$rc = qry("SELECT * FROM tbl_daily_install_container WHERE dic_di_uid = '{$di_uid}'");
|
|
|
|
while($row = mysqli_fetch_assoc($rc)){
|
|
$containers[] = $row;
|
|
}
|
|
|
|
foreach($containers as $c){
|
|
|
|
$action = strtoupper($c['dic_action'] ?? '');
|
|
$type = mysqli_real_escape_string($GLOBALS['conn'], $c['dic_type'] ?? '');
|
|
|
|
if(is_null($c['dic_capacity'])){
|
|
$capacityCond = "IS NULL";
|
|
$capacityVal = "NULL";
|
|
}else{
|
|
$cap = intval($c['dic_capacity']);
|
|
$capacityCond = "= '{$cap}'";
|
|
$capacityVal = "'{$cap}'";
|
|
}
|
|
|
|
$owner_type = mysqli_real_escape_string($GLOBALS['conn'], $c['dic_owner_type'] ?? 'C');
|
|
$is_used = mysqli_real_escape_string($GLOBALS['conn'], $c['dic_is_used'] ?? 'N');
|
|
$has_lock = mysqli_real_escape_string($GLOBALS['conn'], $c['dic_has_lock'] ?? 'N');
|
|
$has_wheel = mysqli_real_escape_string($GLOBALS['conn'], $c['dic_has_wheel'] ?? 'N');
|
|
$has_wood = mysqli_real_escape_string($GLOBALS['conn'], $c['dic_has_woodframe'] ?? 'N');
|
|
|
|
// REMOVE
|
|
if($action === 'REMOVE'){
|
|
|
|
$removeNote = mysqli_real_escape_string(
|
|
$GLOBALS['conn'],
|
|
"Removed via DI#{$di_uid}"
|
|
);
|
|
|
|
qry("
|
|
UPDATE tbl_customer_container
|
|
SET cc_status='I',
|
|
cc_remove_note='{$removeNote}',
|
|
cc_remove_at=NOW(),
|
|
cc_remove_date=NOW(),
|
|
cc_modified_at=NOW()
|
|
WHERE cc_uid = (
|
|
SELECT cc_uid FROM (
|
|
SELECT cc_uid
|
|
FROM tbl_customer_container
|
|
WHERE cc_customer_uid='{$customer_uid}'
|
|
AND cc_status='A'
|
|
AND cc_type='{$type}'
|
|
AND (cc_capacity {$capacityCond})
|
|
ORDER BY IFNULL(cc_install_at,'1970-01-01'), cc_uid
|
|
LIMIT 1
|
|
) x
|
|
)
|
|
");
|
|
}
|
|
|
|
// INSTALL
|
|
else if($action === 'INSTALL'){
|
|
|
|
$nowYmdHis = date('YmdHis');
|
|
|
|
qry("
|
|
INSERT INTO tbl_customer_container (
|
|
cc_customer_uid,
|
|
cc_type, cc_capacity,
|
|
cc_owner_type,
|
|
cc_is_used, cc_has_lock, cc_has_wheel, cc_has_woodframe,
|
|
cc_status,
|
|
cc_install_note,
|
|
cc_install_at, cc_install_date,
|
|
cc_createddate, cc_updateddate,
|
|
cc_modified_at
|
|
) VALUES (
|
|
'{$customer_uid}',
|
|
'{$type}', {$capacityVal},
|
|
'{$owner_type}',
|
|
'{$is_used}', '{$has_lock}', '{$has_wheel}', '{$has_wood}',
|
|
'A',
|
|
'Installed via DI#{$di_uid}',
|
|
NOW(), NOW(),
|
|
'{$nowYmdHis}', '{$nowYmdHis}',
|
|
NOW()
|
|
)
|
|
");
|
|
}
|
|
}
|
|
}
|
|
|
|
private function reorder_daily_install_sequence($driver_uid, $install_date) {
|
|
|
|
$driver_uid = intval($driver_uid);
|
|
$install_date = mysqli_real_escape_string($GLOBALS['conn'], $install_date);
|
|
|
|
$seq = 1;
|
|
|
|
// ================================
|
|
// 완료된 것들 먼저 (P/M/X)
|
|
// ================================
|
|
$rsDone = qry("
|
|
SELECT di_uid
|
|
FROM tbl_daily_install
|
|
WHERE di_driver_uid = '{$driver_uid}'
|
|
AND di_install_date = '{$install_date}'
|
|
AND di_status <> 'A'
|
|
ORDER BY di_order_seq ASC
|
|
");
|
|
|
|
while($row = mysqli_fetch_assoc($rsDone)){
|
|
$uid = intval($row['di_uid']);
|
|
qry("
|
|
UPDATE tbl_daily_install
|
|
SET di_order_seq = '{$seq}'
|
|
WHERE di_uid = '{$uid}'
|
|
");
|
|
$seq++;
|
|
}
|
|
|
|
// ================================
|
|
// 그 다음 대기 상태 업데이트
|
|
// ================================
|
|
$rsActive = qry("
|
|
SELECT di_uid
|
|
FROM tbl_daily_install
|
|
WHERE di_driver_uid = '{$driver_uid}'
|
|
AND di_install_date = '{$install_date}'
|
|
AND di_status = 'A'
|
|
ORDER BY di_order_seq ASC
|
|
");
|
|
|
|
while($row = mysqli_fetch_assoc($rsActive)){
|
|
$uid = intval($row['di_uid']);
|
|
qry("
|
|
UPDATE tbl_daily_install
|
|
SET di_order_seq = '{$seq}'
|
|
WHERE di_uid = '{$uid}'
|
|
");
|
|
$seq++;
|
|
}
|
|
}
|
|
|
|
public function daily_install_reorder() {
|
|
|
|
$driver_uid = intval($_POST['driver_uid'] ?? 0);
|
|
$orderJson = $_POST['order_list'] ?? '';
|
|
|
|
$fail = function($stage, $msg, $extra = []) {
|
|
echo $this->json(array_merge([
|
|
'ok' => 0,
|
|
'stage' => $stage,
|
|
'msg' => $msg,
|
|
'db' => mysqli_error($GLOBALS['conn'])
|
|
], $extra));
|
|
exit;
|
|
};
|
|
|
|
if(!$driver_uid || !$orderJson){
|
|
$fail('validate', 'invalid params');
|
|
}
|
|
|
|
$orderList = json_decode($orderJson, true);
|
|
if(!is_array($orderList) || !count($orderList)){
|
|
$fail('decode', 'invalid order list');
|
|
}
|
|
|
|
// driver의 install_date는 하나라고 가정 (화면 기준)
|
|
$qr = qry("
|
|
SELECT di_install_date
|
|
FROM tbl_daily_install
|
|
WHERE di_driver_uid = '{$driver_uid}'
|
|
LIMIT 1
|
|
");
|
|
$row = mysqli_fetch_assoc($qr);
|
|
|
|
if(!$row){
|
|
$fail('select_date', 'no install data');
|
|
}
|
|
|
|
$install_date = $row['di_install_date'];
|
|
|
|
qry("START TRANSACTION");
|
|
|
|
foreach($orderList as $item){
|
|
|
|
$di_uid = intval($item['di_uid'] ?? 0);
|
|
$seq = intval($item['di_order_seq'] ?? 0);
|
|
|
|
if(!$di_uid || !$seq){
|
|
qry("ROLLBACK");
|
|
$fail('validate_row', 'invalid row');
|
|
}
|
|
|
|
$sql = "
|
|
UPDATE tbl_daily_install
|
|
SET di_order_seq = '{$seq}'
|
|
WHERE di_uid = '{$di_uid}'
|
|
AND di_driver_uid = '{$driver_uid}'
|
|
AND di_status = 'A'
|
|
LIMIT 1
|
|
";
|
|
|
|
if(!qry($sql)){
|
|
qry("ROLLBACK");
|
|
$fail('update', 'update failed', ['di_uid'=>$di_uid]);
|
|
}
|
|
}
|
|
|
|
// 마지막에 안전하게 정렬 보정
|
|
$this->reorder_daily_install_sequence($driver_uid, $install_date);
|
|
|
|
qry("COMMIT");
|
|
|
|
echo $this->json(['ok'=>1]);
|
|
exit;
|
|
}
|
|
}
|