Skip to content

Instantly share code, notes, and snippets.

@jafar260698
Created September 4, 2025 11:07
Show Gist options
  • Select an option

  • Save jafar260698/f9ed1b7c2beced34eba272086b280dea to your computer and use it in GitHub Desktop.

Select an option

Save jafar260698/f9ed1b7c2beced34eba272086b280dea to your computer and use it in GitHub Desktop.
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pos_system/utils/app_date_utils.dart';
import 'package:pos_system/utils/app_utils.dart';
import 'package:pos_system/utils/logger/write_log.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:shelf/shelf.dart';
import 'package:uuid/uuid.dart';
import 'core/services/locator.dart';
import 'data/models/front_office_model.dart';
import 'data/pos_data/fiscal_drive/fiscal_drive_receipt.dart';
import 'data/pos_data/receipt_item.dart';
import 'data/user_data.dart';
import 'domain/network/api_provider.dart';
import 'domain/persistance/db/virtual_cash_db.dart';
import 'package:drift/drift.dart' as drift;
import 'dart:ui' as ui;
class SendReceiptFrontOffice {
SendReceiptFrontOffice._();
static final instance = SendReceiptFrontOffice._();
static Future<Response> sendReceipt(Request request) async {
try {
final body = await request.readAsString();
final saleData = FrontOfficeModel.fromJson(jsonDecode(body));
final apiProvider = locator<ApiProvider>();
final userData = locator<UserData>();
final VirtualCashDb virtualCashDb = locator<VirtualCashDb>();
bool existIntegrationID = await virtualCashDb.integrationIdExists(saleData.transactionId ?? "");
WriteLOG.writeLog("IntegrationID: ${saleData.transactionId}; $existIntegrationID;");
if (existIntegrationID) {
var cheque = await virtualCashDb.getChequeByIntegrationId(saleData.transactionId ?? "");
var sendToBackend = await virtualCashDb.getSendToBackendStatus(cheque?.receiptId ?? "");
if(sendToBackend == 1) {
var result = await apiProvider.sendSingleReceiptWithoutContext(cheque?.receiptId ?? "");
if (result.data != null) {
var htmlData = await generateChequeHTMLByIntegration(result.data!);
return Response.ok(
jsonEncode({
'success': true,
'reason': '',
'html': htmlData
}));
} else {
return Response(
400,
body: jsonEncode({
'success': false,
'reason': 'Fiskal modul bilan yuborishda xatolik:',
}),
headers: {'Content-Type': 'application/json'},
);
}
} else {
var hasSmena = await userData.getSmenaStatus();
if (hasSmena ?? false) {
try {
Map<String, dynamic> paramsSaleReceipt = HashMap();
var currentTime = getCurrentDate();
var randomNum = AppUtils.getRandomNumber();
var fiscalId = await userData.getFiscalId();
var receiptList = [];
for (var element in saleData.invoiceDataItems ?? []) {
InvoiceDataItems invoiceDataItems = element;
receiptList.add(
{
"Discount": invoiceDataItems.discount,
"Name": invoiceDataItems.productName,
"Barcode": invoiceDataItems.barcode ?? "",
"PackageCode": invoiceDataItems.units.toString(),
"SPIC": invoiceDataItems.classCode,
"OwnerType": 2,
"Amount": (invoiceDataItems.count ?? 0) * 1000,
"Label": "",
"Price": invoiceDataItems.price!.toInt() *
invoiceDataItems.count! * 100,
"Units": invoiceDataItems.units,
"VAT": invoiceDataItems.vatPercent,
"VATPercent": invoiceDataItems.vatPercent,
"CommissionInfo": {
"PINFL": invoiceDataItems.commissionPinfl ?? "",
"TIN": invoiceDataItems.comissionTin ?? ""
},
"Other": 0
}
);
}
paramsSaleReceipt = {
"method": "Api.SendSaleReceipt",
"id": randomNum,
"params": {
"FactoryID": fiscalId,
"Receipt": {
"ReceivedCash": saleData.paymentTypeId == 1 ? (saleData
.totalSum! * 100) : 0,
"Time": currentTime,
"Items": receiptList,
"ReceivedCard": saleData.paymentTypeId == 2 ? (saleData
.totalSum! * 100) : 0,
"Location": {
"Latitude": await userData.getLatitude(),
"Longitude": await userData.getLongitude(),
},
}
},
"jsonrpc": "2.0"
};
var response = await apiProvider
.sendReceiptFiscalDriveWithoutContext(paramsSaleReceipt);
if (response != null && response.result != null) {
return sendReceiptsBackend(response.result!, saleData);
} else {
return Response(
400,
body: jsonEncode({
'success': false,
'reason': 'Fiskal modul bilan yuborishda xatolik: ${response
.error?.message}', // Custom error message
}),
headers: {'Content-Type': 'application/json'},
);
}
} catch (e) {
WriteLOG.writeLog(e.toString());
return Response(
400, // HTTP status code for "Bad Request"
body: jsonEncode({
'success': false,
'reason': 'Server bilan xatolik: $e',
}),
headers: {'Content-Type': 'application/json'},
);
}
} else {
return Response(
400, // HTTP status code for "Bad Request"
body: jsonEncode({
'success': false,
'reason': 'Virtual Kassada Smena ochilmagan:',
// Custom error message
}),
headers: {'Content-Type': 'application/json'},
);
}
}
} else {
var hasSmena = await userData.getSmenaStatus();
if (hasSmena ?? false) {
try {
Map<String, dynamic> paramsSaleReceipt = HashMap();
var currentTime = getCurrentDate();
var randomNum = AppUtils.getRandomNumber();
var fiscalId = await userData.getFiscalId();
var receiptList = [];
for (var element in saleData.invoiceDataItems ?? []) {
InvoiceDataItems invoiceDataItems = element;
receiptList.add(
{
"Discount": invoiceDataItems.discount,
"Name": invoiceDataItems.productName,
"Barcode": invoiceDataItems.barcode ?? "",
"PackageCode": invoiceDataItems.units.toString(),
"SPIC": invoiceDataItems.classCode,
"OwnerType": 2,
"Amount": (invoiceDataItems.count ?? 0) * 1000,
"Label": "",
"Price": invoiceDataItems.price!.toInt() *
invoiceDataItems.count! * 100,
"Units": invoiceDataItems.units,
"VAT": invoiceDataItems.vatPercent,
"VATPercent": invoiceDataItems.vatPercent,
"CommissionInfo": {
"PINFL": invoiceDataItems.commissionPinfl ?? "",
"TIN": invoiceDataItems.comissionTin ?? ""
},
"Other": 0
}
);
}
paramsSaleReceipt = {
"method": "Api.SendSaleReceipt",
"id": randomNum,
"params": {
"FactoryID": fiscalId,
"Receipt": {
"ReceivedCash": saleData.paymentTypeId == 1 ? (saleData
.totalSum! * 100) : 0,
"Time": currentTime,
"Items": receiptList,
"ReceivedCard": saleData.paymentTypeId == 2 ? (saleData
.totalSum! * 100) : 0,
"Location": {
"Latitude": await userData.getLatitude(),
"Longitude": await userData.getLongitude(),
},
}
},
"jsonrpc": "2.0"
};
var response = await apiProvider
.sendReceiptFiscalDriveWithoutContext(paramsSaleReceipt);
if (response != null && response.result != null) {
return sendReceiptsBackend(response.result!, saleData);
} else {
return Response(
400,
body: jsonEncode({
'success': false,
'reason': 'Fiskal modul bilan yuborishda xatolik: ${response
.error?.message}', // Custom error message
}),
headers: {'Content-Type': 'application/json'},
);
}
} catch (e) {
WriteLOG.writeLog(e.toString());
return Response(
400, // HTTP status code for "Bad Request"
body: jsonEncode({
'success': false,
'reason': 'Fiskal modul bilan yuborishda xatolik: $e',
// Custom error message
}),
headers: {'Content-Type': 'application/json'},
);
}
} else {
return Response(
400, // HTTP status code for "Bad Request"
body: jsonEncode({
'success': false,
'reason': 'Virtual Kassada Smena ochilmagan:',
// Custom error message
}),
headers: {'Content-Type': 'application/json'},
);
}
}
} catch(error) {
WriteLOG.writeLog(error.toString());
return Response(
400,
body: jsonEncode({
'success': false,
'reason': 'Xatolik: ${error}',
}),
headers: {'Content-Type': 'application/json'},
);
}
}
static Future<Response> sendReceiptsBackend(
FiscalDriveReceiptResult fiscalDriveReceiptResult,
FrontOfficeModel frontOfficeModel) async {
try {
var currentTime = getCurrentDate();
var receiptList = [];
var ofdDateTime = getCustomDate(fiscalDriveReceiptResult.dateTime ?? "");
final VirtualCashDb virtualCashDb = locator<VirtualCashDb>();
final apiProvider = locator<ApiProvider>();
final userData = locator<UserData>();
var receiptId = const Uuid().v1();
var companyId = (await userData.getCompanyId()) ?? "";
var userId = (await userData.getUserId()) ?? "";
var smenaId = (await userData.getSmenaId()) ?? "";
var cashboxId = await userData.getCashboxId() ?? "";
for (var element in frontOfficeModel.invoiceDataItems!) {
InvoiceDataItems invoiceDataItems = element;
var receiptItemsId = const Uuid().v1();
receiptList.add(
{
"commission_pinfl": invoiceDataItems.commissionPinfl ?? "",
"commission_tin": invoiceDataItems.comissionTin ?? "",
"discount_sum": invoiceDataItems.discount,
"discount_value": 0,
"discount_type": "no_discount",
"product_name": invoiceDataItems.productName,
"product_barcode": invoiceDataItems.barcode! ?? "",
"product_class_code": invoiceDataItems.classCode,
"product_class_name": invoiceDataItems.className,
"product_id": invoiceDataItems.productId.toString(),
"product_mxik_code": invoiceDataItems.classCode,
"receipt_item_id": receiptItemsId,
"sale_count": invoiceDataItems.count,
"sale_price": invoiceDataItems.price,
"total_price": invoiceDataItems.totalPrice,
"vat_percent": invoiceDataItems.vatPercent,
"vat_sum": invoiceDataItems.vatSum,
"product_package_code": invoiceDataItems.units.toString(),
"owner_type": 2,
"product_type": 2,
}
);
var salesProduct = SoldProductEntityCompanion(
commissionPinfl: drift.Value(invoiceDataItems.commissionPinfl ?? ""),
commissionTin: drift.Value(invoiceDataItems.comissionTin ?? ""),
discountValue: const drift.Value.absentIfNull(0),
discountSum: const drift.Value.absentIfNull(0),
discountType: const drift.Value.absentIfNull("no_discount"),
productName: drift.Value.absentIfNull(invoiceDataItems.productName),
productBarcode: drift.Value.absentIfNull(invoiceDataItems.barcode),
productClassCode: drift.Value.absentIfNull(
invoiceDataItems.classCode),
productClassName: drift.Value.absentIfNull(
invoiceDataItems.className),
productId: drift.Value.absentIfNull(
invoiceDataItems.productId.toString()),
productMxikCode: drift.Value.absentIfNull(
invoiceDataItems.classCode),
receiptItemId: drift.Value.absentIfNull(receiptItemsId),
saleCount: drift.Value(invoiceDataItems.count?.toDouble()),
salePrice: drift.Value(invoiceDataItems.price?.toDouble()),
totalPrice: drift.Value(invoiceDataItems.totalPrice?.toDouble()),
vatPercent: drift.Value(invoiceDataItems.vatPercent),
vatSum: const drift.Value(0),
chequeId: drift.Value(receiptId),
hasMarking: const drift.Value(0),
markingCode: const drift.Value(""),
ownerType: const drift.Value(2),
productType: const drift.Value(2),
packageCode: drift.Value.absentIfNull(invoiceDataItems.units.toString()),
);
virtualCashDb.insertSoldProduct(salesProduct);
}
var paymentTypeList = [];
var paymentDateId = const Uuid().v1();
// 1 - Naqd, 2 Plastik
var paymentTypeID = "";
if (frontOfficeModel.paymentTypeId == 1) {
paymentTypeID = "e0b691e1-3f78-4bf3-816f-e50b2f9e8e5f";
} else if (frontOfficeModel.paymentTypeId == 2) {
paymentTypeID = "f4f47104-662f-4e20-92cf-56cbf71d206d";
}
paymentTypeList.add({
"amount": frontOfficeModel.totalSum,
"pay_sum": frontOfficeModel.totalPaySum,
"payment_data_id": paymentDateId,
"payment_type_id": paymentTypeID,
"provider_id": "",
});
var paymentDate = PaymentDateEntityCompanion(
paySum: drift.Value(frontOfficeModel.totalPaySum!.toDouble()),
paymentDataId: drift.Value(paymentDateId),
paymentTypeId: drift.Value(paymentTypeID),
chequeId: drift.Value(receiptId)
);
virtualCashDb.insertPaymentDate(paymentDate);
//
var totalReceivedCash = frontOfficeModel.paymentTypeId == 1
? frontOfficeModel.totalPaySum!
: 0.0;
var totalReceivedCard = frontOfficeModel.paymentTypeId != 1
? frontOfficeModel.totalPaySum!
: 0.0;
var list = [
{
"cashback": 0,
"cashbox_id": cashboxId,
"company_id": companyId,
"created_date": currentTime,
"total_discount_sum": 0,
"ofd_date_time": ofdDateTime,
"ofd_fiscal_sign": fiscalDriveReceiptResult.fiscalSign,
"ofd_qr_code_url": fiscalDriveReceiptResult.qRCodeURL,
"ofd_receipt_sequence_number": int.parse(fiscalDriveReceiptResult.receiptSeq ?? "0"),
"ofd_terminal_id": fiscalDriveReceiptResult.terminalID,
"payment_data": paymentTypeList,
"receipt_id": receiptId,
"receipt_items": receiptList,
"receipt_type": "sale",
"sale_day_id": smenaId,
"send_ofd_status": true,
"total_pay": frontOfficeModel.totalPaySum!,
"total_sum": frontOfficeModel.totalSum!,
"total_vat_sum": frontOfficeModel.vatSum,
"user_id": userId,
"total_received_cash": totalReceivedCash,
"total_received_card": totalReceivedCard,
"app_version": await AppUtils.initVersion()
}
];
var chequeItem = ChequeEntityCompanion(
cashback: const drift.Value(0),
cashboxId: drift.Value(cashboxId),
companyId: drift.Value(companyId),
createdDate: drift.Value(currentTime),
discountSum: const drift.Value(0),
ofdDateTime: drift.Value(ofdDateTime),
ofdFiscalSign: drift.Value(fiscalDriveReceiptResult.fiscalSign),
ofdQrCodeUrl: drift.Value(fiscalDriveReceiptResult.qRCodeURL),
ofdReceiptSequenceNumber: drift.Value(fiscalDriveReceiptResult.receiptSeq),
ofdTerminalId: drift.Value(fiscalDriveReceiptResult.terminalID),
receiptId: drift.Value(receiptId),
receiptType: const drift.Value("sale"),
saleDayId: drift.Value(smenaId),
sendOfdStatus: const drift.Value(1),
totalPay: drift.Value(frontOfficeModel.totalPaySum?.toDouble()),
totalSum: drift.Value(frontOfficeModel.totalSum?.toDouble() ?? 0),
totalVatSum: drift.Value(frontOfficeModel.vatSum?.toDouble()),
userId: drift.Value(userId),
senToBackend: const drift.Value(0),
totalReceivedCard: drift.Value(totalReceivedCard.toDouble()),
totalReceivedCash: drift.Value(totalReceivedCash.toDouble()),
isIntegration: const drift.Value(1),
integrationId: drift.Value(frontOfficeModel.transactionId),
);
await virtualCashDb.insertChequeFrontOffice(chequeItem, frontOfficeModel.transactionId ?? "");
var result = await apiProvider.sendReceiptWithoutContext(list);
if (result.data != null) {
virtualCashDb.updateSingleRow(receiptId, 1);
}
var htmlData = await generateChequeHTML(fiscalDriveReceiptResult, frontOfficeModel);
return Response.ok(
jsonEncode({
'success': true,
'reason': '',
'html': htmlData
}),
headers: {'Content-Type': 'application/json'},
);
} catch (e) {
WriteLOG.writeLog("Debug error2 $e");
return Response(
400,
body: jsonEncode({
'success': false,
'reason': 'Serverga yuborishda xatolik: $e', // Custom error message
}),
headers: {'Content-Type': 'application/json'},
);
}
}
static Future<String> generateChequeHTML(
FiscalDriveReceiptResult fiscalDriveReceiptResult,
FrontOfficeModel frontOfficeModel) async {
try {
final UserData userData = locator<UserData>();
var companyStir = (await userData.getCompanyTin()) ?? "";
var companyAddress = (await userData.getCashboxAddress()) ?? "";
var cashier = (await userData.getUserName() ?? "");
var cashboxId = (await userData.getCashboxId());
var versionApp = await AppUtils.initVersion();
// Format Money
String formatMoney(double amount) {
final formatter = NumberFormat.currency(symbol: '', decimalDigits: 2);
return formatter.format(amount);
}
var invoicesDataItems = frontOfficeModel.invoiceDataItems;
// Prepare items in HTML
String chequeItems = "";
for (var item in invoicesDataItems!) {
chequeItems += """
<div style='font-size: 10px'>${item.productName} - ${item.units}</div>
<div style='font-size: 10px;text-align: right;'>${formatMoney(
item.price!.toDouble())} x ${formatMoney(
item.count!.toDouble())} = ${formatMoney(
item.totalPrice!.toDouble())}</div>
<div style='font-size: 10px;'>QQS - ${item.vatPercent}%</div>
<div style='font-size: 10px;'>MXIK: ${item.classCode}</div>
<div style='font-size: 10px;'>Shtrix kod: ${item.barcode}</div>
""";
}
// Generate QR code
String qrCodeImage = await generateBase64QRCode(fiscalDriveReceiptResult.qRCodeURL!);
// HTML content
String htmlContent = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
@page {
margin: 0;
}
body { font-family: Arial, sans-serif; margin:0; padding: 0; }
.header { text-align: center; font-size: 12px; }
.row { font-size: 11px; display: flex; justify-content: space-between; }
.divider { border-top: 1px solid black; margin: 10px 0; }
.qr-code {
padding: 10px;
}
img {
width: 150px; /* Adjust size as needed */
height: 150px;
object-fit: contain;
}
</style>
</head>
<body>
<div class="header">
<h4 style="text-align:center">O’zbekiston Respublikasi Vazirlar Mahkamasi huzuridagi Soliq-Servis DUK</h4>
<p>$companyAddress</p>
</div>
<hr class="divider"/>
<div class="row">
<span>STIR:</span>
<span>$companyStir</span>
</div>
<div class="row">
<span>Sana:</span>
<span>${getCustomDate(fiscalDriveReceiptResult.dateTime!)}</span>
</div>
<div class="row">
<span>Chek raqami:</span>
<span>${fiscalDriveReceiptResult.receiptSeq}</span>
</div>
<div class="row">
<span>Kassir:</span><span>$cashier</span>
</div>
<div class="divider"></div>
<!-- Invoice Items -->
$chequeItems
<div class="divider"></div>
<div class="row" style="font-size: 13px; font-weight: bold;">
<span>Jami:</span>
<span>${formatMoney(frontOfficeModel.totalSum!.toDouble())}</span>
</div>
<div class="row">
<span>QQS:</span>
<span>${formatMoney(frontOfficeModel.vatSum!.toDouble())}</span>
</div>
<div class="row" style="font-size: 12px; font-weight: bold;">
<span>To'lov:</span>
<span>${formatMoney(frontOfficeModel.totalPaySum!.toDouble())}</span>
</div>
<hr class="divider"/>
<div class="row">
<span>Naqd:</span>
<span>${frontOfficeModel.paymentTypeId == 1 ? formatMoney(frontOfficeModel.totalSum!.toDouble()) : 0.0}</span>
</div>
<div class="row">
<span>Karta orqali:</span>
<span>${frontOfficeModel.paymentTypeId == 2 ? formatMoney(frontOfficeModel.totalSum!.toDouble()) : 0.0}</span>
</div>
<div class="row">
<span>Qaytim:</span>
<span>${formatMoney(0.0)}</span>
</div>
<div class="divider" style="border-top: 2px dashed black;"></div>
<div style="text-align: center; font-weight: bold;">
Fiskal ma'lumotlar
</div>
<div class="row" style="font-size: 11px; font-weight: bold;">
<span>Virtual Kassa $versionApp version</span><span></span>
</div>
<div class="row" style="font-size: 11px;">
<span>$cashboxId</span><span></span>
</div>
<div class="row" style="font-size: 11px; font-weight: bold;">
<span>FM raqami:</span><span>${fiscalDriveReceiptResult.terminalID}</span>
</div>
<div class="row" style="font-size: 11px; font-weight: bold;">
<span>Chek raqami:</span><span>${fiscalDriveReceiptResult.receiptSeq}</span>
</div>
<div class="row" style="font-size: 11px; font-weight: bold;">
<span>Fiskal belgi:</span><span>${fiscalDriveReceiptResult.fiscalSign}</span>
</div>
<div class="qr-code">
<img src='data:image/png;base64,$qrCodeImage' alt='QR Code'>
</div>
</body>
</html>
""";
// Saving the HTML content to a file
final directory = await getApplicationDocumentsDirectory();
final filePath = '${directory.path}/receipt.html';
final file = File(filePath);
await file.writeAsString(htmlContent);
return htmlContent;
} catch (e) {
WriteLOG.writeLog(e.toString());
return "";
}
}
static Future<String> generateChequeHTMLByIntegration(ReceiptData receiptData) async {
try {
final UserData userData = locator<UserData>();
var companyStir = (await userData.getCompanyTin()) ?? "";
var companyAddress = (await userData.getCashboxAddress()) ?? "";
var cashier = (await userData.getUserName() ?? "");
var cashboxId = (await userData.getCashboxId());
var versionApp = await AppUtils.initVersion();
var totalCash = 0.0;
var totalCard = 0.0;
receiptData.paymentData?.forEach((element) {
if(element.paymentTypeId == "e0b691e1-3f78-4bf3-816f-e50b2f9e8e5f"){
totalCash = (element.paySum ?? 0).toDouble();
}
if(element.paymentTypeId == "f4f47104-662f-4e20-92cf-56cbf71d206d"){
totalCard = (element.paySum ?? 0).toDouble();
}
});
// Format Money
String formatMoney(double amount) {
final formatter = NumberFormat.currency(symbol: '', decimalDigits: 2);
return formatter.format(amount);
}
var invoicesDataItems = receiptData.receiptItems;
// Prepare items in HTML
String chequeItems = "";
for (var item in invoicesDataItems!) {
chequeItems += """
<div style='font-size: 10px'>${item.productName} - ${item.productMeasureType}</div>
<div style='font-size: 10px;text-align: right;'>${formatMoney(
item.productSalePrice!.toDouble())} x ${formatMoney(
item.productSaleCount!.toDouble())} = ${formatMoney(
item.productTotalPrice!.toDouble())}</div>
<div style='font-size: 10px;'>QQS - ${item.productVatPercent}%</div>
<div style='font-size: 10px;'>MXIK: ${item.productClassCode}</div>
<div style='font-size: 10px;'>Shtrix kod: ${item.productBarcode}</div>
""";
}
// Generate QR code
String qrCodeImage = await generateBase64QRCode(receiptData.ofdQrCodeUrl!);
// HTML content
String htmlContent = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
@page {
margin: 0;
}
body { font-family: Arial, sans-serif; margin:0; padding: 0; }
.header { text-align: center; font-size: 12px; }
.row { font-size: 11px; display: flex; justify-content: space-between; }
.divider { border-top: 1px solid black; margin: 10px 0; }
.qr-code {
padding: 10px;
}
img {
width: 150px; /* Adjust size as needed */
height: 150px;
object-fit: contain;
}
</style>
</head>
<body>
<div class="header">
<h4 style="text-align:center">O’zbekiston Respublikasi Vazirlar Mahkamasi huzuridagi Soliq-Servis DUK</h4>
<p>$companyAddress</p>
</div>
<hr class="divider"/>
<div class="row">
<span>STIR:</span>
<span>$companyStir</span>
</div>
<div class="row">
<span>Sana:</span>
<span>${getCustomDate(receiptData.ofdDateTime??"")}</span>
</div>
<div class="row">
<span>Chek raqami:</span>
<span>${receiptData.ofdReceiptSeq}</span>
</div>
<div class="row">
<span>Kassir:</span><span>$cashier</span>
</div>
<div class="divider"></div>
<!-- Invoice Items -->
$chequeItems
<div class="divider"></div>
<div class="row" style="font-size: 13px; font-weight: bold;">
<span>Jami:</span>
<span>${formatMoney(receiptData.totalSum!.toDouble())}</span>
</div>
<div class="row">
<span>QQS:</span>
<span>${formatMoney(receiptData.totalVatSum!.toDouble())}</span>
</div>
<div class="row" style="font-size: 12px; font-weight: bold;">
<span>To'lov:</span>
<span>${formatMoney(receiptData.totalPay!.toDouble())}</span>
</div>
<hr class="divider"/>
<div class="row">
<span>Naqd:</span>
<span>${formatMoney(totalCash)}</span>
</div>
<div class="row">
<span>Karta orqali:</span>
<span>${formatMoney(totalCard)}</span>
</div>
<div class="row">
<span>Qaytim:</span>
<span>${formatMoney(0.0)}</span>
</div>
<div class="divider" style="border-top: 2px dashed black;"></div>
<div style="text-align: center; font-weight: bold;">
Fiskal ma'lumotlar
</div>
<div class="row" style="font-size: 11px; font-weight: bold;">
<span>Virtual Kassa $versionApp version</span><span></span>
</div>
<div class="row" style="font-size: 11px;">
<span>$cashboxId</span><span></span>
</div>
<div class="row" style="font-size: 11px; font-weight: bold;">
<span>FM raqami:</span><span>${receiptData.terminalId}</span>
</div>
<div class="row" style="font-size: 11px; font-weight: bold;">
<span>Chek raqami:</span><span>${receiptData.ofdReceiptSeq}</span>
</div>
<div class="row" style="font-size: 11px; font-weight: bold;">
<span>Fiskal belgi:</span><span>${receiptData.ofdFiscalSign}</span>
</div>
<div class="qr-code">
<img src='data:image/png;base64,$qrCodeImage' alt='QR Code'>
</div>
</body>
</html>
""";
// Saving the HTML content to a file
final directory = await getApplicationDocumentsDirectory();
final filePath = '${directory.path}/receipt.html';
final file = File(filePath);
await file.writeAsString(htmlContent);
return htmlContent;
} catch (e) {
WriteLOG.writeLog(e.toString());
return "";
}
}
static Future<String> generateBase64QRCode(String qrCodeURL) async {
try {
// Create the QrPainter object
final qrCodePainter = QrPainter(
data: qrCodeURL,
version: QrVersions.auto,
gapless: true,
);
// Convert the QrPainter to a UI Image
final uiImage = await qrCodePainter.toImage(150); // Size 150x150
// Convert the image to ByteData in PNG format
final byteData = await uiImage.toByteData(format: ui.ImageByteFormat.png);
if (byteData == null) {
throw Exception('Error converting QR code to ByteData');
}
// Convert the ByteData to Uint8List (needed for base64 encoding)
final pngBytes = byteData.buffer.asUint8List();
// Encode the bytes to base64 string
final base64String = base64Encode(pngBytes);
return base64String;
} catch (e) {
WriteLOG.writeLog(e.toString());
return '';
}
}
// API CALLS
static Future<Response> getOverallData(Request request) async {
try {
final VirtualCashDb virtualCashDb = locator<VirtualCashDb>();
var result = await virtualCashDb.getTotalPayAndCount();
return Response.ok(
jsonEncode({'success': true, 'reason': '', 'data' : result}),
headers: {'Content-Type': 'application/json'},
);
} catch(e) {
WriteLOG.writeLog("Debug error2 $e");
return Response.ok(
jsonEncode({'success': false, 'reason': '$e'}),
headers: {'Content-Type': 'application/json'},
);
}
}
static Future<Response> getChequeList(Request request) async {
try {
final VirtualCashDb virtualCashDb = locator<VirtualCashDb>();
var result = await virtualCashDb.getCustomCheques();
return Response.ok(
jsonEncode({'success': true, 'reason': '', 'data' : result}),
headers: {'Content-Type': 'application/json'},
);
} catch(e) {
WriteLOG.writeLog("Debug error2 $e");
return Response.ok(
jsonEncode({'success': false, 'reason': '$e'}),
headers: {'Content-Type': 'application/json'},
);
}
}
static Future<Response> updateIntegrationId(Request request) async {
try {
// Parse the request body
final body = await request.readAsString();
final data = jsonDecode(body);
// Extract receipt_id and integration_id from the parsed data
final receiptId = data['receipt_id'];
final newIntegrationId = data['integration_id'];
// Validate the input
if (receiptId == null || newIntegrationId == null) {
return Response.badRequest(
body: jsonEncode({'success': false, 'reason': 'Invalid input'}),
headers: {'Content-Type': 'application/json'},
);
}
final VirtualCashDb virtualCashDb = locator<VirtualCashDb>();
await virtualCashDb.updateIntegrationId(receiptId, newIntegrationId);
return Response.ok(
jsonEncode({'success': true, 'reason': '', 'data' : null}),
headers: {'Content-Type': 'application/json'},
);
} catch(e) {
WriteLOG.writeLog("Debug error2 $e");
return Response.ok(
jsonEncode({'success': false, 'reason': '$e'}),
headers: {'Content-Type': 'application/json'},
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment