Dokumentasi Query SQL - Aplikasi Timbangan

Dokumen ini berisi seluruh query SQL yang dieksekusi dalam aplikasi timbangan, termasuk alur eksekusi saat proses sinkronisasi data.


Alur Eksekusi: Dialog0.Accepted()

Saat user menekan tombol "Download" di main window dan mengkonfirmasi dialog, method Accepted() akan dijalankan dengan urutan:

def Accepted(self):
    is_Success = local_db.sync_with_server()      # Step 1
    if (is_Success):
        is_Success = local_db.upload_data()        # Step 2
    if (is_Success):
        is_Success = local_db.delete_old_data()    # Step 3
    if (is_Success):
        local_db.synchronize_download()            # Step 4
    self.close()

STEP 1: sync_with_server()

Query 1.1: Insert/Replace Equipment (Raspi/PC)

INSERT OR REPLACE INTO Equipment 
    ([ID],
     [Epicor_Resource_ID],
     [Epicor_Equipment_ID],
     [Epicor_Asset_Number],
     [Location],
     [Owned_By],
     [Description],
     [Type], 
     [MAC_Address]) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)

Tujuan: Menyimpan informasi equipment (Raspberry Pi/PC) berdasarkan MAC address dari API server.


Query 1.2: Select Setting untuk Validasi

SELECT Set_TB_Equpment_ID 
FROM Setting

Tujuan: Mengecek apakah sudah ada setting timbangan yang dipilih sebelumnya.


Query 1.3: Insert/Replace Setting

INSERT OR REPLACE INTO Setting 
VALUES (?, ?)

Parameter:

Tujuan: Menyimpan/update konfigurasi equipment dan sensor timbangan.


Query 1.4: Nonaktifkan Semua Sensor

UPDATE SENSOR 
SET is_active = 0

Tujuan: Menonaktifkan semua sensor sebelum sinkronisasi data baru dari server.


Query 1.5: Insert/Replace Equipment (dari GetEquipmentSensor API)

INSERT OR REPLACE INTO Equipment 
    ([ID],
     [Epicor_Resource_ID],
     [Epicor_Equipment_ID],
     [Epicor_Asset_Number],
     [Location],
     [Owned_By],
     [Description],
     [Type]) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?)

Tujuan: Menyimpan data equipment/timbangan dari server berdasarkan plant.


Query 1.6: Insert/Replace Sensor

INSERT OR REPLACE INTO Sensor 
    ([ID],
     [Equipment_ID],
     [Name],
     [Adjustment_value],
     [is_active],
     [Description],
     [Brand],
     [Output_format]) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?)

Tujuan: Menyimpan data sensor timbangan dari server, termasuk format output dan brand.


Query 1.7: Nonaktifkan Semua Epicor Transaction

UPDATE Epicor_Transaction 
SET is_active = 0

Tujuan: Menonaktifkan semua job sebelum sinkronisasi data terbaru dari server.


Query 1.8: Insert/Replace Epicor_Transaction

INSERT OR REPLACE INTO Epicor_Transaction 
    (Job_Number, 
     Employee_Id, 
     Plant, 
     Part_Number, 
     Part_Description, 
     Employee_Name, 
     ClockInDate, 
     Isi_Kemasan_C, 
     EAN, 
     SVH_Kemas, 
     SVL_Kemas, 
     SVH_Product, 
     SVL_Product, 
     SV_Product, 
     Unit_Kemas, 
     Unit_Product, 
     Cavity, 
     Jenis_job, 
     is_Active) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

Tujuan: Menyimpan data job aktif dari Epicor (SAP), termasuk standar berat dan parameter penimbangan.

Catatan Format Tanggal:


STEP 2: upload_data()

Query 2.1: Select Parameter Set Transaction yang Belum Sync

SELECT Job_Number, 
       Employee_Id, 
       Plant, 
       Part_Number, 
       Part_Description, 
       Employee_Name, 
       ClockInDate, 
       Isi_Kemasan_C, 
       EAN, 
       SVH_Kemas, 
       SVL_Kemas, 
       SVH_Product, 
       SVL_Product, 
       SV_Product, 
       Unit_Product, 
       Unit_Kemas, 
       Jenis_job, 
       Created_at, 
       is_Finished, 
       Jumlah_Lot, 
       Cavity 
FROM Parameter_Set_Transaction 
WHERE is_Synced = 0

Tujuan: Mengambil semua parameter set transaction yang belum diupload ke server.


Query 2.2: Update Parameter Set Transaction Setelah Sync Berhasil

UPDATE Parameter_Set_Transaction 
SET is_Synced = ? 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ?

Parameter:

Tujuan: Mencegah data yang sama diupload berkali-kali.


Query 2.3: Select Logging Transaction yang Belum Sync

SELECT ID, 
       Equipment_ID, 
       Sensor_ID, 
       Sensor_Name, 
       Value_Avg, 
       Value_Min, 
       Value_Max, 
       SV, 
       SVL, 
       SVH, 
       Created_at, 
       Logging_tag, 
       Unit, 
       Job_Number, 
       Part_Number, 
       Employee_ID, 
       Employee_Name, 
       OOS_Count_Low, 
       OOS_Count_High, 
       OOS_Value_Low, 
       OOS_Value_High, 
       No_Lot, 
       Value_Avg_Old, 
       is_Synced, 
       Alert_Status, 
       ClockInDate 
FROM Logging_Transaction 
WHERE is_Synced = 0

Tujuan: Mengambil semua hasil penimbangan yang belum diupload ke server.


Query 2.4: Update Logging Transaction Setelah Sync Berhasil

UPDATE Logging_Transaction 
SET is_Synced = ? 
WHERE ID = ?

Parameter:

Tujuan: Mencegah data yang sama diupload berkali-kali.


STEP 3: delete_old_data()

Query 3.1: Select Data Lama untuk Dihapus

SELECT DISTINCT ET.Job_Number, 
                ET.Employee_Id, 
                ET.ClockInDate 
FROM Epicor_Transaction ET 
WHERE ET.is_Active = 0 
  AND ET.ClockInDate < date('now','-3 days') 

EXCEPT 

SELECT DISTINCT PST.Job_Number, 
                PST.Employee_Id, 
                PST.ClockInDate 
FROM Parameter_Set_Transaction PST 
LEFT JOIN Logging_Transaction LT 
    ON PST.Job_Number = LT.Job_Number 
    AND PST.Employee_Id = LT.Employee_Id 
    AND PST.ClockInDate = LT.ClockInDate 
WHERE PST.is_Synced = 0 
   OR LT.is_Synced = 0

Tujuan: Mengidentifikasi data yang:

Logika:


Query 3.2: Delete dari Logging_Transaction

DELETE FROM Logging_Transaction 
WHERE (( Job_Number = '{row[0]}' 
     AND Employee_Id = '{row[1]}' 
     AND ClockInDate = '{row[2]}')
    OR ( Job_Number = '...' 
     AND Employee_Id = '...' 
     AND ClockInDate = '...')
    ... )

Tujuan: Menghapus data logging (hasil timbangan) yang sudah lama dan sudah sync.


Query 3.3: Delete dari Parameter_Set_Transaction

DELETE FROM Parameter_Set_Transaction 
WHERE (( Job_Number = '{row[0]}' 
     AND Employee_Id = '{row[1]}' 
     AND ClockInDate = '{row[2]}')
    OR ...)

Tujuan: Menghapus parameter set transaction yang sudah lama dan sudah sync.


Query 3.4: Delete dari Epicor_Transaction

DELETE FROM Epicor_transaction 
WHERE (( Job_Number = '{row[0]}' 
     AND Employee_Id = '{row[1]}' 
     AND ClockInDate = '{row[2]}')
    OR ...)

Tujuan: Menghapus data job Epicor yang sudah lama dan sudah sync.

Catatan: Jika tidak ada data yang memenuhi kriteria, query menggunakan kondisi WHERE FALSE sehingga tidak ada data yang dihapus.


STEP 4: synchronize_download()

Query 4.1: Select MAX ID Logging Transaction

SELECT MAX(ID) 
FROM Logging_Transaction

Tujuan: Mendapatkan ID terakhir untuk menghindari konflik primary key saat insert data dari server.


