
사용자는 엑셀 대량 주문 페이지를 통해 접근할 수 있다.
사용자는 주문서 다운로드 버튼을 클릭하면,
셀팜 측에서 제공하는 대량 주문 양식을 다운로드 받을 수 있다.
사용자는 주문서 업로드 버튼을 클릭하여 파일을 업로드 할 수 있다.
사용자가 외부 양식을 업로드하는 경우,
사용자에게 "셀팜측의 양식을 업로드 해주세요."하는 경고 메세지를 출력할 수 있다.
사용자의 엑셀파일의 모든 열을 유효성을 확인 한다.
모든 유효성 검사를 통과한 엑셀 파일만이 정상적으로 주문 접수가 될 수 있게 한다.
사용자의 파일을 5행부터 읽어 주문내역을 화면에 표시한다.
사용자가 주문하기 버튼을 누르면 주문내역에 사용자가 기입한 주문정보를 출력한다.
사용자 주문내역 검색필터를 통하여 검색에 따른 결과를 보여준다.
검색활성시 활성 조건은 주문처리 상태, 날짜, 상품명을 기준으로 하며
각 검색필터 별로 검색할 수 있게 한다.
사용자는 본인의 주문내역을 선택할 수 있다.
사용자는 주문내역을 선택적으로 다운로드 할 수 있다.
+) 추가한 부분
사용자가 엑셀 대량 주문 시 "남은 예치금 내역을 보여줬으면 좋겠다."는 의견을 반영하였고, 주문내역에서 엑셀 대량주문을 통해 주문한 것과 개별적으로 주문한 내역을 구분할 필요가 있었다.
사용자가 대량 주문할 excelfile을 업로드하면,
셀팜 측에서 재공하는 파일인지 아닌지 먼저 검사를 한다.
<?php
include_once('./_common.php');
if (!$is_member)
goto_url(G5_BBS_URL . "/login.php?url=" . urlencode(G5_SHOP_URL . "/bulk_order.php"));
$g5['title'] = '엑셀 대량 주문';
include_once('./_head.php');
?>
<?php
require './vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
set_time_limit(0);
ini_set('memory_limit', '50M');
$is_upload_file = (isset($_FILES['orderFile']['tmp_name']) && $_FILES['orderFile']['tmp_name']) ? 1 : 0;
if(!$is_upload_file){
alert("액셀 파일을 업로드 해주세요!");
}else{
$file = $_FILES['orderFile']['tmp_name'];
try {
$spreadsheet = IOFactory::load($file);
} catch (\Exception $e) {
die("Could not read file: " . $e->getMessage());
}
$worksheet = $spreadsheet->getActiveSheet();
$cellValue = $worksheet->getCell('A1')->getValue(1);
if ($cellValue !== '대량 주문양식-test_sample.xlsx') {
alert("잘못된 양식입니다. 셀팜 양식을 업로드 해주세요.");
} else {
//echo "셀팜양식임을 확인함<br>";
셀팜측에서 제공하는 양식이 맞다면 엑셀파일의 모든 열을 유효성 검사를 시작한다.
else {
//echo "셀팜양식임을 확인함<br>";
$highestRow = $worksheet->getHighestRow();
$highestColumn = $worksheet->getHighestColumn();
$start_rows=5;//5행 부터 읽기 시작
// $total_price=0;
for ($i = $highestRow; $i >= $start_rows; $i--){
$j=0;
$rowData = $worksheet->rangeToArray('A' . $i . ':' . $highestColumn . $i, NULL, TRUE, FALSE);
$order = (string) $rowData[0][$j++];
if($order){
$order = explode(',', $order);
$od_name = $rowData[0][1];//주문자 이름
$re_name = $rowData[0][7]; //수취인 이름
$od_phone_num = $rowData[0][2];//주문자 연락처
$re_phone_num = $rowData[0][8];//수취인 연락처
$postalCode = $rowData[0][10];//우편번호
$od_address1 = $rowData[0][11];//기본주소
$od_address2 = $rowData[0][12];//상세주소
$option = $rowData[0][4]; //옵션명
$product_code = $rowData[0][3];//상품 코드
$product_num = $rowData[0][5];//상품 수량
$product_price = $rowData[0][6]; //상품 금액
$msg = $rowData[0][9];//배송 메세지
$order_price = 0;// 각 행의 주문 금액
$total_price = 0;//총 주문 금액
if (empty($od_name))
alert('주문자 필드는 필수 입력 필드 입니다! 주문자명이 없는 행이 있는지 확인해 주세요!');
if (empty($re_name))
alert('수취인 필드는 필수 입력 필드 입니다! 수취인 명이 없는 행이 있는지 확인해 주세요!');
if (!is_numeric($od_phone_num))
alert('첨부하신 엑셀 파일의 ' . $i . '번째 줄의 주문내역에 문제 (주문자 연락처 - 문자포함)가 있어서 대량 주문이 불가능 합니다.');
if (!is_numeric($re_phone_num))
alert('첨부하신 엑셀 파일의 ' . $i . '번째 줄의 주문내역에 문제 (수취인 연락처 - 문자포함)가 있어서 대량 주문이 불가능 합니다.');
if (!is_numeric($postalCode) || strpos($postalCode, ',')){
echo "우편 번호 : $postalCode<br>";
alert('첨부하신 엑셀 파일 ' . $i . '번째 줄의 주문내역에 문제(우편번호 - 문자포함)가 있어서 대량 주문이 불가능 합니다.');
}if (strlen($postalCode) != 5)
alert('첨부하신 엑셀 파일 ' . $i . '번째 줄의 주문내역에 문제(우편번호 - 구우편번호 입력)가 있어서 대량 주문이 불가능 합니다.');
if (empty($od_address1) or empty($od_address2))
alert('기본주소와 상세주소는 필수 입력 필드 입니다! 올바른 주소를 입력해주세요.');
if (empty($product_code)) {
alert('첨부하신 엑셀파일의 ' . $i . '번째 줄의 상품번호가 누락되었습니다.');
} elseif (!is_numeric($product_num) || !is_numeric($product_price)) {
alert('첨부하신 엑셀파일의 ' . $i . '번째 줄의 수량과 주문금액을 0을 제외한 숫자로만 입력해 주세요.');
} else
{
$sql = " select it_id, it_name, it_price from {$g5['g5_shop_item_table']} where it_id ='{$product_code}' ";
$row = sql_fetch($sql);
if (!$row){
alert('유효한 상품코드를 입력해주세요.');
}
elseif($product_code=='1691051137'){
alert('첨부하신 엑셀 파일 ' . $i . '번째 줄의 상품 번호에 해당 상품이 예치금이여서 대량주문이 불가능합니다. 예치금이 부족하신 경우 예치금 충전후 이용해 주세요.');
}
elseif($product_num=='0'){
alert('첨부하신 엑셀 파일 ' . $i . '번째 줄의 수량이 0이여서 대량주문이 불가능합니다.');
}
elseif ($row['it_price'] != $product_price ){
alert('첨부하신 엑셀 파일 ' . $i . '번째 줄의 상품금액이 일치 하지 않습니다.');
}else
{
if ($product_num!='0'){//Loop 1회
$order_price = $product_num * $product_price;
$one_total_price += $order_price;
//echo"for: $one_total_price<br>";
}
if ($one_total_price > $member['mb_point']){
alert("예치금이 부족하여 대량 주문에 실패하였습니다. 예치금 충전후 다시 시도하여 주세요.");
} else{//validate pass OK
processRowData($i, $highestColumn, $worksheet, $start_rows, $member, $default);
//입금 처리
insert_point($member['mb_id'], (-1) * $od_receipt_point, "주문번호 $od_id 결제");
$new_balance = $member['mb_point'] - $one_total_price;//예치금 잔액
$sql = "UPDATE {$g5['member_table']} SET mb_point = $new_balance WHERE mb_id = '{$member['mb_id']}'";
$result = sql_query($sql, false);
}
function processRowData : 유효성 검사를 통과한 엑셀 파일의 행을 읽는 기능을 수행한다.
엑셀파일의 모든 행을 읽어들였다면, db에 저장을 하는 insertToCart를 호출한다.
function processRowData($i, $highestColumn, $worksheet, $start_rows, $member, $default) {
global $g5, $data, $all_data;
$rowData = $worksheet->rangeToArray('A' . $i . ':' . $highestColumn . $i, NULL, TRUE, FALSE);
$product_code = $rowData[0][3];
$product_num = $rowData[0][5];
$j = 0;
if (trim($product_code) == '') {
return;
}
$order = (string) $rowData[0][$j++];
if($order){
$order = explode(',', $order);
$od_b_zip = $rowData[0][10];
$od_id = get_uniqid();
// $order_price = 0;
$product_code = $rowData[0][3];
$sql = " select it_id, it_name, it_sc_type, it_sc_method, it_sc_price, it_sc_minimum, it_sc_qty, it_price, it_notax, it_supply_point, it_point_type from {$g5['g5_shop_item_table']} where it_id ='{$product_code}' ";
$row = sql_fetch($sql);
$io_id = '';
$io_type = 0;
$point = 0;
if ($config['cf_use_point']) {
if ($io_type == 0) {
$point = get_item_point($row, '');
} else {
$point = $row['it_supply_point'];
}
if ($point < 0)
$point = 0;
}
$ct_option = $row['it_name'];
$data = array(
'index' => $i,
'product_code' => $rowData[0][3],
'it_name' => $row['it_name'],
'ct_option' => $rowData[0][4],
'it_cnt'=>$rowData[0][5],
'receiver'=>$rowData[0][7],
're_tel'=>$rowData[0][2],
'de_msg'=>$rowData[0][9],
'postalCode'=>$rowData[0][10],
'address1'=>$rowData[0][11],
'address2'=>$rowData[0][12]
);
$all_data[] = $data;
$ct_send_cost = 0;
if ($row['it_sc_type'] == 1) {
$ct_send_cost = 2; // 무료
} else if ($row['it_sc_type'] > 1 && $row['it_sc_method'] == 1) {
$ct_send_cost = 1; // 착불
}
insertToCart($product_code, $rowData, $member, $row, $product_num, $it_qty, $point, $ct_option, $io_id, $io_type, $ct_send_cost, $default);
}
}
?>
function insertToCart : 사용자의 주문을 장바구니 table에 저장한다.
function insertToCart($product_code, $rowData, $member, $row, $product_num, $it_qty, $point, $ct_option, $io_id, $io_type, $ct_send_cost, $default) {
global $g5;
$ba_id = 'ba_'.get_uniqid();
$od_id = get_uniqid();
$remote_addr = get_real_client_ip();
$sql = " insert {$g5['g5_shop_cart_table']}
set od_id = '$od_id',
ba_id = '$ba_id',
mb_id = '{$member['mb_id']}',
it_id = '$product_code',
it_name = '{$row['it_name']}',
it_sc_type = '{$row['it_sc_type']}',
it_sc_method = '{$row['it_sc_method']}',
it_sc_price = '{$row['it_sc_price']}',
it_sc_minimum = '{$row['it_sc_minimum']}',
it_sc_qty = '{$row['it_sc_qty']}',
ct_status = '입금',
ct_price = '{$row['it_price']}',
ct_point = '$point',
ct_point_use = '0',
ct_stock_use = '0',
ct_option = '$ct_option',
ct_qty = '$product_num',
ct_notax = '{$row['it_notax']}',
io_id = '$io_id',
io_type = '$io_type',
io_price = '0',
ct_time = '" . G5_TIME_YMDHIS . "',
ct_ip = '$remote_addr',
ct_send_cost = '$ct_send_cost',
ct_direct = '0',
ct_select = '1',
ct_select_time = '" . G5_TIME_YMDHIS . "'
";
$result = sql_query($sql, false);
$order_price = $order_price + ($row['it_price'] * $it_qty); // 주문금액
$send_cost = get_sendcost($od_id);
insertToOrder($product_code, $rowData, $member, $row, $product_num, $it_qty, $point, $ct_option, $io_id, $io_type, $ct_send_cost, $order_price, $send_cost, $ba_id, $od_id, $default);
}
function insertToOrder : 사용자의 주문을 장바구니 table에 저장한다.
insertToOrder table에 data를 저장해야 사용자의 주문내역 page에서 조회할 수 있기 때문이다.
따라서 나는 사용자가 개별적으로 주문하는 것과 대량주문을 통해 주문한 내역을 구분할 필요가 있었다.
따라서 table에 is_bulk 라는 column을 새로 생성한후에 대량주문을 통해 저장되는 것만 1로 설정하였으며, 주문내역 page에 엑셀 대량주문 보기 check-box를 생성하였다.
<?php
function insertToOrder($product_code, $rowData, $member, $row, $product_num, $it_qty, $point, $ct_option, $io_id, $io_type, $ct_send_cost, $order_price, $send_cost, $ba_id, $od_id, $default){
//var_dump($rowData);
global $g5;
$od_b_zip = preg_replace('/[^0-9]/', '', $rowData[0][10]);
$od_b_zip1 = substr($od_b_zip, 0, 3);
$od_b_zip2 = substr($od_b_zip, 3);
$zipcode = $od_b_zip;
$sql = " select sc_id, sc_price from {$g5['g5_shop_sendcost_table']} where sc_zip1 <= '$zipcode' and sc_zip2 >= '$zipcode' ";
$tmp = sql_fetch($sql);
if (!(isset($tmp['sc_id']) && $tmp['sc_id']))
$send_cost2 = 0;
else
$send_cost2 = (int) $tmp['sc_price'];
$j = 1; // 주문 데이터
$od_name = (string) $rowData[0][$j++];//주문자
$od_tel = (string) $rowData[0][$j++];//주문자 연락처
$od_hp = $od_tel;
$j+=2;//상품 번호 열, 옵션명은 건너뜀
$od_cart_count = (string) $rowData[0][$j++];//수량
$od_cart_price = (int) $rowData[0][$j++];//주문금액
$od_b_name = (string) $rowData[0][$j++];//수취인
$od_b_tel = (string) $rowData[0][$j++];//수취인 연락처
$od_b_hp = $od_b_tel;//수취인 연락처
$od_b_addr3 = '';
$od_b_addr_jibeon = 'R';
$od_memo = (string) $rowData[0][$j++];//배송 메세지
$od_b_zip = (string) $rowData[0][$j++];//우편번호
$od_b_zip1 = substr($od_b_zip, 0, 3);
$od_b_zip2 = substr($od_b_zip, 3);
$od_b_addr1 = (string) $rowData[0][$j++];//기본 주소
$od_b_addr2 = (string) $rowData[0][$j++];//상세 주소
$od_unique_id = (string) $rowData[0][$j++];
$od_cart_price = $od_cart_price * $od_cart_count; // 총 상품가액
$od_receipt_point = $order_price + $send_cost; // 입금된 포인트
$is_bulk = (int)1;//대량주문인지 단순 개별 주문건인지 구분하기 위한 토글
if ($default['de_bank_use']) {
$str = explode("\n", trim($default['de_bank_account']));
$bank_account = $str[0];
}
$sql = " insert {$g5['g5_shop_order_table']}
set od_id = '$od_id',
ba_id = '$ba_id',
mb_id = '{$member['mb_id']}',
od_pwd = '{$member['mb_password']}',
od_name = '{$member['mb_name']}',
od_email = '{$member['mb_email']}',
od_tel = '{$member['mb_tel']}',
od_hp = '{$member['mb_hp']}',
od_zip1 = '{$member['mb_zip1']}',
od_zip2 = '{$member['mb_zip2']}',
od_addr1 = '{$member['mb_addr1']}',
od_addr2 = '{$member['mb_addr2']}',
od_addr3 = '{$member['mb_addr3']}',
od_addr_jibeon = '{$member['mb_addr_jibeon']}',
od_b_name = '$od_b_name',
od_b_tel = '$od_b_tel',
od_b_hp = '$od_b_hp',
od_b_zip1 = '$od_b_zip1',
od_b_zip2 = '$od_b_zip2',
od_b_addr1 = '$od_b_addr1',
od_b_addr2 = '$od_b_addr2',
od_b_addr3 = '$od_b_addr3',
od_b_addr_jibeon = '$od_b_addr_jibeon',
od_deposit_name = '{$member['mb_name']}',
od_memo = '$od_memo',
od_cart_count = '$od_cart_count',
od_cart_price = '$od_cart_price',
od_send_cost = '$send_cost',
od_send_cost2 = '$send_cost2',
od_receipt_price = '0',
od_receipt_point = '$od_receipt_point',
od_bank_account = '$bank_account',
od_receipt_time = '".G5_TIME_YMDHIS."',
od_misu = '0',
od_pg = '{$default['de_pg_service']}',
od_escrow = '0',
od_tax_flag = '{$default['de_tax_flag_use']}',
od_tax_mny = '0',
od_vat_mny = '0',
od_free_mny = '0',
od_status = '입금',
od_shop_memo = '',
od_time = '" . G5_TIME_YMDHIS . "',
od_ip = '$REMOTE_ADDR',
od_settle_case = '예치금 사용',
od_test = '{$default['de_card_test']}',
od_unique_id = '$od_unique_id',
is_bulk = '$is_bulk'
";
$result = sql_query($sql, false);
//echo"rexs: $result<br>";
// 정말로 insert 가 되었는지 한번더 체크한다.
$exists_sql = " select od_id, od_tno, od_ip from {$g5['g5_shop_order_table']} where od_id = '{$od_id}' ";
$exists_order = sql_fetch($exists_sql);
if (!$result || !(isset($exists_order['od_id']) && $od_id && $exists_order['od_id'] === $od_id)) {
$sql = " delete from {$g5['g5_shop_cart_table']} where od_id = '{$od_id}' ";
sql_query($sql, false);
$sql = " delete from {$g5['g5_shop_order_table']} where od_id = '{$od_id}' ";
sql_query($sql, false);
alert('죄송합니다 일시적인 오류로 인하여 주문이 제대로 이루어지지 않았습니다.\n\n첨부하신 엑셀 파일 ' . $i . '번째 줄의 주문내역부터 다시 진행해 주시기 바랍니다.');
}
}
<div class="tbl_head03 tbl_wrap" style="cursor: pointer;">
<form action="download.php" method="post" id="excelDownloadForm-simpleOrderList" >
<button type="submit" class=" download_btn"><img class='order_inquiry_btn_img'src='./../../img/excelImg.png'/>DownLoad</button>
</form>
<div><!--주문내역조회-->
<table><!--주문내역 table-->
<thead>
<tr>
<th scope="col" class="all_chk chk_box">
<input type="checkbox" id="chkall" onclick="if (this.checked) all_checked(true); else all_checked(false);" class="simple-chk1">
<label for="chkall">
<span></span>
<b class="sound_only">현재 페이지 전체선택
</label>
</th>
<th scope="col">발주 번호</th>
<th scope="col">주문서 번호</th>
<th scope="col">주문 일시</th>
<th scope="col" class="none500">상품명</th>
<th scope="col" class="none500">상품수</th>
<th scope="col" class="none600">주문 금액</th>
<th scope="col">배송 상태</th>
<th scope="col">송장 번호</th>
<th scope="col">네이버 / 쿠팡 번호</th>
</tr>
</thead>
<tbody>
<?php
$order_start_date = isset($_POST['order_start_date']) ? $_POST['order_start_date'] : '';
$order_end_date = isset($_POST['order_end_date']) ? $_POST['order_end_date'] : '';
$word_search = isset($_POST['word_search']) ? $_POST['word_search'] : '';
$invoice_search = isset($_POST['invoice_search']) ? $_POST['invoice_search'] : '';
$bulk_search = isset($_POST['bulk_order']) && $_POST['bulk_order'] == 1 ? 1 : 0; //엑셀 대량 주문 보기 추가
$sql_common = "from {$g5['g5_shop_order_table']} o
join {$g5['g5_shop_cart_table']} c on o.od_id = c.od_id
where o.mb_id = '{$member['mb_id']}'";
if ($order_start_date && $order_end_date) { //날짜 범위 주문내역 필터링
$sql_common .= " and o.od_time between '{$order_start_date} 00:00:00' and '{$order_end_date} 23:59:59'";
}
if ($word_search) {//검색어 기반 주문내역 필터링
$sql_common .= " and (o.od_id like '%{$word_search}%' or c.it_name like '%{$word_search}%')";
}
if ($invoice_search) {//송장번호 주문내역 필터링
$sql_common .= " and o.od_invoice = '{$invoice_search}'";
}
if($bulk_search){//excel 대량주문 필터링
$sql_common .=" and o.is_bulk = '{$bulk_search}'";
}
$sql= "select c.ba_id, o.od_id, o.od_time, c.it_name, o.od_cart_count,
o.od_cart_price + o.od_send_cost + o.od_send_cost2 as total_cost,
o.od_status, o.od_invoice, o.od_naver_coupang_number
$sql_common order by o.od_id desc $limit";
코드를 입력하세요
<최종구현>
