Membuat dan membangun sebuah aplikasi E-Struk offline untuk penjualan

Membuat dan membangun sebuah aplikasi E-Struk offline untuk penjualan

Daftar Isi

Halo sahabat javasetid.com, membangun sebuah bisnis tak luput dari yang namanya transaksi, zaman sekarang ini yang serba digital banyak sekali alat pembayaran yang bisa kita gunakan seperti Qris, Ovo, Dana, Transfer non tunai, nah walaupun demikian bagaimana dengan kita nantinya yang berjualan dan pelanggan tersebut tidak memiliki beberapa aplikasi diatas? otomatis kita harus membuat pembayaran secara manual dan itu memerlukan yang namanya struk.

Pada kesempatan kali saya akan ekspose bagaimana cara membuat aplikasi e-struk lengkap dengan nilai pajaknya dan bisa kamu cetak menggunakan printer biasa atau tanpa dicetak juga bisa,kamu dapat memanfaatkan ini sebagai bukti struk yang sah adapun fitur aplikasi E-Struk ini nantinya ialah sebagai berikut:

Bagian Input data

1. Nama Pemilik

2. Alamat Pemilik

3. Nomor Telepon

4. Nama Barang

5. Harga barang (Rp)

6. Kasir

7. Total yang akan dihitung dengan pajak


Nah Setelah fiturnya sudah kita buat konsepnya maka kita bisa lanjutnya ketahap selanjutnya dimulai dengan membuat projek baru dengan bahasa java dan settingan Android Manifest dimana Sobat bisa tempat kode berikut ini :

AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"

android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Epajakku"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="user"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">

<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

Setelah selesai bagian ini kita lanjut ke bagian MainActivitynya untuk kodenya bisa sobat lihat berikut ini:

MainActivity.java

package com.epajakku;

import android.bluetooth.BluetoothSocket;
import android.content.ContentValues;
import android.content.Intent;
import android.graphics.Paint;
import android.graphics.pdf.PdfDocument;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {

private EditText etNama, etAlamat, etTelepon, etNamaBarang, etHargaBarang, etKasir;
private TextView tvHasil;
private Button btnHitung, btnReset, btnStruk, btnSimpanPDF, btnBagikanWA;

private BluetoothSocket bluetoothSocket;
private OutputStream outputStream;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Inisialisasi View
etNama = findViewById(R.id.etNama);
etAlamat = findViewById(R.id.etAlamat);
etTelepon = findViewById(R.id.etTelepon);
etNamaBarang = findViewById(R.id.etNamaBarang);
etHargaBarang = findViewById(R.id.etHargaBarang);
etKasir = findViewById(R.id.etKasir);
tvHasil = findViewById(R.id.tvHasil);
btnHitung = findViewById(R.id.btnHitung);
btnReset = findViewById(R.id.btnReset);
btnStruk = findViewById(R.id.btnStruk);
btnSimpanPDF = findViewById(R.id.btnSimpanPDF);
btnBagikanWA = findViewById(R.id.btnBagikanWA);

// Tombol Hitung Pajak
btnHitung.setOnClickListener(v -> hitungPajak());

// Tombol Reset
btnReset.setOnClickListener(v -> resetForm());

// Tombol Lihat Struk
btnStruk.setOnClickListener(v -> tampilkanStruk());

// Tombol Simpan ke PDF
btnSimpanPDF.setOnClickListener(v -> simpanStrukKePDF());

// Tombol Bagikan WhatsApp
btnBagikanWA.setOnClickListener(v -> bagikanStruk());

}

private void hitungPajak() {
String namaBarang = etNamaBarang.getText().toString();
String hargaBarangStr = etHargaBarang.getText().toString();

if (namaBarang.isEmpty() || hargaBarangStr.isEmpty()) {
tvHasil.setText("Silakan isi semua data!");
return;
}

double hargaBarang = Double.parseDouble(hargaBarangStr);
double pajak = hargaBarang * 0.00; // 0% pajak
double totalHarga = hargaBarang + pajak;

// Format ke Rupiah
String formatTotal = "Rp " + String.format("%,.2f", totalHarga);

tvHasil.setText("Total Harga Setelah Pajak: " + formatTotal);
}

private void resetForm() {
etNama.setText("");
etAlamat.setText("");
etTelepon.setText("");
etNamaBarang.setText("");
etHargaBarang.setText("");
etKasir.setText("");
tvHasil.setText("Total Harga Setelah Pajak: -");
}

private void tampilkanStruk() {
String struk = generateStruk();
new android.app.AlertDialog.Builder(this)
.setTitle("Struk Pembelian")
.setMessage(struk)
.setPositiveButton("OK", null)
.show();
}

private Uri simpanStrukKePDF() {
String struk = generateStruk();

// **Pilih ukuran sesuai printer thermal**
int pageWidth = 380; // Untuk print 58mm
int pageHeight = 600; // Panjang fleksibel

PdfDocument pdfDocument = new PdfDocument();
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(pageWidth, pageHeight, 1).create();
PdfDocument.Page page = pdfDocument.startPage(pageInfo);

Paint paint = new Paint();
paint.setTextSize(14); // Font lebih kecil agar pas
int x = 20, y = 40;

for (String line : struk.split("\n")) {
page.getCanvas().drawText(line, x, y, paint);
y += 22; // Jarak antar baris lebih rapat
}

pdfDocument.finishPage(page);

String fileName = "Struk__Pembelian_di_toko_javasetid.pdf";
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
values.put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf");
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS);

Uri uri = getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);
try {
OutputStream outputStream = getContentResolver().openOutputStream(uri);
pdfDocument.writeTo(outputStream);
outputStream.close();
pdfDocument.close();
Toast.makeText(this, "Struk disimpan sebagai PDF", Toast.LENGTH_LONG).show();
return uri;
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Gagal menyimpan PDF", Toast.LENGTH_SHORT).show();
return null;
}
}


private void bagikanStruk() {
Uri pdfUri = simpanStrukKePDF(); // Simpan dan dapatkan URI file PDF

if (pdfUri != null) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_STREAM, pdfUri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

try {
startActivity(Intent.createChooser(intent, "Bagikan Struk PDF melalui..."));
} catch (Exception ex) {
Toast.makeText(this, "Tidak ada aplikasi yang mendukung berbagi PDF", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Gagal membuat file PDF", Toast.LENGTH_SHORT).show();
}
}


private String generateStruk() {
String namaToko = "TOKO JAVASETID"; // 🏪 Ganti dengan nama toko Anda
String alamatToko = "Jl. Gunung Leuser Nomor 2, Tebing TInggi"; // 📌 Alamat toko

String namaPemilik = etNama.getText().toString();
String alamat = etAlamat.getText().toString();
String telepon = etTelepon.getText().toString();
String namaBarang = etNamaBarang.getText().toString();
String hargaBarangStr = etHargaBarang.getText().toString();
String namaKasir = etKasir.getText().toString(); // Tambahkan nama kasir

if (namaPemilik.isEmpty() || alamat.isEmpty() || telepon.isEmpty() ||
namaBarang.isEmpty() || hargaBarangStr.isEmpty() || namaKasir.isEmpty()) {
return "Silakan isi semua data!";
}

// Ambil tanggal pembelian
String tanggalPembelian = new SimpleDateFormat("dd/MM/yyyy HH:mm", Locale.getDefault()).format(new Date());

double hargaBarang = Double.parseDouble(hargaBarangStr);
double pajak = hargaBarang * 0.00;
double totalHarga = hargaBarang + pajak;

return
"================================\n" +
" " + namaToko + " \n" +
" " + alamatToko + " \n" +
"================================\n" +
"Tanggal : " + tanggalPembelian + "\n" +
"Kasir : " + namaKasir + "\n" +
"--------------------------------\n" +
"Nama Pemilik: " + namaPemilik + "\n" +
"Alamat : " + alamat + "\n" +
"Telepon : " + telepon + "\n" +
"--------------------------------\n" +
"Nama Barang : " + namaBarang + "\n" +
"Harga Barang: Rp " + String.format("%,.0f", hargaBarang) + "\n" +
"Pajak (0%) : Rp " + String.format("%,.0f", pajak) + "\n" +
"Total Harga : Rp " + String.format("%,.0f", totalHarga) + "\n" +
"================================\n" +
" TERIMA KASIH TELAH BERBELANJA! \n" +
"================================";
}
}

Nah, setelah selesai bagian ini, kita lanjut ke bagian Activity_main.xml nya, dengan codingan sebagai berikut:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="20dp">

<!-- Identitas Pemilik -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nama Pemilik">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etNama"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Alamat Pemilik">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etAlamat"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nomor Telepon">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etTelepon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone"/>
</com.google.android.material.textfield.TextInputLayout>

<!-- Deskripsi Pembelian -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Nama Barang">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etNamaBarang"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Harga Barang (Rp)">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etHargaBarang"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"/>
</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Kasir">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/etKasir"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>