Query 4.2: Insert/Replace Parameter Set Transaction dari Server

INSERT OR REPLACE INTO Parameter_Set_Transaction 
    (Job_Number, 
     Employee_Id, 
     Plant, 
     Part_Number, 
     Part_Description, 
     Employee_Name, 
     ClockInDate, 
     Isi_Kemasan_C, 
     EAN, 
     SVH_Kemas, 
     SVL_Kemas, 
     SVH_Product, 
     SVL_Product, 
     SV_Product, 
     Unit_Product, 
     Unit_Kemas, 
     Jenis_job, 
     Created_at, 
     is_Finished, 
     is_Synced, 
     Jumlah_Lot, 
     Cavity) 
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

Parameter:

Tujuan: Mendownload parameter set transaction dari server (dari device lain atau web).


Query 4.3: Insert/Replace Logging Transaction dari Server

INSERT OR REPLACE INTO Logging_Transaction 
    (ID, 
     Equipment_ID, 
     Sensor_ID, 
     Sensor_Name, 
     Value_Avg, 
     Value_Min, 
     Value_Max, 
     SV, 
     SVL, 
     SVH, 
     Created_at, 
     Logging_tag, 
     Unit, 
     Job_Number, 
     Part_Number, 
     Employee_ID, 
     Employee_Name, 
     OOS_Count_Low, 
     OOS_Count_High, 
     OOS_Value_Low, 
     OOS_Value_High, 
     No_Lot, 
     Value_Avg_Old, 
     is_Synced, 
     Alert_Status, 
     ClockInDate) 
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

Parameter:

Tujuan: Mendownload hasil logging transaction dari server (dari device lain atau web).


Query Tambahan: Operasi Penimbangan

Insert Logging Transaction (Saat Timbang Baru)

-- Untuk Produk Bersih atau Kemas
INSERT INTO Logging_Transaction 
    (ID, 
     Equipment_ID, 
     Sensor_ID, 
     Sensor_Name, 
     Job_Number, 
     Part_Number, 
     Employee_ID, 
     Employee_Name, 
     No_Lot, 
     is_Synced, 
     Created_at, 
     Unit, 
     Value_Avg, 
     SVL, 
     SVH, 
     Alert_Status, 
     ClockinDate) 
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
-- Untuk Produk Kotor (dengan Cavity)
INSERT INTO Logging_Transaction 
    (ID, 
     Equipment_ID, 
     Sensor_ID, 
     Sensor_Name, 
     Job_Number, 
     Part_Number, 
     Employee_ID, 
     Employee_Name, 
     No_Lot, 
     is_Synced, 
     Created_at, 
     Unit, 
     Value_Avg, 
     SV, 
     Alert_Status, 
     ClockinDate) 
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

Logika Alert Status:


Update Logging Transaction (Saat Update Timbangan)

-- Get SVL and SVH
SELECT SVL, SVH 
FROM Logging_Transaction 
WHERE ID = ?
-- Update value
UPDATE Logging_Transaction 
SET Value_Avg_Old = Value_Avg, 
    Value_Avg = ?, 
    Created_at = ?, 
    Alert_Status = ?, 
    is_Synced = 0 
WHERE ID = ?
-- Get Job info for marking Parameter Set as not synced
SELECT Job_Number, Employee_Name, ClockInDate 
FROM Logging_Transaction 
WHERE ID = ?

Tujuan: Menyimpan nilai lama sebelum update, dan menandai data perlu sync ulang.


Get Logging Transaction Data

-- Untuk Produk Kotor (dengan SV)
SELECT ID, No_Lot, Value_Avg, Value_Avg_Old, Alert_Status 
FROM Logging_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ? 
  AND SV IS NOT NULL 
ORDER BY No_Lot DESC
-- Untuk Produk Bersih/Kemas (tanpa SV)
SELECT ID, No_Lot, Value_Avg, Value_Avg_Old, Alert_Status 
FROM Logging_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ? 
  AND SV IS NULL 
ORDER BY No_Lot DESC

Get Logging Transaction yang NOT OK

SELECT ID, No_Lot, Value_Avg, Value_Avg_Old, Alert_Status 
FROM Logging_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ? 
  AND Alert_Status = 'NOT OK' 
