feat: 워크스페이스 탭 자동복원 + 주문 입금확인 토글 + 메뉴 개명(전화접수→주문접수)
종량제3 세션 작업. - 워크스페이스 탭 계정별 저장·자동복원(member_workspace_tabs 자동생성, pref/workspace-tabs) - 주문접수 관리 입금확인(so_paid) 수동 토글(phoneOrderMarkPaid, order/phone/manage/paid) - 메뉴 '전화 접수 관리' → '주문접수관리' 개명(피드백 #35) + 시드/개명 SQL Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -274,6 +274,70 @@ SQL);
|
||||
return $this->response->setJSON(['ok' => true, 'csrf' => csrf_hash()]);
|
||||
}
|
||||
|
||||
/** member_workspace_tabs 테이블 보장(없으면 생성) */
|
||||
private function ensureWorkspaceTabsTable(\CodeIgniter\Database\BaseConnection $db): void
|
||||
{
|
||||
if ($db->tableExists('member_workspace_tabs')) {
|
||||
return;
|
||||
}
|
||||
$db->query(<<<'SQL'
|
||||
CREATE TABLE IF NOT EXISTS `member_workspace_tabs` (
|
||||
`mwt_mb_idx` INT UNSIGNED NOT NULL,
|
||||
`mwt_state` MEDIUMTEXT NULL,
|
||||
`mwt_updated` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`mwt_mb_idx`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
SQL);
|
||||
}
|
||||
|
||||
/** 계정별 워크스페이스 탭 상태 조회(자동 복원용). 없으면 'null'. */
|
||||
public function loadWorkspaceTabsState(int $mbIdx): string
|
||||
{
|
||||
if ($mbIdx <= 0) {
|
||||
return 'null';
|
||||
}
|
||||
$db = \Config\Database::connect();
|
||||
if (! $db->tableExists('member_workspace_tabs')) {
|
||||
return 'null';
|
||||
}
|
||||
$row = $db->table('member_workspace_tabs')->select('mwt_state')->where('mwt_mb_idx', $mbIdx)->get()->getRowArray();
|
||||
$s = (string) ($row['mwt_state'] ?? '');
|
||||
return $s !== '' ? $s : 'null';
|
||||
}
|
||||
|
||||
/** 계정별 워크스페이스 탭 상태 저장 (자동 복원) */
|
||||
public function saveWorkspaceTabs(): ResponseInterface
|
||||
{
|
||||
$mbIdx = (int) (session()->get('mb_idx') ?? 0);
|
||||
if ($mbIdx <= 0) {
|
||||
return $this->response->setJSON(['ok' => false, 'csrf' => csrf_hash()]);
|
||||
}
|
||||
$state = (string) ($this->request->getPost('state') ?? '');
|
||||
// 크기 제한 + JSON 유효성
|
||||
if (strlen($state) > 30000) {
|
||||
return $this->response->setJSON(['ok' => false, 'csrf' => csrf_hash()]);
|
||||
}
|
||||
if ($state !== '') {
|
||||
json_decode($state);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
return $this->response->setJSON(['ok' => false, 'csrf' => csrf_hash()]);
|
||||
}
|
||||
}
|
||||
|
||||
$db = \Config\Database::connect();
|
||||
$this->ensureWorkspaceTabsTable($db);
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$exists = $db->table('member_workspace_tabs')->where('mwt_mb_idx', $mbIdx)->countAllResults();
|
||||
if ($exists > 0) {
|
||||
$db->table('member_workspace_tabs')->where('mwt_mb_idx', $mbIdx)
|
||||
->update(['mwt_state' => $state, 'mwt_updated' => $now]);
|
||||
} else {
|
||||
$db->table('member_workspace_tabs')->insert(['mwt_mb_idx' => $mbIdx, 'mwt_state' => $state, 'mwt_updated' => $now]);
|
||||
}
|
||||
|
||||
return $this->response->setJSON(['ok' => true, 'csrf' => csrf_hash()]);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// 기본정보관리 (단가·포장 단위 진입 허브)
|
||||
// ──────────────────────────────────────────────
|
||||
@@ -7896,6 +7960,37 @@ SQL;
|
||||
return redirect()->to(site_url('bag/order/phone/manage'))->with('success', '주문 수정 저장이 완료되었습니다.');
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문접수 관리 — 입금확인(so_paid) 수동 토글(JSON 응답).
|
||||
* 입금확인이 완료되어야 포장(스캔)이 가능하다.
|
||||
*/
|
||||
public function phoneOrderMarkPaid()
|
||||
{
|
||||
$lgIdx = $this->lgIdx();
|
||||
if (! $lgIdx) {
|
||||
return $this->response->setJSON(['ok' => false, 'message' => '지자체를 선택해 주세요.', 'csrf' => csrf_hash()]);
|
||||
}
|
||||
|
||||
$soIdx = (int) ($this->request->getPost('so_idx') ?? 0);
|
||||
$paid = ((int) ($this->request->getPost('paid') ?? 0)) === 1 ? 1 : 0;
|
||||
if ($soIdx <= 0) {
|
||||
return $this->response->setJSON(['ok' => false, 'message' => '주문 값이 올바르지 않습니다.', 'csrf' => csrf_hash()]);
|
||||
}
|
||||
|
||||
$orderModel = model(ShopOrderModel::class);
|
||||
$order = $orderModel->where('so_idx', $soIdx)->where('so_lg_idx', $lgIdx)->first();
|
||||
if (! $order) {
|
||||
return $this->response->setJSON(['ok' => false, 'message' => '선택한 주문을 찾을 수 없습니다.', 'csrf' => csrf_hash()]);
|
||||
}
|
||||
if ((string) ($order->so_status ?? '') === 'cancelled') {
|
||||
return $this->response->setJSON(['ok' => false, 'message' => '취소된 주문은 입금상태를 변경할 수 없습니다.', 'csrf' => csrf_hash()]);
|
||||
}
|
||||
|
||||
$orderModel->update($soIdx, ['so_paid' => $paid]);
|
||||
|
||||
return $this->response->setJSON(['ok' => true, 'so_idx' => $soIdx, 'paid' => $paid, 'csrf' => csrf_hash()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 전화접수 관리 — 봉투코드 스캔으로 즉시 판매·포장 처리(JSON 응답).
|
||||
* 선택된 주문의 판매소로 판매 기록(bag_sale) + 재고 차감 + 팩코드 sold 전환 +
|
||||
@@ -7921,6 +8016,11 @@ SQL;
|
||||
return $this->response->setJSON(['ok' => false, 'message' => '선택한 주문을 사용할 수 없습니다.', 'csrf' => csrf_hash()]);
|
||||
}
|
||||
|
||||
// 입금확인(so_paid=1)이 안 된 주문은 포장(판매) 스캔 불가.
|
||||
if ((int) ($order->so_paid ?? 0) !== 1) {
|
||||
return $this->response->setJSON(['ok' => false, 'message' => '입금확인이 완료되지 않은 주문입니다. 입금확인 후 포장하세요.', 'csrf' => csrf_hash()]);
|
||||
}
|
||||
|
||||
$scan = $this->resolveDesignatedSaleBarcode($lgIdx, $barcode);
|
||||
if (! ($scan['ok'] ?? false)) {
|
||||
return $this->response->setJSON(array_merge($scan, ['csrf' => csrf_hash()]));
|
||||
|
||||
@@ -44,7 +44,11 @@ class Home extends BaseController
|
||||
}
|
||||
helper('admin');
|
||||
|
||||
return view('bag/layout/workspace');
|
||||
// 계정별 저장된 탭 상태(자동 복원). 없으면 'null'.
|
||||
$savedWorkspaceJson = (new \App\Controllers\Bag())
|
||||
->loadWorkspaceTabsState((int) (session()->get('mb_idx') ?? 0));
|
||||
|
||||
return view('bag/layout/workspace', ['savedWorkspaceJson' => $savedWorkspaceJson]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user