<!-- Tombol Aksi -->
<com.google.android.material.button.MaterialButton
android:id="@+id/btnHitung"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hitung Pajak"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"/>

<TextView
android:id="@+id/tvHasil"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Total Harga Setelah Pajak: -"
android:textSize="16sp"
android:textStyle="bold"
android:gravity="center"
android:paddingTop="10dp"
android:textColor="@color/black"/>

<com.google.android.material.button.MaterialButton
android:id="@+id/btnReset"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Reset"
android:backgroundTint="@color/red"/>

<com.google.android.material.button.MaterialButton
android:id="@+id/btnStruk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Lihat Struk"/>

<com.google.android.material.button.MaterialButton
android:id="@+id/btnSimpanPDF"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Simpan Struk ke PDF"/>

<com.google.android.material.button.MaterialButton
android:id="@+id/btnBagikanWA"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Bagikan Struk"/>


</LinearLayout>
</ScrollView>


Tambahkan bagian color di values sesuai dengan keinginan, untuk layoutnya kurang lebih seperti ini

Tampilan Layout Aplikasi E-Struk

Tampila E-Struk Penjualan


Untuk Settingan besarnya pajak, sobat bisa rubah di bagian coding MainActivity.java, carilah codingan 0.00 - 0.05 yang berkaitan dengan pajak untuk settingan nilai pajak sobat tinggal pilih saja dan terapkan,untuk besaran pajak PPN sebagai berikut:


Sejarah PPN di Indonesia

PPN pertama kali diperkenalkan di Indonesia pada tahun 1984 melalui Undang-Undang Nomor 8 Tahun 1983, menggantikan Pajak Penjualan. Sejak saat itu, PPN menjadi salah satu sumber pendapatan utama negara. Peraturan mengenai PPN terus diperbarui, termasuk penyesuaian tarif dan perluasan objek pajak untuk menyesuaikan dengan dinamika ekonomi.

Perbandingan PPN dengan Negara Tetangga

Indonesia menetapkan tarif PPN sebesar 11%, yang lebih tinggi dibandingkan Malaysia dan Singapura. Malaysia sebelumnya menerapkan GST dengan tarif 6%, namun kemudian kembali ke sistem SST dengan tarif 5% hingga 10%.

Di Singapura, GST diberlakukan dengan tarif 7%, dan rencananya akan naik menjadi 9%. Perbandingan ini menunjukkan bahwa tarif PPN Indonesia berada pada tingkat menengah dibandingkan negara-negara tetangga​
Tarif PPN Berapa Persen?

Berdasarkan Pasal 7 Undang Undang Nomor 42 Tahun 2009 tentang Perubahan Ketiga Atas UU Nomor 8 Tahun 1983 tentang PPN dan PPnBM (Pajak Penjualan Atas Barang Mewah), tarif PPN normal di Indonesia yang berlaku adalah 10%.

Namun besar tarif PPN ini bisa diubah paling rendah 5% dan paling banyak 15% yang perubahannya diatur lagi dalam Peraturan Pemerintah (PP).

Tarif Baru PPN Berapa Persen?

Besar tarif pajak penghasilan 10% berlaku selama bertahun-tahun sejak diterbitkannya UU PPN.

Melalui Undang-Undang No. 7 Tahun 2021 tentang Harmonisasi Peraturan Perpajakan (UU HPP), pemerintah telah menaikkan tarif PPN secara bertahap. Tarif PPN terbaru 11% mulai April 2022, kemudian rencananya akan dinaikkan lagi menjadi sebesar 12% pada 2025. Sesuai dengan definisi PPN di atas, maka setiap barang dan/atau jasa yang menjadi objek Pajak Pertambahan Nilai, akan dikenakan pajak PPN dengan tarif PPN terbaru tersebut. 

Nah setelah mengetahui hal diatas kamu sudah bisa buat, dengan menyesuaikan aturan yang ada, eits jangan lupa keuntungan perusahaanmu harus kamu pertimbangkan juga ya.


Cara setting code ini :

Setelah kamu mendapatkan source codenya, ikuti panduan berikut ini

a. Rubah nama tokomu di bagian MainActivity

b. Rubah nilai pajak pada codingan 0.00 - 0.05

c. Build aplikasi dan selamat mencoba


Apakah SOURCE Ini dijual?

Tentu saja jika sobat tertarik ingin mencoba langsung tanpa coding manual bisa kamu japri melalui instagram atau whatsApp, untuk harga sc ini kita hargai cuma Rp.50.000,00 saja, 

Untuk demo aplikasi bisa kamu donwload dan coba disini.

Posting Komentar