ORDER BY No_Lot DESC

Tujuan: Menampilkan hasil timbangan yang out of specification untuk review.


Get Count Logging Transaction

SELECT ID 
FROM Logging_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ?

Tujuan: Menghitung jumlah lot yang sudah ditimbang.


Query untuk Parameter Set Transaction

Insert Parameter Set Transaction (Start Job Baru)

-- Get data from Epicor_Transaction
SELECT Job_Number, 
       Employee_Id, 
       Plant, 
       Part_Number, 
       Part_Description, 
       Employee_Name, 
       ClockInDate, 
       Isi_Kemasan_C, 
       EAN, 
       SVH_Kemas, 
       SVL_Kemas, 
       SVH_Product, 
       SVL_Product, 
       Unit_Product, 
       Unit_Kemas, 
       Jenis_job, 
       SV_Product, 
       Cavity 
FROM Epicor_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND is_Active = 1
-- Insert to Parameter_Set_Transaction
INSERT INTO Parameter_Set_Transaction 
    (Job_Number, 
     Employee_Id, 
     Plant, 
     Part_Number, 
     Part_Description, 
     Employee_Name, 
     ClockInDate, 
     Isi_Kemasan_C, 
     EAN, 
     SVH_Kemas, 
     SVL_Kemas, 
     SVH_Product, 
     SVL_Product, 
     Unit_Product, 
     Unit_Kemas, 
     Jenis_job, 
     SV_Product, 
     Created_at, 
     is_Finished, 
     is_Synced, 
     Jumlah_Lot, 
     Cavity) 
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

Parameter:


Check if Job Finished

SELECT is_Finished 
FROM Parameter_Set_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ?

Submit Job (Finish Penimbangan)

-- Update as finished
UPDATE Parameter_Set_Transaction 
SET is_synced = 0, 
    is_Finished = 1, 
    jumlah_lot = ? 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ?

Tujuan: Menandai job selesai dan update jumlah lot yang ditimbang.


Synchronize Upload (untuk Job Spesifik)

-- Get Parameter Set Transaction
SELECT Job_Number, 
       Employee_Id, 
       Plant, 
       Part_Number, 
       Part_Description, 
       Employee_Name, 
       ClockInDate, 
       Isi_Kemasan_C, 
       EAN, 
       SVH_Kemas, 
       SVL_Kemas, 
       SVH_Product, 
       SVL_Product, 
       SV_Product, 
       Unit_Product, 
       Unit_Kemas, 
       Jenis_job, 
       Created_at, 
       is_Finished, 
       Jumlah_Lot, 
       Cavity 
FROM Parameter_Set_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ? 
  AND is_Synced = 0
-- Get Logging Transaction (including NOT OK)
SELECT ID, 
       Equipment_ID, 
       Sensor_ID, 
       Sensor_Name, 
       Value_Avg, 
       Value_Min, 
       Value_Max, 
       SV, 
       SVL, 
       SVH, 
       Created_at, 
       Logging_tag, 
       Unit, 
       Job_Number, 
       Part_Number, 
       Employee_ID, 
       Employee_Name, 
       OOS_Count_Low, 
       OOS_Count_High, 
       OOS_Value_Low, 
       OOS_Value_High, 
       No_Lot, 
       Value_Avg_Old, 
       is_Synced, 
       Alert_Status, 
       ClockInDate 
FROM Logging_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ? 
  AND (is_Synced = 0 OR Alert_Status = 'NOT OK')

Catatan: Data dengan status "NOT OK" akan selalu diupload ulang untuk tracking.


Query untuk Window Navigation

Get Active ClockInDate

SELECT ClockInDate 
FROM Epicor_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND is_Active = 1

Get All Job Number (by Jenis Job)

SELECT Job_Number 
FROM Epicor_Transaction 
WHERE Jenis_job = ? 
  AND is_Active = 1

Get All Job Number (Continue/Unfinished)

SELECT pst.Job_Number 
FROM Parameter_Set_Transaction pst 
JOIN Epicor_Transaction et 
    ON pst.Job_Number = et.Job_Number 
    AND pst.Employee_ID = et.Employee_ID 
    AND pst.ClockInDate = et.ClockInDate 
