233 lines
10 KiB
TypeScript
233 lines
10 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { BackHandler } from 'react-native';
|
|
import { View, Text, StyleSheet, TouchableOpacity, ScrollView } from 'react-native';
|
|
import { WebView } from 'react-native-webview';
|
|
import { useFocusEffect } from 'expo-router';
|
|
|
|
const InvoiceScreen = ({ navigation, cfg }:any) => {
|
|
|
|
let html = '';
|
|
function formatNumber(number: any) {
|
|
return number.toLocaleString('id-ID', {
|
|
minimumFractionDigits: 2,
|
|
maximumFractionDigits: 2
|
|
});
|
|
}
|
|
|
|
const [order] = cfg && cfg.invoice && cfg.invoice.sales_order ? cfg.invoice.sales_order:[];
|
|
if(order){
|
|
const orderLine: any = cfg.invoice.sales_order_line;
|
|
const [cus] = cfg.dataPilihan.customer.filter((s: any) => s.id == order.partner_id)
|
|
console.log(order)
|
|
const uom: any = {
|
|
'27': 'PCS',
|
|
'28': 'SLOP',
|
|
'29': 'BAL',
|
|
'30': 'DOS',
|
|
|
|
}
|
|
html = `
|
|
<html>
|
|
<head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
|
<title></title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
</head>
|
|
<body class="p-[20px]">
|
|
<div class="rounded-md bg-white p-[20px] min-h-[calc(100%)]">
|
|
<div class="grid grid-cols-1 text-gray-600 font-semibold gap-4 mb-5">
|
|
<div>
|
|
<h1 class="text-2xl font-bold">CV. KBS</h1>
|
|
<p class="text-sm mb-3">Jl. Mangga No 10, DENPASAR</p>
|
|
|
|
<div class="grid text-gray-600 font-semibold gap-4" style="grid-template-columns: 130px 5px auto">
|
|
<h1 class="text-sm">${(`sales order`).toUpperCase()}</h1>
|
|
<span class="text-sm">:</span>
|
|
<h1 class="text-sm font-bold">${order?.name}</h1>
|
|
</div>
|
|
<div class="grid text-gray-600 font-semibold gap-4" style="grid-template-columns: 130px 5px auto">
|
|
<h1 class="text-sm">Tanggal & Jam</h1>
|
|
<span class="text-sm">:</span>
|
|
<h1 class="text-sm">${order.write_date != 'timestamp' ? order.write_date : cfg.invoice.times}</h1>
|
|
</div>
|
|
<div class="grid text-gray-600 font-semibold gap-4" style="grid-template-columns: 130px 5px auto">
|
|
<h1 class="text-sm">Kode Sales</h1>
|
|
<span class="text-sm">:</span>
|
|
<h1 class="text-sm">${order?.client_order_ref}</h1>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-1 text-gray-600 font-semibold gap-4">
|
|
<div>
|
|
<h1 class="text-md">Customer</h1>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<div class="grid grid-cols-1 text-gray-600 font-semibold gap-4 mb-6">
|
|
<div>
|
|
<div class="grid text-gray-600 font-semibold gap-4" style="grid-template-columns: 130px 5px auto">
|
|
<h1 class="text-sm">Nama</h1>
|
|
<span class="text-sm">:</span>
|
|
<h1 class="text-sm">${cus.name ? cus.name : '-'}</h1>
|
|
</div>
|
|
<div class="grid text-gray-600 font-semibold gap-4" style="grid-template-columns: 130px 5px auto">
|
|
<h1 class="text-sm">Alamat</h1>
|
|
<span class="text-sm">:</span>
|
|
<h1 class="text-sm">${cus.street?cus.street:'-'}</h1>
|
|
</div>
|
|
<div class="grid text-gray-600 font-semibold gap-4" style="grid-template-columns: 130px 5px auto">
|
|
<h1 class="text-sm">No. Telp</h1>
|
|
<span class="text-sm">:</span>
|
|
<h1 class="text-sm">${cus.phone?cus.phone:'-'}</h1>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table class="w-full">
|
|
<tr class="border-b-2">
|
|
<th class="text-sm text-left">Produk</th>
|
|
<th class="text-sm text-right w-[40px]">Qty</th>
|
|
<th class="text-sm text-right w-[150px]">Harga satuan</th>
|
|
<th class="text-sm text-right w-[150px]">Nominal</th>
|
|
</tr>
|
|
${(function (d: any) {
|
|
console.log(d)
|
|
return d.map(function (n: any) {
|
|
return `
|
|
<tr class="border-b-2">
|
|
<td class="text-sm text-left">${n?.name}</td>
|
|
<td class="text-sm text-right">${n?.product_uom_qty} ${uom[n?.product_uom]}</td>
|
|
<td class="text-sm text-right">${formatNumber(n?.price_unit)}</td>
|
|
<td class="text-sm text-right">Rp ${formatNumber(n?.price_subtotal)}</td>
|
|
</tr>
|
|
`
|
|
}).join('')
|
|
})(orderLine)}
|
|
</table>
|
|
<div class="grid mt-5" class="grid" style="grid-template-columns: 100px auto">
|
|
<div></div>
|
|
<div class="grid" style="border-bottom:1px solid #ddd;grid-template-columns: 180px auto">
|
|
<div class="text-sm font-bold">Jumlah Sebelum Pajak</div>
|
|
<div class="text-sm text-right">Rp ${formatNumber(order?.amount_untaxed)}</div>
|
|
</div>
|
|
</div>
|
|
<div class="grid" class="grid" style="grid-template-columns: 100px auto">
|
|
<div></div>
|
|
<div class="grid" style="border-bottom:1px solid #ddd;grid-template-columns: 180px auto">
|
|
<div class="text-sm">Pajak</div>
|
|
<div class="text-sm text-right">Rp ${formatNumber(order?.amount_total - order?.amount_untaxed)}</div>
|
|
</div>
|
|
</div>
|
|
<div class="grid" class="grid" style="grid-template-columns: 100px auto">
|
|
<div></div>
|
|
<div class="grid" style="border-bottom:1px solid #ddd;grid-template-columns: 180px auto">
|
|
<div class="text-sm font-bold">Total</div>
|
|
<div class="text-sm text-right">Rp ${formatNumber(order?.amount_total)}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
|
|
`;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<View style={{ flexDirection: "column", height: "100%" }}>
|
|
<View style={{ flexDirection: "row", justifyContent: "center", alignItems: "flex-end", height: 80, backgroundColor: "white" }}>
|
|
<Text style={{
|
|
fontSize: 20,
|
|
fontWeight: "700",
|
|
paddingVertical: 10
|
|
}}>INVOICE</Text>
|
|
</View>
|
|
<View style={{ flex: 1 }}>
|
|
<WebView
|
|
originWhitelist={["*"]}
|
|
source={{ html: html }}
|
|
style={{ backgroundColor: 'lightgray' }}
|
|
/>
|
|
</View>
|
|
<View style={{ flexDirection: "row", height: 80, backgroundColor: "white" }}>
|
|
<TouchableOpacity style={[styles.button, {
|
|
flex: 1
|
|
, flexDirection: "row"
|
|
, justifyContent: "center"
|
|
, alignItems: "center"
|
|
}]}>
|
|
<Text style={styles.buttonText}>Cetak Invoice</Text>
|
|
</TouchableOpacity>
|
|
<TouchableOpacity style={[styles.button, {
|
|
flex: 1
|
|
, flexDirection: "row"
|
|
, justifyContent: "center"
|
|
, alignItems: "center"
|
|
}]}>
|
|
<Text style={styles.buttonText}>Kirim Invoice</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
</View>
|
|
</>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
title: {
|
|
fontSize: 32,
|
|
fontWeight: 'bold',
|
|
marginVertical: 10,
|
|
},
|
|
date: {
|
|
fontSize: 16,
|
|
color: '#888',
|
|
marginBottom: 20,
|
|
},
|
|
info: {
|
|
marginBottom: 20,
|
|
},
|
|
infoText: {
|
|
fontSize: 16,
|
|
marginBottom: 5,
|
|
},
|
|
divider: {
|
|
borderBottomColor: '#000',
|
|
borderBottomWidth: 1,
|
|
marginVertical: 10,
|
|
},
|
|
itemRow: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
marginVertical: 5,
|
|
},
|
|
itemText: {
|
|
fontSize: 18,
|
|
},
|
|
itemTextSatuan: {
|
|
fontSize: 18,
|
|
textAlign: 'center'
|
|
},
|
|
totalRow: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
marginVertical: 10,
|
|
},
|
|
totalText: {
|
|
fontSize: 24,
|
|
fontWeight: 'bold',
|
|
},
|
|
button: {
|
|
backgroundColor: '#4199d5',
|
|
borderRadius: 8,
|
|
padding: 8,
|
|
alignItems: 'center',
|
|
margin: 10,
|
|
height: 50
|
|
},
|
|
buttonText: {
|
|
color: '#fff',
|
|
fontSize: 18,
|
|
fontWeight: 'bold',
|
|
},
|
|
});
|
|
|
|
export default InvoiceScreen; |