(경동기업, 주일기업)
난 한국사람이고, 한국어를 제일 잘한다. 위의 두개의 회사의 업무를 처리하는 프로그램을 개발하고 있다.
이제부터 코드를 만들거나 수정하는 일을 할 것이다.
웹사이트를 개발하고 관리하고 있다.
mysql, php, javascript로 대부분을 만들었다.
오류에 대한 언급을 하면, 그 해당오류에 대한 코드만 보여주면 좋겠다.
이제부터 코드에 관련된 내용을 물어볼 것이니, 최선을 다해 답변해줘.
모든 script에 대한 선언은 이미 되어 있는 상태다.
예를 들어 부트스트랩, 제이쿼리 등 전체 코드에 필요한 CDN 선언은 load_header.php 파일에 선언되어있다.
발주부터 출하, 재고관리, 인사관리 등등 전산시스템을 구축하고 있다.
회계부분도 매출, 출고통계, 로트번호관리 등 여러가지 종합적인 프로그램을 진행중에 있다.
지난 6개월간의 GPT와 협업해서 많은 코드를 만들었다. 하지만, 추가적인 요구사항들이 있어서 계속 수정할 것이다.
이제부터 이 개발과 관련된 코드에 대해 물어볼 것이다.
난 GPT의 모든 정보를 신뢰한다. 고마워. GPT 선생님! 추가적인 질문을 시작한다.
오류에 대한 언급을 하면, 그 해당오류에 대한 코드만 보여주면 좋겠다.
이제부터 코드에 관련된 내용을 물어볼 것이니, 최선을 다해 답변해줘.
이제부터 내가 질문하는 것에는 전체코드 생성이라는 말이 없으면 부분적으로 내가 요청한 부분만 대답해줘. 알겠지?
08/01 질문내용
위의 파일은 statistics.php이다. 이 코드에는 스크린, 스라트의 제조통계를 화면에 보여주는 것인데,
내가 만들고 싶은 것은 두개의 합산된 것도 유지하면서,
col-sm-4을 활용해서 첫번째 col-sm-6에는 스크린의 차트가 보이고
옆의 col-sm-4에는 스라트
그리고 마지막 col-sm-4에는 두개의 합친 지금의 코드를 보여주는 코드로 수정하고자 한다.
가독성을 높이고, 경영자에게 더 좋은 정보를 제공하기 위해서이다.
아래의 코드로 충분히 이렇게 수정가능한 것 같다. 코드를 만들고 오류가 없지는 체크까지 부탁한다.
chandj의 DB 내용중 output 테이블은 아래의 형태를 갖고 있다.
num: 고유 번호
con_num: 공사 번호
is_deleted: 삭제 여부
outdate: 출고일
indate: 접수일
outworkplace: 출고 작업장
orderman: 발주자
outputplace: 수신처 주소
receiver: 수신자
phone: 연락처
comment: 비고
file_name_0 ~ file_name_4: 파일명
file_copied_0 ~ file_copied_4: 파일 경로
root: 회사 구분
steel: 절곡 발주 여부
motor: 모터 발주 여부
delivery: 배송 방식
regist_state: 등록 상태
bend_state: 절곡 상태
motor_state: 모터 상태
searchtag: 검색 태그
update_log: 업데이트 로그
screen: 스크린 정보
screen_state: 스크린 상태
screen_su: 스크린 수량
screen_m2: 스크린 면적 (m²)
screenlist: 스크린 목록
slatlist: 슬랫 목록
slat: 슬랫 정보
slat_state: 슬랫 상태
slat_su: 슬랫 수량
slat_m2: 슬랫 면적 (m²)
updatecomment: 수정 사항 기록
이 테이블의 구조를 이해할 수 있겠니? 각 컬럼의 역할도 마찬가지로 기억해줘.
이 모든 내용을 output 테이블이라고 칭하고 싶다.
fetch_deadlineDate.php 내용은 아래와 같다.
query("SELECT pjname, deadlineDate, secondord, deliverymethod, num, outputDate, status, hallDoorList, carDoorList, carWallList, etcList
FROM " . $DB . ".order
WHERE is_deleted IS NULL
AND MONTH(deadlineDate) = $month
AND YEAR(deadlineDate) = $year");
while($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
array_push($data_order, $row);
}
$data_order = array(
"data_order" => $data_order,
);
echo(json_encode($data_order, JSON_UNESCAPED_UNICODE));
} catch (PDOException $Exception) {
print "오류: ".$Exception->getMessage();
}
?>
fetch_outputDate.php 내용은 아래와 같다.
query("SELECT pjname, deadlineDate, secondord, deliverymethod, num, outputDate, status, hallDoorList, carDoorList, carWallList, etcList
FROM " . $DB . ".order
WHERE is_deleted IS NULL
AND MONTH(deadlineDate) = $month
AND YEAR(deadlineDate) = $year");
while($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
array_push($data_order, $row);
}
$data_order = array(
"data_order" => $data_order,
);
echo(json_encode($data_order, JSON_UNESCAPED_UNICODE));
} catch (PDOException $Exception) {
print "오류: ".$Exception->getMessage();
}
?>
위의 코드에는 공통사항이 많다. 내가 언급한 output 테이블의 요소들로 바꾸고 두개의 파일을 하나의 파일로 만들고 전달하는 인자에 따라 처리하면 될 것 같다.
fetch_date.php 파일로 통합하고 output테이블의 컬럼요소에 맞게 수정해줘.
아래의 파일은 month_schedule.php 파일인데, 한산엘테크 웹사이트에서 가져온 코드이다.
output 테이블에 맞게 모든 것을 수정해야 하는데,
방금 만든 fetch_date는 여기서 두개의 파일호출에 적용하면 된다.
스크린의 면적을 누적하고, 스라트의 면적을 누적하는 코드가 있어야 한다. 이미 정의는 되어있다.
################################## 주일기업
(주일기업)
난 한국사람이고, 한국어를 제일 잘한다. 위의 두개의 회사의 업무를 처리하는 프로그램을 개발하고 있다.
이제부터 코드를 만들거나 수정하는 일을 할 것이다.
웹사이트를 개발하고 관리하고 있다.
mysql, php, javascript로 대부분을 만들었다.
오류에 대한 언급을 하면, 그 해당오류에 대한 코드만 보여주면 좋겠다.
이제부터 코드에 관련된 내용을 물어볼 것이니, 최선을 다해 답변해줘.
모든 script에 대한 선언은 이미 되어 있는 상태다.
예를 들어 부트스트랩, 제이쿼리 등 전체 코드에 필요한 CDN 선언은 load_header.php 파일에 선언되어있다.
발주부터 출하, 재고관리, 인사관리 등등 전산시스템을 구축하고 있다.
회계부분도 매출, 출고통계, 로트번호관리 등 여러가지 종합적인 프로그램을 진행중에 있다.
지난 6개월간의 GPT와 협업해서 많은 코드를 만들었다. 하지만, 추가적인 요구사항들이 있어서 계속 수정할 것이다.
이제부터 이 개발과 관련된 코드에 대해 물어볼 것이다.
난 GPT의 모든 정보를 신뢰한다. 고마워. GPT 선생님! 추가적인 질문을 시작한다.
오류에 대한 언급을 하면, 그 해당오류에 대한 코드만 보여주면 좋겠다.
이제부터 코드에 관련된 내용을 물어볼 것이니, 최선을 다해 답변해줘.
이제부터 내가 질문하는 것에는 전체코드 생성이라는 말이 없으면 부분적으로 내가 요청한 부분만 대답해줘. 알겠지?
공사수주 리스트의 자료를 수정하려고 한다.
work 테이블의 컬럼은 아래와 같이 구성되어있다.
기본 정보:
num: 기본 키로, 자동 증가하는 정수값입니다.
is_deleted: 삭제 여부를 나타내는 플래그입니다.
work_state: 작업의 상태를 나타내는 문자열입니다.
프로젝트 및 고객 정보:
id, name, nick: 고객 또는 담당자에 대한 식별자 및 이름 정보입니다.
subject: 프로젝트나 작업의 제목입니다.
content, condate1, condate2: 프로젝트나 작업의 상세 내용 및 날짜 정보입니다.
regist_day: 등록 날짜를 기록합니다.
파일 및 문서 관련 정보:
file_name_0 ~ file_name_4: 관련된 파일의 이름을 저장합니다.
file_copied_0 ~ file_copied_4: 파일 복사본의 이름을 저장합니다.
금전 및 청구 관련 정보:
estimate1 ~ estimate4: 견적 관련 정보입니다.
bill1 ~ bill6: 청구서 관련 정보입니다.
deposit1 ~ deposit6: 입금 관련 정보입니다.
receivable: 미수금 관련 정보입니다.
claimamount1 ~ claimamount7, claimbalance1 ~ claimbalance7: 청구금액 및 잔액 정보입니다.
작업 진행 관련 정보:
worklist: 작업 리스트를 저장합니다.
workday, endworkday: 작업 시작일과 종료일을 나타냅니다.
worker, cablestaff, asman: 작업자, 케이블 스태프, A/S 담당자 정보를 포함합니다.
A/S 관련 정보:
asday, asendday, asproday: A/S 관련 날짜 정보입니다.
aslist, asresult, ashistory: A/S 관련 작업 리스트, 결과, 이력 정보를 저장합니다.
청구 및 클레임 정보:
claimperson, claimtel: 클레임을 제기한 사람과 그 연락처입니다.
claimdate1 ~ claimdate6: 클레임 발생일을 기록합니다.
claimfix1 ~ claimfix7: 클레임 수정 관련 정보입니다.
기타 정보:
comment, searchtag, update_log: 코멘트, 검색 태그, 업데이트 로그와 같은 부가 정보를 기록합니다.
## 공급가액,세액 자동만들기 프롬프트
위의 코드에서 4개의 estimate 관련 내용을 한행에 td요소를 8개로 나눠서 날짜부터 금액을 표현하는 것까지 표현하고,
파일첨부는 colspan="1", colspan="7"로 구분해서 사용하자.
그리고 위의 요소는 페이지를 오픈할때, 콤마를 제거하고, 숫자 3자리마다 콤마를 찍어주는 로직을 넣어준다.
그리고, input이 발생할때 위의 요소는 세액은 readonly로 놓고, 공급가액을 넣으면 세액과 금액을 자동으로 계산하고, 반대로 금액을 넣으면 역으로 공급가액과 세액을 계산하는 동적 페이지로 구조를 자바스크립트로 만든다.
$bill6_vat = isset($row['bill6_vat']) ? $row['bill6_vat'] : '';
위의 형식으로 만들어줘.
$bill6_vat = isset($_REQUEST['bill6_vat']) ? $_REQUEST['bill6_vat'] : '';
위의 형식으로 만들어줘.
1. 위의 코드를 $bill_issueDate1, $bill_issueDate2 ... 이런식으로 표현
2. 위의 코드를 bill_issueDate1, bill_issueDate2 ... 이런식으로 표현
3. 위의 코드를 bill_issueDate1=?, bill_issueDate2=? ... 이런식으로 표현
위의 3개를 만족하는 모양 형성해줘.
#컬럼제작
만든 컬럼을 적용해서 하는데, 혹시 등록일자는 기본으로 있어야 할 것 같아. 등록일자(registedate) , is_deleted, updatelog, searchtag는 항상 기본으로 들어가야 한다. 모든 table에 있어야 한다.
이에 따라 테이블에 4개의 컬럼을 추가하는 slq문장도 필요한다.
위의 코드에서 tbody의 tr요소를 4개 만들건데,
name은 위의 tr요소 행 숫자만큼 col1부터 col13까지 [] 형식으로 만들어줘.
아니다. 현재 php와 mysql의 버전이 json 타입으로 저장할수 없기에 text로 저장하는 대신 json으로 encode, decode해서 사용한다.
위의 코드는 수정되어야 한다. 일단 col18개까지 늘어야 한다.
엑셀은 D열부터 col1에 해당된다. 엑셀수식을 d5는 col1과 같은 것이다. 이렇게 해줘.
1) col7은 col3 * col4 으로 계산한다.
2) col8은 col5*col6*col7 로 계산한다.
3) col10 = col9* 1.2
4) col11 = col8 * col10
5) col12 는 엑셀수식 =ROUND(N5,-3) 이것을 이용한다. N5는 col11이다.
6) col14 는 엑셀수식 =ROUND(J5*P5,-3)
7) col15 , 엑셀수식 =O5+Q5
8) col16 = 엑셀수식 =R5/J5
9) col17 = 엑셀수식 =ROUND(S5,-3)
10) col18 = 엑셀수식 =R5/K5
이렇게 수식을 적용해줘.
위의 코드는 수정되어야 한다. 일단 col20개까지 늘어야 한다.
엑셀은 D열부터 col1에 해당된다. 엑셀수식을 d5는 col1과 같은 것이다. 이렇게 해줘.
1) col6은 =(col7*col8*col9*col9)/1000
2) col9은 col5/2
3) col12 = col6 * col11
4) col11 = col8 * col10
5) col13는 col2 * col3 * col12
6) col15는 col13 * col14
7) col15은 엑셀수식 =O5+Q5
8) col18은 =(col15/col2/col3)+col7
9) col19= 엑셀수식 math.round(col18*1.2*1000)/1000
10) col20= 엑셀수식 math.round(col18/3*1000)/1000
이렇게 수식을 적용해줘.
+ - Copy
품목
두께(T)
폭
길이(M)
가공비
입고가
원가합계
판매가 15%
위의 price_screenplate의 테이블을 아래의 th요소에 맞게 만들어야 한다.
function addRow(tableBody, rowData) {
var newRow = $('
');
// + / - 버튼 추가
newRow.append('
' +
'
' +
'' +
'' +
'' +
'
');
// col1부터 col8까지 채우기
for (let i = 1; i <= 8; i++) {
let colValue = rowData['col' + i] || ''; // 값이 없으면 빈 문자열 사용
// 첫 번째 열 제외, 모든 열에 텍스트 박스를 추가
newRow.append('
');
}
// 새 행을 테이블에 추가
tableBody.append(newRow);
// 숫자 필드에 3자리마다 콤마 추가 (소수점 입력 가능)
newRow.find('.number-format').on('input change', function() {
let value = $(this).val().replace(/,/g, ''); // 기존의 콤마를 제거
// 소수점 포함 숫자 검사
if (!isNaN(value) && value !== '') {
// 정수와 소수 부분 분리
let parts = value.split('.');
parts[0] = Number(parts[0]).toLocaleString('en'); // 3자리마다 콤마 추가
// 소수점이 있는 경우
let formattedValue = parts.join('.');
$(this).val(formattedValue);
}
// 행 계산 함수 호출
calculateRow(newRow);
});
// 처음 로드될 때도 자동 계산 적용
calculateRow(newRow);
}
function calculateRow(row) {
// 소수점 자릿수와 콤마를 포함한 숫자 형식 변환 함수
function formatNumber(value, decimalPlaces) {
// value를 소수점 자릿수에 맞게 고정
let fixedValue = parseFloat(value).toFixed(decimalPlaces);
// 정수 부분과 소수 부분으로 분리
let [integerPart, decimalPart] = fixedValue.split('.');
// 정수 부분에만 콤마 추가
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
// 소수점 이하가 존재하고 0보다 큰 경우, 정수 부분과 결합하여 반환
if (decimalPart && parseInt(decimalPart) > 0) {
return `${integerPart}.${decimalPart}`;
} else {
return integerPart; // 소수점 이하가 없거나 0인 경우 정수만 반환
}
}
// col1부터 col8까지의 값을 가져오기
const col6 = parseFloat(row.find('.col6').val().replace(/,/g, '')) || 0;
const col7 = parseFloat(row.find('.col7').val().replace(/,/g, '')) || 0;
const col8 = parseFloat(row.find('.col8').val().replace(/,/g, '')) || 0;
// 판매가 15% (col9) 계산: col8에 1.15를 곱한 값
const col9 = col8 * 1.15;
if (!isNaN(col9)) {
row.find('.col9').val(formatNumber(col9, 0));
}
// 콤마 및 소수점 표시 설정
if (!isNaN(col6)) {
row.find('.col6').val(formatNumber(col6, 2));
}
if (!isNaN(col7)) {
row.find('.col7').val(formatNumber(col7, 2));
}
if (!isNaN(col8)) {
row.find('.col8').val(formatNumber(col8, 0));
}
}
위의 코드를 col1부터 col8까지 만들어야하는데,
숫자 3자리마다 콤마 형태로 나오게 해줘.
자동계산은 원가합계에 해당되는 col7과, col8이 해당되고 이 col7,col8은 수식이 적용되어야 한다.
col7은 = col5 + col6
col8은 =ROUND(col7*1.2,-3)
#연기차단재 관련 생성 프롬프트
+ - Copy
품목
용도
단위(롤)
길이(mm)
폭(mm)
용차
가공비
입고가
원가합계
판매가 15%
1롤/50M
위의 price_smokeban의 테이블을 아래의 th요소에 맞게 만들어야 한다.
(위의 코드는 참고용이다. 11개의 컬럼을 만들어야 하니까.)
위의 코드를 col1부터 col11까지 만들어야하는데,
숫자 3자리마다 콤마 형태로 나오게 해줘.
자동계산은 원가합계에 해당되는 col9과, col10, col11이 해당되고 이는 수식이 적용되어야 한다.
col9은 = col6/(10*50) + col7+ col8
col10은 =ROUND(col9 * 1.15,-3)
col11은 ==ROUND((col10*50)/(1200/50),-4)
function addRow(tableBody, rowData) {
var newRow = $('
');
// + / - 버튼 추가
newRow.append('
' +
'
' +
'' +
'' +
'' +
'
');
// col1부터 col8까지 채우기
for (let i = 1; i <= 8; i++) {
let colValue = rowData['col' + i] || ''; // 값이 없으면 빈 문자열 사용
// 첫 번째 열 제외, 모든 열에 텍스트 박스를 추가
newRow.append('
');
}
// 새 행을 테이블에 추가
tableBody.append(newRow);
// 숫자 필드에 3자리마다 콤마 추가 (소수점 입력 가능)
newRow.find('.number-format').on('input change', function() {
let value = $(this).val().replace(/,/g, ''); // 기존의 콤마를 제거
// 소수점 포함 숫자 검사
if (!isNaN(value) && value !== '') {
// 정수와 소수 부분 분리
let parts = value.split('.');
parts[0] = Number(parts[0]).toLocaleString('en'); // 3자리마다 콤마 추가
// 소수점이 있는 경우
let formattedValue = parts.join('.');
$(this).val(formattedValue);
}
// 행 계산 함수 호출
calculateRow(newRow);
});
// 처음 로드될 때도 자동 계산 적용
calculateRow(newRow);
}
function calculateRow(row) {
// 소수점 자릿수와 콤마를 포함한 숫자 형식 변환 함수
function formatNumber(value, decimalPlaces) {
// value를 소수점 자릿수에 맞게 고정
let fixedValue = parseFloat(value).toFixed(decimalPlaces);
// 정수 부분과 소수 부분으로 분리
let [integerPart, decimalPart] = fixedValue.split('.');
// 정수 부분에만 콤마 추가
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
// 소수점 이하가 존재하고 0보다 큰 경우, 정수 부분과 결합하여 반환
if (decimalPart && parseInt(decimalPart) > 0) {
return `${integerPart}.${decimalPart}`;
} else {
return integerPart; // 소수점 이하가 없거나 0인 경우 정수만 반환
}
}
// col1부터 col8까지의 값을 가져오기
const col6 = parseFloat(row.find('.col6').val().replace(/,/g, '')) || 0;
const col7 = parseFloat(row.find('.col7').val().replace(/,/g, '')) || 0;
const col8 = parseFloat(row.find('.col8').val().replace(/,/g, '')) || 0;
// 판매가 15% (col9) 계산: col8에 1.15를 곱한 값
const col9 = col8 * 1.15;
if (!isNaN(col9)) {
row.find('.col9').val(formatNumber(col9, 0));
}
// 콤마 및 소수점 표시 설정
if (!isNaN(col6)) {
row.find('.col6').val(formatNumber(col6, 2));
}
if (!isNaN(col7)) {
row.find('.col7').val(formatNumber(col7, 2));
}
if (!isNaN(col8)) {
row.find('.col8').val(formatNumber(col8, 0));
}
}
######## #개발자 컬럼보기 ########
위의 코드에서 $user_id=='pro'인 경우는 th행을 하나 더 만들건데,
일련번호를 부여해서 개발할때 보려고 한다.
th 2번째 열부터 1로 시작해서 66열까지 1,2,.... 66번까지 col과 비교하면서 개발을 하려고 개발자 아이디인 'pro'만 보이도록 코드를 수정해줘.
######단가 가져오기 fetch_price ##### 제작 프롬프트
단가를 가져오는 코드들을 fetch_price.php를 호출해서 가져오는 방식이면 좋겠다.
이를 호출할때 테이블명과 값을 전달하면 결과를 리턴하는 방식이면 좋겠다.
그러면 위의 9가지 단가들에 대해서 하나의 모듈을 사용하면 효과적일 것 같다.
물론 조건은 파라미터는 하나에서 여러개가 될 수 있다.
## json 저장 안됨 ##
$sql = "SELECT itemList FROM {$DB}.$tablename WHERE JSON_UNQUOTE(JSON_EXTRACT(itemList, '$.code')) IN ($placeholders) AND (is_deleted IS NULL OR is_deleted = 0)";
위의 코드는 잘못되었다.
php버전과 mysql에서 json을 지원하지 않는 버전을 사용한다.
text로 저장하고, encode, decode로 작업한다.
// 모터 부분
if(True) {
$data = [];
$counter = 0;
foreach ($decodedEstimateList as $item) {
if (isset($item['col5']) && !empty($item['col5'])) {
$counter++;
// 각 col 값을 배열에 추가합니다.
$row = [];
$row['col1'] = '2.2 모터';
$row['col2'] = $item['col3'] ?? ''; // 부호
$row['col3'] = $item['col5'] ?? ''; // 실리카
$row['col4'] = $item['col7'] ?? ''; // SUS
$row['col5'] = $item['col6'] ; // 벽마감표시
$row['col6'] = $item['col8']; // 오픈 가로
$row['col7'] = $item['col9']; // 오픈 세로
$row['col8'] = $item['col10']; // 제작 가로
$row['col9'] = $item['col11']; // 제작 세로
$row['col10'] = $item['col31']; // 케이스 500*380
// $data 배열에 행을 추가합니다.
$data[] = $row;
}
}
모터부분의 내용의 누계를 내려고 한다.
## 모터 150 부터 1000까지 개수 파악하는 프롬프트 ##
전체 col1~col12까지 배열은 필요없고 sum의 개념만 있으면 된다.
$item['col13']은 중량을 나타내는데
이 값에 따라 col1~col7까지 누적해야 한다.
col1의 값은 아래의 엑셀공식이다.
E8은 $item['col4']의 문자열앞에 두문자'KS'이면 '스크린'으로 인식
m8은 중량을 의미하는 $item['col13'];
엑셀공식
=IF(AND(E8="스크린",BK8=4,M8<=150),1,IF(AND(E8="스크린",BK8=5,M8<=123),1,IF(AND(E8="스크린",BK8=6,M8<=104),1,0)))
col2의 값은 아래의 엑셀공식이다.
E8은 $item['col4']의 문자열앞에 두문자'KS'이면 '스크린'으로 인식
m8은 중량을 의미하는 $item['col13'];
bk8은 $item['col53'];
엑셀공식
=IF(AND(E8="스크린",BK8=4,M8>150,M8<=300),1,IF(AND(E8="스크린",BK8=5,M8>123,M8<=246),1,IF(AND(E8="스크린",BK8=6,M8>104,M8<=208),1,IF(AND(E8="철재",BK8=4,M8<=300),1,IF(AND(E8="철재",BK8=5,M8<=246),1,IF(AND(E8="철재",BK8=6,M8<=208),1,0))))))
col3의 값은 아래의 엑셀공식이다.
E8은 $item['col4']의 문자열앞에 두문자'KS'이면 '스크린'으로 인식
m8은 중량을 의미하는 $item['col13'];
bk8은 $item['col53'];
엑셀공식
=IF(AND(E8="스크린",BK8=4,M8>300,M8<=400),1,IF(AND(E8="스크린",BK8=5,M8>246,M8<=327),1,IF(AND(E8="스크린",BK8=6,M8>208,M8<=300),1,IF(AND(E8="철재",BK8=4,M8>300,M8<=400),1,IF(AND(E8="철재",BK8=5,M8>246,M8<=327),1,IF(AND(E8="철재",BK8=6,M8>208,M8<=277),1,0))))))
col4의 값은 아래의 엑셀공식이다.
E8은 $item['col4']의 문자열앞에 두문자'KS'이면 '스크린'으로 인식
m8은 중량을 의미하는 $item['col13'];
bk8은 $item['col53'];
엑셀공식
=IF(AND(E8="스크린",BK8=5,M8>327,M8<=500),1,IF(AND(E8="스크린",BK8=6,M8>300,M8<=424),1,IF(AND(E8="철재",BK8=5,M8>400,M8<=500),1,IF(AND(E8="철재",BK8=5,M8>327,M8<=500),1,IF(AND(E8="철재",BK8=6,M8>277,M8<=424),1,IF(AND(E8="철재",BK8=8,M8<=324),1,0))))))
col5의 값은 아래의 엑셀공식이다.
E8은 $item['col4']의 문자열앞에 두문자'KS'이면 '스크린'으로 인식
m8은 중량을 의미하는 $item['col13'];
bk8은 $item['col53'];
엑셀공식
=IF(AND(BK8=5,M8>500,M8<=600),1,IF(AND(BK8=6,M8>424,M8<=508),1,IF(AND(BK8=8,M8>324,M8<=388),1,0)))
col6의 값은 아래의 엑셀공식이다.
E8은 $item['col4']의 문자열앞에 두문자'KS'이면 '스크린'으로 인식
m8은 중량을 의미하는 $item['col13'];
bk8은 $item['col53'];
엑셀공식
=IF(AND(E8="철재",BK8=6,M8>600,M8<=800),1,IF(AND(E8="철재",BK8=6,M8>508,M8<=800),1,IF(AND(E8="철재",BK8=8,M8>388,M8<=611),1,0)))
col7의 값은 아래의 엑셀공식이다.
E8은 $item['col4']의 문자열앞에 두문자'KS'이면 '스크린'으로 인식
m8은 중량을 의미하는 $item['col13'];
bk8은 $item['col53'];
엑셀공식
=IF(AND(E8="철재",BK8=6,M8>800,M8<=1000),1,IF(AND(E8="철재",BK8=8,M8>611,M8<=1000),1,0))
col8의 값은 아래이다.
$item['col15']의 합
col9의 값은 값은 아래이다.
$item['col16']의 합
col10의 값은 값은 아래이다.
$item['col17']의 합
col11의 값은 값은 아래이다.
$item['col14']의 합
col12의 값은 값은 아래이다.
col11 * 4
## 스크린 발주서 절곡 부분 ##
// 절곡 부분
if(True) {
$data = [];
foreach ($decodedEstimateList as $item) {
}
echo '
';
echo '
';
echo '';
echo '
';
echo '
2.3 절곡
';
echo '
(1) 가이드레일 (EGI 1.6T/ SUS 1.2T)
';
echo '
(2) 케이스 (EGI 1.6T)
';
echo '
(3) 하단마감재 (SUS 1.2T)
';
echo '
(4) 연기차단재
';
echo '
';
echo '
';
echo '
사이즈
';
echo '
수량
';
echo '
사이즈
';
echo '
수량
';
echo '
분류
';
echo '
3000
';
echo '
4000
';
echo '
종류
';
echo '
수량
';
echo '
';
echo '
';
echo '
' . $col1_sum . '
';
echo '
' . $col2_sum . '
';
echo '
' . $col3_sum . '
';
echo '
' . $col4_sum . '
';
echo '
' . $col5_sum . '
';
echo '
' . $col6_sum . '
';
echo '
' . $col7_sum . '
';
echo '
' . $col8_sum . '
';
echo '
' . $col9_sum . '
';
echo '
';
echo '';
echo '
';
echo '
';
}
아래의 5개는 배열은 필요없고 sum의 개념만 있으면 된다.
AC8은 $item['col23']은 셔터의 유효 길이를 의미한다.
이 값에 따라 row3_1 ~ row3_5는 행의 누계를 3_1은 3열, 1행을 의미한다. 총 5개를 만들어야 한다.
row3_1의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AC8<=2438,2,IF(AND(AC8>4300,AC8<=5438),2,0))
row3_2의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AND(AC8>2438, AC8<=3000),2,IF(AND(AC8>4300,AC8<=5438),2,IF(AND(AC8>5438,AC8<=6000),4,IF(AND(AC8>6000,AC8<=7300),2,0))))
row3_3의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AND(AC8>3000, AC8<=3500),2,IF(AND(AC8>6000,AC8<=6500),2,0))
row3_4의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AND(AC8>3500, AC8<=4000),2,IF(AND(AC8>6500,AC8<=7000),2,0))
row3_5의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AND(AC8>4000, AC8<=4300),2,IF(AND(AC8>7000,AC8<=7300),2,0))
아래의 8개는 배열은 필요없고 sum의 개념만 있으면 된다.
AQ8은 $item['col32']은 셔터의 유효 길이를 의미한다.
이 값에 따라 row5_1 ~ row5_6는 행의 누계를 5_1은 5열, 1행을 의미한다.
row5_1의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AQ8<=1219,1,IF(AND(AQ8>4150,AQ8<=4219),1,IF(AND(AQ8>4219,AQ8<=4719),1,IF(AND(AQ8>4876,AQ8<=5219),1,IF(AND(AQ8>5219,AQ8<=5369),1,IF(AND(AQ8>9026,AQ8<=9219),1,0))))))
row5_2의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AND(AQ8>1219,AQ8<=2438),1,IF(AND(AQ8>4719,AQ8<=4876),2,IF(AND(AQ8>5369,AQ8<=5938),1,IF(AND(AQ8>6000,AQ8<=6438),1,IF(AND(AQ8>6500,AQ8<=6588),1,IF(AND(AQ8>8300,AQ8<=8376),2,IF(AND(AQ8>8376,AQ8<=8438),1,IF(AND(AQ8>8438,AQ8<=8876),2,IF(AND(AQ8>9000,AQ8<=9026),2,IF(AND(AQ8>9219,AQ8<=9438),1,IF(AND(AQ8>10150,AQ8<=10738),1,0)))))))))))
row5_3의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AND(AQ8>2438,AQ8<=3000),1,IF(AND(AQ8>4150,AQ8<=4219),1,IF(AND(AQ8>5369,AQ8<=5438),1,IF(AND(AQ8>5938,AQ8<=6000),2,IF(AND(AQ8>6438,AQ8<=6500),1,IF(AND(AQ8>7000,AQ8<=7150),1,IF(AND(AQ8>8376,AQ8<=8438),2,IF(AND(AQ8>8876,AQ8<=9000),3,IF(AND(AQ8>9438,AQ8<=10150),2,IF(AND(AQ8>10738,AQ8<=11000),1,0))))))))))
row5_4의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AND(AQ8>3000,AQ8<=3500),1,IF(AND(AQ8>4219,AQ8<=4719),1,IF(AND(AQ8>5438,AQ8<=5938),1,IF(AND(AQ8>6438,AQ8<=6500),1,IF(AND(AQ8>6588,AQ8<=7000),2,IF(AND(AQ8>7150,AQ8<=7650),1,IF(AND(AQ8>8300,AQ8<=8376),1,IF(AND(AQ8>9219,AQ8<=9438),2,IF(AND(AQ8>9438,AQ8<=9500),1,0)))))))))
row5_5의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AND(AQ8>3500,AQ8<=4000),1,IF(AND(AQ8>4876,AQ8<=5219),1,IF(AND(AQ8>6000,AQ8<=6438),1,IF(AND(AQ8>7150,AQ8<=7500),1,IF(AND(AQ8>7650,AQ8<=8000),2,IF(AND(AQ8>8000,AQ8<=8150),1,IF(AND(AQ8>8438,AQ8<=8876),1,IF(AND(AQ8>9026,AQ8<=9219),2,IF(AND(AQ8>9500,AQ8<=10000),1,IF(AND(AQ8>10150,AQ8<=10438),2,IF(AND(AQ8>10738,AQ8<=11000),2,0)))))))))))
row5_6의 값은 아래의 엑셀공식이다.
엑셀공식
=IF(AND(AQ8>4000,AQ8<=4150),1,IF(AND(AQ8>5219,AQ8<=5369),1,IF(AND(AQ8>6500,AQ8<=6588),1,IF(AND(AQ8>7000,AQ8<=7150),1,IF(AND(AQ8>7500,AQ8<=7650),1,IF(AND(AQ8>8000,AQ8<=8150),1,IF(AND(AQ8>8150,AQ8<=8300),2,IF(AND(AQ8>9000,AQ8<=9026),1,IF(AND(AQ8>10000,AQ8<=10150),1,IF(AND(AQ8>10438,AQ8<=10738),2,0))))))))))
row5_7의 값은 $item['col39'] 의 합
row5_8의 값은 $item['col41'] 의 합
work 테이블의 아래의 컬럼이 있다.
1차
2차
3차
4차
5차
6차
6행의 컬럼이름들이 많다. 이 컬럼을 accountList 컬럼으로 넣으려고 하는데,
json형태로 만든 후 encode, decode를 통해 테이블에는 text형태로 저장할 것이다.
php와 mysql이 json 저장을 지원하지 않는 버전이라서 그렇다.
그러면 아래의 코드에서 json의 encode, decode 코드형태를 엿볼 수 있다.
위의 컬럼의 값들을 읽어서 1행부터 col1,col2,col3,col4,col5,col6까지 생성되는 것이다.
예를 들면,
1차
위의 코드는 col1은 bill_issueDate1이 되는 것이다.
위의 데이터는 6행을 반복하면 col1의 데이터는
[{"col1":"2024-09-01"}.......{"col1":""}]
이렇게 되는 것이겠지?
아래의 코드를 참조하자.
setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
// 이 스크립트의 메모리 제한 증가
ini_set('memory_limit', '256M');
$sql = "SELECT * FROM " . $DB . "." . $tablename . " ";
try {
$stmh = $pdo->prepare($sql);
$stmh->execute();
$rows = $stmh->fetchAll(PDO::FETCH_ASSOC);
$dataByNum = [];
// 데이터를 num별로 그룹화
foreach ($rows as $row) {
$num = $row['num'];
if (!isset($dataByNum[$num])) {
$dataByNum[$num] = [
'accountList' => []
];
}
$dataByNum[$num]['accountList'] = json_decode($row['accountList'], true);
}
$updateData = [];
// num별로 데이터 처리
foreach ($dataByNum as $num => $lists) {
$newOrderlist = [];
foreach ($lists['accountList'] as $item) {
$newItem = $item;
$tempCol14 = isset($item['col14']) ? $item['col14'] : '';
$tempCol15 = isset($item['col15']) ? $item['col15'] : '';
$newItem['col15'] = $tempCol14;
$newItem['col16'] = $tempCol15;
$newOrderlist[] = $newItem;
}
$updateData[$num] = [
'accountList' => json_encode($newOrderlist, JSON_UNESCAPED_UNICODE)
];
}
// 데이터베이스 업데이트
$pdo->beginTransaction();
$sql = "UPDATE " . $DB . ".{$tablename} SET accountList = ? WHERE num = ?";
$stmh = $pdo->prepare($sql);
foreach ($updateData as $num => $data) {
$stmh->execute([$data['accountList'], $num]);
}
$pdo->commit();
} catch (PDOException $Exception) {
$pdo->rollBack();
print "오류: " . $Exception->getMessage();
}
?>
work 테이블의 위의 컬럼들을 accountList에 저장하는 코드로 만들어줘. 컬럼을 정리하려고 한다.
## json으로 올바르게 나오지 않는경우#####
## 아래의 코드로 하면 된다.
// JSON이 배열인지 아닌지 여부를 확인하는 방법
if (typeof accountList === 'string') {
try {
accountList = JSON.parse(accountList);
} catch (e) {
console.error('JSON 파싱 오류:', e);
accountList = [];
}
}
if (Array.isArray(accountList)) {
console.log('accountList is an array:', accountList);
} else {
console.log('accountList is not an array, resetting to empty array');
accountList = [];
}
accountList.forEach(function(rowData, index) {
addBillRow($('#accountListBody'), rowData);
});
##공급가액 아이콘으로 계산하기 ###
function addRow_Bill(tableBody, rowData = {}) {
var newRow = $('
');
// 첫 번째 열: 일련번호 (자동 생성)
newRow.append('
' +
'
' +
'' +
'' +
'
');
// col1 (발행일자) - "0000-00-00"을 빈 문자열로 처리
var col1Value = (rowData.col1 === "0000-00-00") ? '' : rowData.col1;
newRow.append('
');
// col2 (공급가액)
newRow.append('
');
// col3 (부가세)
newRow.append('
');
// col4 (발행금액)
newRow.append('
');
// col5 (입금일자) - "0000-00-00"을 빈 문자열로 처리
var col5Value = (rowData.col5 === "0000-00-00") ? '' : rowData.col5;
newRow.append('
');
// col6 (입금액)
newRow.append('
');
tableBody.append(newRow);
// 일련번호를 업데이트
updateSerialNumbers(tableBody);
// 숫자 필드에 3자리마다 콤마 추가 (소수점 입력 가능)
newRow.find('.number-format').on('input change', function() {
let value = $(this).val().replace(/,/g, ''); // 기존의 콤마를 제거
// 소수점 포함 숫자 검사
if (!isNaN(value) && value !== '') {
// 정수와 소수 부분 분리
let parts = value.split('.');
parts[0] = Number(parts[0]).toLocaleString('en'); // 3자리마다 콤마 추가
// 소수점이 있는 경우
let formattedValue = parts.join('.');
$(this).val(formattedValue);
}
//계산 함수 호출
calculateTotals();
});
// 처음 로드될 때도 자동 계산 적용
calculateTotals();
}
위의 코드에 3번째 요소와 5번째 td요소인 발행합계의 열에 input요소 옆에 계산 아이콘은 배치해서 누르면 공급가액/부가세/발행합계를 그 행에 대해서 자동계산을 하려고 한다.
공급가액 옆의 아이콘을 누르면 공급가액을 기준으로 부가세와 발행금액이 계산되고, 발행금액을 누르면 역으로 공급가액과 부가세를 계산하는 원리다.
이 아이콘을 사용할거야.
1행은 col1은 condate, col2는 estimate1_supply, col3는 estimate1_vat, col4는 estimate1,
col5는 file_name_0, , col6은 file_copied_0
다소 매치가 안될것 같지만, 내가 제공한 코드를 보면 규칙이있으니 참고바랍니다.
2행은 col1은 condate1, col2는 estimate2_supply, col3는 estimate2_vat, col4는 estimate2,
col5는 file_name_1, col6은 file_copied_1
2행은 col1은 condate2, col2는 estimate3_supply, col3는 estimate3_vat, col4는 estimate3,
col5는 file_name_2, col6은 file_copied_2
이렇게 나와야 한다.
#2. 파일 업로드 시 식별자 전송
saveData 함수에서 파일을 전송할 때, 해당 파일의 row_id도 함께 전송하여 파일이 어느 행에 속하는지 알 수 있도록 합니다.
실제 위와 같이 행을 동적으로 추가하고 그 마지막에 첨부파일을 넣는 방식인데, 여러가지 동적으로 행을 만들고 지우고 추가하고 하는 과정에서 내 마음대로 되지 않는구나.
화면의 동적추가 및 기타 동작은 되지만, 서버에서 처리하는 insert.php 에서 제대로 되지 않는다. 이유는 알것 같지만, 막상 코드로 잘 안된다.
문제는 이것이다.
estimateList에서 col5, col6을 json형태로 가져와서 웹에서 front end에서는 잘 되는데 이것이 file을 서버로 전달하면, insert.php에서 파일의 첨부가 있을때, 이것이 1행에서 추가된 것이면 기존의 col5, col6의 1행에 해당되는 값만 수정이 되어야 하는데,
지금은 만약 4행이 있다면 4행 전부가 그 파일이름으로 수정이 되고, 1행은 서버저장 파일이름도 잘못되서 나온다.
결국은 estimateList의 각 행과 upfile로 전달된 file의 첨부가 몇행에서 이뤄졌는지 정보가 전달되어야 정확할 것 같은데 방법이 있을까?
ChatGPT의 말:
ChatGPT
네, 상황을 이해했습니다. estimateList의 각 행과 파일 업로드가 정확히 매칭되지 않아서 문제가 발생하고 있습니다. 이를 해결하기 위해서는 다음과 같은 전략을 사용해야 합니다:
해결책:
행의 고유 식별자 추가: 각 행이 고유한 식별자를 가지도록 하여 파일 업로드와 정확히 매칭할 수 있도록 합니다. 이 식별자는 행이 생성될 때마다 할당되며, insert.php에서 파일 업로드 처리 시 이 식별자를 사용해 해당 행과 파일을 매칭합니다.
파일 업로드 시 식별자 전송: 파일 업로드가 일어날 때 해당 파일이 어느 행에 속하는지 식별자를 함께 전송합니다. 이를 통해 insert.php에서 해당 행만 파일 정보를 업데이트할 수 있습니다.
1. 행의 고유 식별자 추가
각 행에 고유한 data-id 속성을 추가합니다. 이 속성은 자바스크립트에서 행을 생성할 때 무작위 또는 순차적으로 생성됩니다.
#컬럼등 추가했을때 만들어주는 코드
cableworkStatus, certifiedInspector, certifiedLabelAttachedDate
위의 3개의 컬럼을 추가했다.
_row.php 파일은 아래의 형태이다. 추가해줘.
8250,H8<=10200),1,0)
$col61은 =IF(AND(E8="스크린",BK8=6,H8>8250,H8<=10200),1,0)
var fileDiv = $('
').attr('id', 'file' + i).css({
display: 'inline-block',
width: 'calc(20% - 10px)', // 5개를 한 줄에 맞추기 위해 20%의 너비 할당 (5개의 이미지가 한 줄에 배치됨)
margin: '5px',
textAlign: 'center' // 이미지와 버튼을 중앙 정렬
});
위의 코드는 5개 있을때는 좋은데, 1개, 2개 이미지가 있을때는 서로 겹처보인다. 1개, 2개~ 5개까지 여백이 확보되게 수정해줘.
## 같은 이름의 첨부파일 등록하지 않기
코드 수정:
다음은 파일을 FormData에 추가하기 전에 중복 여부를 검사하는 코드입니다.
javascript
코드 복사
function uploadFiles(files) {
console.log('업로드 파일 리스트:', files);
isUploading = true; // 업로드 중 상태 설정
var formData = new FormData($('#board_form')[0]);
// 현재 폼 데이터에 추가된 파일 이름 목록 추적
var existingFiles = new Set();
for (var pair of formData.entries()) {
if (pair[0] === 'upfile[]') {
existingFiles.add(pair[1].name);
}
}
// 중복되지 않은 파일만 추가
for (var i = 0; i < files.length; i++) {
if (!existingFiles.has(files[i].name)) {
formData.append('upfile[]', files[i]);
existingFiles.add(files[i].name); // 추가된 파일 이름을 목록에 저장
console.log('파일 추가:', files[i].name); // 디버그
} else {
console.log('중복 파일 무시:', files[i].name); // 디버그
}
}
#토글버튼 추가로직 #
위의 코드에서 table을 보이게 안보이게 하는 토글 버튼을 만들건데, 아래의 코드를 참조해서 html 코드와 자바스크립트를 추가해줘.
쿠키에도 저장하고 다시 불러오는 과정도 포함된다.
절곡판
품목
규격
두께(T)
비중
㎡ / 단가
$(document).ready(function() {
initializePage();
// Toggle button for bendTable
$("#bendTableToggle").on("click", function() {
var showBendTable = getCookie("showBendTable");
var bendTable = $("#item_bendTable");
if (showBendTable === "show") {
bendTable.css("display", "none");
setCookie("showBendTable", "hide", 10);
} else {
bendTable.css("display", "block");
setCookie("showBendTable", "show", 10);
}
});
// Check the cookie value on page load and set the table visibility
var showBendTable = getCookie("showBendTable");
var bendTable = $("#item_bendTable");
if (showBendTable === "show") {
bendTable.css("display", "block");
} else {
bendTable.css("display", "none");
}
});
##발주서 테이블 생성원리 설명자료 ##
이제부터 생성원리에 대한 설명을 시작한다.
tr 1행은 아래와 같이 구성된다. 12개로 나뉜다.
구성품 길이 (mm) 수량 구성품 길이 수량 구성품 길이 수량 구성품 길이 수량
td 1열은 '하단마감재
(60*40)'
td 2열은 길이 3000 또는 4000으로 구성된 자료를 읽어와서 해당수량을 다음열인 3열에 나타내는 것이다.
길이 3000에 대한 수량 col44
길이 4000에 대한 수량 col45
td 4열은 '하단 보강엘바
(60*17)'
td 5열은 길이 3000 또는 4000으로 구성된 자료를 읽어와서 해당수량을 다음열인 6열에 나타내는 것이다.
길이 3000에 대한 수량 col47
길이 4000에 대한 수량 col48
td 7열은 '하단
보강평철'
td 8열은 길이 3000 또는 4000으로 구성된 자료를 읽어와서 해당수량을 다음열인 9열에 나타내는 것이다.
길이 3000에 대한 수량 col50
길이 4000에 대한 수량 col51
td 10열은 '하단 무게평철
[50*12T]'
td 11열은 길이 2000으로 구성된 자료를 읽어와서 해당수량을 다음열인 12열에 나타내는 것이다.
길이 2000에 대한 수량 col52
위의 내용을 코드로 만들어줘.
위의 코드를 하단마감재의 내용으로 전부 수정해줘.
하단마감재 계산방법은 아래와 같다. 즉, 혼합형,벽면형, 측면형 표시는 필요가 없다.
이미지는 ../img/bottombar/bottombar_KSS01.jpg
../img/bottombar/bottombar_KSE01.jpg
이런식으로 이름과 관련이미지가 저장되어있다.
KWE01는 KSE01과 같은 형태다.
하단마감재 산출공식은 아래를 참조한다.