WHERE pst.is_Finished = 0 
  AND et.is_Active = 1

Get Operator Name by Job Number

SELECT Employee_Name 
FROM Epicor_Transaction 
WHERE Job_Number = ? 
  AND is_Active = 1

Get Operator Name (Continue/Unfinished)

SELECT pst.Employee_Name 
FROM Parameter_Set_Transaction pst 
JOIN Epicor_Transaction et 
    ON pst.Job_Number = et.Job_Number 
    AND pst.Employee_ID = et.Employee_ID 
    AND pst.ClockInDate = et.ClockInDate 
WHERE pst.Job_Number = ? 
  AND pst.is_Finished = 0 
  AND et.is_Active = 1

Generate Window 2 Display Data

SELECT ClockInDate, 
       Isi_Kemasan_C, 
       EAN, 
       SVH_Kemas, 
       SVL_Kemas, 
       SVH_Product, 
       SVL_Product, 
       Unit_Product, 
       Unit_Kemas, 
       Jenis_Job 
FROM Epicor_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND is_Active = 1

Display Logic:


Generate Window 2 PK (Produk Kotor) Display Data

SELECT ClockInDate, 
       Isi_Kemasan_C, 
       EAN, 
       SV_Product, 
       Unit_Product, 
       Cavity 
FROM Epicor_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND is_Active = 1

Query untuk Sensor/Equipment Management

Get All Active Sensors

SELECT [Name] 
FROM Sensor 
WHERE is_active = 1

Get Selected Sensor

SELECT Raspi_Equpment_ID, Set_TB_Equpment_ID 
FROM Setting

Set Selected Sensor

UPDATE Setting 
SET Set_TB_Equpment_ID = ?

Get Equipment ID

SELECT Raspi_Equpment_ID 
FROM setting

Get Lot Number

SELECT * 
FROM Logging_Transaction 
WHERE Job_Number = ? 
  AND Employee_Name = ? 
  AND ClockInDate = ?

Tujuan: Menghitung lot number berikutnya dengan len(rows) + 1.


Ringkasan Alur Data

Flow: Download/Sync (Dialog0.Accepted)

  1. sync_with_server() - Download master data (Equipment, Sensor, Job)
  2. upload_data() - Upload data lokal ke server
  3. delete_old_data() - Hapus data lama (>3 hari & sudah sync)
  4. synchronize_download() - Download transaksi dari device lain

Flow: Start Penimbangan Baru

  1. User pilih Job Number & Operator
  2. Check isFinished_Parameter_Set_Transaction()
  3. Jika belum ada, insert_Parameter_Set_Transaction()
  4. Mulai penimbangan

Flow: Penimbangan

  1. Serial port baca data timbangan
  2. Parse data → float value
  3. insert_Logging_Transaction() atau update_Logging_Transaction()
  4. Check SVL/SVH → Set Alert_Status
  5. Auto is_Synced = 0 untuk upload nanti

Flow: Submit/Finish Job

  1. Dialog konfirmasi submit
  2. submit() → Update is_Finished = 1, jumlah_lot
  3. synchronize_upload() → Upload ke server
  4. Kembali ke Window0

Flow: Save (tanpa Submit)

  1. synchronize_upload() → Upload data tanpa finish job
  2. User bisa lanjutkan nanti

Catatan Penting

1. is_Synced Flag

2. is_Finished Flag

3. is_Active Flag

4. Alert Status

5. Value_Avg_Old

6. Cavity (Produk Kotor)

7. Data Retention


API Endpoints yang Dipanggil

1. ServerAPI.GetRaspiByMacAddress(macAddress)

2. ServerAPI.GetEquipmentSensor(plant)

3. ServerAPI.GetEpicorTransaction(plant)

4. ServerAPI.CreateUpdateParameterSetTransaction(obj)

5. ServerAPI.CreateUpdateLoggingTransaction(obj)

6. ServerAPI.GetParameterSetTransaction()

7. ServerAPI.GetLoggingTransaction()


Dibuat: February 2, 2026
Versi: 1.0
Platform: Python 3.9 + PyQt5 + SQLite3