update struk
This commit is contained in:
@@ -25,6 +25,7 @@ import '../../widgets/dotted_border/global_dotted_border.dart';
|
|||||||
import '../../widgets/universal_image.dart';
|
import '../../widgets/universal_image.dart';
|
||||||
import '../Products/add product/modle/create_product_model.dart';
|
import '../Products/add product/modle/create_product_model.dart';
|
||||||
import '../language/language_provider.dart';
|
import '../language/language_provider.dart';
|
||||||
|
import '../../Provider/product_provider.dart';
|
||||||
|
|
||||||
class SalesInvoiceDetails extends StatefulWidget {
|
class SalesInvoiceDetails extends StatefulWidget {
|
||||||
const SalesInvoiceDetails({
|
const SalesInvoiceDetails({
|
||||||
@@ -134,6 +135,7 @@ class _SalesInvoiceDetailsState extends State<SalesInvoiceDetails> {
|
|||||||
final locale = Localizations.localeOf(context).languageCode;
|
final locale = Localizations.localeOf(context).languageCode;
|
||||||
return Consumer(builder: (context, ref, __) {
|
return Consumer(builder: (context, ref, __) {
|
||||||
final printerData = ref.watch(thermalPrinterProvider);
|
final printerData = ref.watch(thermalPrinterProvider);
|
||||||
|
final products = ref.watch(productProvider);
|
||||||
final businessSettingData = ref.watch(businessInfoProvider);
|
final businessSettingData = ref.watch(businessInfoProvider);
|
||||||
final hasWarranty = widget.saleTransaction.salesDetails!.any((e) => e.warrantyInfo?.warrantyDuration != null);
|
final hasWarranty = widget.saleTransaction.salesDetails!.any((e) => e.warrantyInfo?.warrantyDuration != null);
|
||||||
final hasGuarantee = widget.saleTransaction.salesDetails!.any((e) => e.warrantyInfo?.guaranteeDuration != null);
|
final hasGuarantee = widget.saleTransaction.salesDetails!.any((e) => e.warrantyInfo?.guaranteeDuration != null);
|
||||||
@@ -1316,6 +1318,7 @@ class _SalesInvoiceDetailsState extends State<SalesInvoiceDetails> {
|
|||||||
transaction: model,
|
transaction: model,
|
||||||
productList: model.transitionModel!.salesDetails,
|
productList: model.transitionModel!.salesDetails,
|
||||||
context: context,
|
context: context,
|
||||||
|
products: products.value,
|
||||||
);
|
);
|
||||||
// final defould = true;
|
// final defould = true;
|
||||||
|
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ class SalesProduct {
|
|||||||
this.productPurchasePrice,
|
this.productPurchasePrice,
|
||||||
this.productCode,
|
this.productCode,
|
||||||
this.productType,
|
this.productType,
|
||||||
|
this.vat,
|
||||||
});
|
});
|
||||||
|
|
||||||
SalesProduct.fromJson(dynamic json) {
|
SalesProduct.fromJson(dynamic json) {
|
||||||
@@ -270,6 +271,7 @@ class SalesProduct {
|
|||||||
productType = json['product_type'];
|
productType = json['product_type'];
|
||||||
productPurchasePrice = json['productPurchasePrice'];
|
productPurchasePrice = json['productPurchasePrice'];
|
||||||
category = json['category'] != null ? Category.fromJson(json['category']) : null;
|
category = json['category'] != null ? Category.fromJson(json['category']) : null;
|
||||||
|
vat = json['vat'] != null ? SalesVat.fromJson(json['vat']) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
num? id;
|
num? id;
|
||||||
@@ -279,6 +281,7 @@ class SalesProduct {
|
|||||||
num? productPurchasePrice;
|
num? productPurchasePrice;
|
||||||
String? productType;
|
String? productType;
|
||||||
Category? category;
|
Category? category;
|
||||||
|
SalesVat? vat;
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final map = <String, dynamic>{};
|
final map = <String, dynamic>{};
|
||||||
@@ -288,6 +291,9 @@ class SalesProduct {
|
|||||||
if (category != null) {
|
if (category != null) {
|
||||||
map['category'] = category?.toJson();
|
map['category'] = category?.toJson();
|
||||||
}
|
}
|
||||||
|
if (vat != null) {
|
||||||
|
map['vat'] = vat?.toJson();
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,6 +513,14 @@ class SalesVat {
|
|||||||
num? id;
|
num? id;
|
||||||
String? name;
|
String? name;
|
||||||
num? rate;
|
num? rate;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final map = <String, dynamic>{};
|
||||||
|
map['id'] = id;
|
||||||
|
map['name'] = name;
|
||||||
|
map['rate'] = rate;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Branch {
|
class Branch {
|
||||||
|
|||||||
@@ -129,10 +129,15 @@ class ThermalPrinter extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> printSalesThermalInvoiceNow({required PrintSalesTransactionModel transaction, required List<SalesDetails>? productList, required BuildContext context}) async {
|
Future<void> printSalesThermalInvoiceNow(
|
||||||
|
{required PrintSalesTransactionModel transaction,
|
||||||
|
required List<SalesDetails>? productList,
|
||||||
|
required BuildContext context,
|
||||||
|
List<Product>? products}) async {
|
||||||
await getBluetooth();
|
await getBluetooth();
|
||||||
isBluetoothConnected
|
isBluetoothConnected
|
||||||
? SalesThermalPrinterInvoice().printSalesTicket(printTransactionModel: transaction, productList: productList, context: context)
|
? SalesThermalPrinterInvoice().printSalesTicket(
|
||||||
|
printTransactionModel: transaction, productList: productList, context: context, products: products)
|
||||||
: listOfBluDialog(context: context);
|
: listOfBluDialog(context: context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'package:nb_utils/nb_utils.dart';
|
|||||||
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
|
import 'package:print_bluetooth_thermal/print_bluetooth_thermal.dart';
|
||||||
|
|
||||||
import '../Const/api_config.dart';
|
import '../Const/api_config.dart';
|
||||||
|
import '../Screens/Products/Model/product_model.dart';
|
||||||
import '../Screens/Products/add product/modle/create_product_model.dart';
|
import '../Screens/Products/add product/modle/create_product_model.dart';
|
||||||
import '../constant.dart';
|
import '../constant.dart';
|
||||||
import '../model/sale_transaction_model.dart';
|
import '../model/sale_transaction_model.dart';
|
||||||
@@ -23,6 +24,7 @@ class SalesThermalPrinterInvoice {
|
|||||||
Future<void> printSalesTicket(
|
Future<void> printSalesTicket(
|
||||||
{required PrintSalesTransactionModel printTransactionModel,
|
{required PrintSalesTransactionModel printTransactionModel,
|
||||||
required List<SalesDetails>? productList,
|
required List<SalesDetails>? productList,
|
||||||
|
List<Product>? products,
|
||||||
required BuildContext context}) async {
|
required BuildContext context}) async {
|
||||||
bool? isConnected = await PrintBluetoothThermal.connectionStatus;
|
bool? isConnected = await PrintBluetoothThermal.connectionStatus;
|
||||||
bool defould = (printTransactionModel.personalInformationModel.data?.invoiceLanguage == 'english' ||
|
bool defould = (printTransactionModel.personalInformationModel.data?.invoiceLanguage == 'english' ||
|
||||||
@@ -36,8 +38,10 @@ class SalesThermalPrinterInvoice {
|
|||||||
|
|
||||||
if (defould) {
|
if (defould) {
|
||||||
bytes = is80mm
|
bytes = is80mm
|
||||||
? await getSalesTicket80mm(printTransactionModel: printTransactionModel, productList: productList)
|
? await getSalesTicket80mm(
|
||||||
: await getSalesTicket58mm(printTransactionModel: printTransactionModel, productList: productList);
|
printTransactionModel: printTransactionModel, productList: productList, products: products)
|
||||||
|
: await getSalesTicket58mm(
|
||||||
|
printTransactionModel: printTransactionModel, productList: productList, products: products);
|
||||||
} else {
|
} else {
|
||||||
final bool isRTL = rtlLang.contains(await getLanguageName());
|
final bool isRTL = rtlLang.contains(await getLanguageName());
|
||||||
|
|
||||||
@@ -62,7 +66,9 @@ class SalesThermalPrinterInvoice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<List<int>> getSalesTicket58mm(
|
Future<List<int>> getSalesTicket58mm(
|
||||||
{required PrintSalesTransactionModel printTransactionModel, required List<SalesDetails>? productList}) async {
|
{required PrintSalesTransactionModel printTransactionModel,
|
||||||
|
required List<SalesDetails>? productList,
|
||||||
|
List<Product>? products}) async {
|
||||||
List<DateTime> returnedDates = [];
|
List<DateTime> returnedDates = [];
|
||||||
String productName({required num detailsId}) {
|
String productName({required num detailsId}) {
|
||||||
final details = productList?[productList.indexWhere((element) => element.id == detailsId)];
|
final details = productList?[productList.indexWhere((element) => element.id == detailsId)];
|
||||||
@@ -258,11 +264,11 @@ class SalesThermalPrinterInvoice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bytes += generator.row([
|
bytes += generator.row([
|
||||||
PosColumn(text: 'SL', width: 1, styles: const PosStyles(align: PosAlign.left, bold: true)),
|
PosColumn(text: 'Item', width: 4, styles: const PosStyles(align: PosAlign.left, bold: true)),
|
||||||
PosColumn(text: 'Product', width: 4, styles: const PosStyles(align: PosAlign.left, bold: true)),
|
PosColumn(text: 'Qt', width: 1, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
||||||
PosColumn(text: 'Qty', width: 1, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
PosColumn(text: 'Price', width: 3, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
||||||
PosColumn(text: 'VAT/Tax', width: 2, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
PosColumn(text: '%', width: 1, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
||||||
PosColumn(text: 'Amount', width: 4, styles: const PosStyles(align: PosAlign.right, bold: true)),
|
PosColumn(text: 'Amount', width: 3, styles: const PosStyles(align: PosAlign.right, bold: true)),
|
||||||
]);
|
]);
|
||||||
bytes += generator.hr();
|
bytes += generator.hr();
|
||||||
List.generate(productList?.length ?? 1, (index) {
|
List.generate(productList?.length ?? 1, (index) {
|
||||||
@@ -279,14 +285,16 @@ class SalesThermalPrinterInvoice {
|
|||||||
final name = "${productList?[index].product?.productName ?? ''}"
|
final name = "${productList?[index].product?.productName ?? ''}"
|
||||||
"${productList?[index].product?.productType == ProductType.variant.name ? ' [${productList?[index].stock?.batchNo ?? ''}]' : ''}";
|
"${productList?[index].product?.productType == ProductType.variant.name ? ' [${productList?[index].stock?.batchNo ?? ''}]' : ''}";
|
||||||
|
|
||||||
|
final double qty = getProductQuantity(detailsId: productList?[index].id ?? 0).toDouble();
|
||||||
|
final double price = num.tryParse(productList?[index].price.toString() ?? '0')?.toDouble() ?? 0;
|
||||||
|
final double discount = num.tryParse(productList?[index].discount.toString() ?? '0')?.toDouble() ?? 0;
|
||||||
|
final product = products?.firstWhere((element) => element.id == productList?[index].productId,
|
||||||
|
orElse: () => Product());
|
||||||
|
final double vatPercent = num.tryParse(product?.vat?.rate.toString() ?? '0')?.toDouble() ?? 0;
|
||||||
|
final double amountExVat = (price * qty) - (discount * qty);
|
||||||
|
final double vatAmount = (amountExVat * vatPercent) / 100;
|
||||||
|
|
||||||
bytes += generator.row([
|
bytes += generator.row([
|
||||||
PosColumn(
|
|
||||||
text: '${index + 1}',
|
|
||||||
width: 1,
|
|
||||||
styles: const PosStyles(
|
|
||||||
align: PosAlign.left,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: name,
|
text: name,
|
||||||
width: 4,
|
width: 4,
|
||||||
@@ -295,19 +303,23 @@ class SalesThermalPrinterInvoice {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: formatPointNumber(getProductQuantity(detailsId: productList?[index].id ?? 0)),
|
text: formatPointNumber(qty),
|
||||||
width: 1,
|
width: 1,
|
||||||
styles: const PosStyles(align: PosAlign.center),
|
styles: const PosStyles(align: PosAlign.center),
|
||||||
),
|
),
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: formatPointNumber(0),
|
text: formatPointNumber(price),
|
||||||
width: 2,
|
width: 3,
|
||||||
styles: const PosStyles(align: PosAlign.center),
|
styles: const PosStyles(align: PosAlign.center),
|
||||||
),
|
),
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text:
|
text: "${vatPercent % 1 == 0 ? vatPercent.toInt() : vatPercent}",
|
||||||
"${((productList?[index].price ?? 0) * getProductQuantity(detailsId: productList?[index].id ?? 0)) - ((productList?[index].discount ?? 0) * getProductQuantity(detailsId: productList?[index].id ?? 0))}",
|
width: 1,
|
||||||
width: 4,
|
styles: const PosStyles(align: PosAlign.center),
|
||||||
|
),
|
||||||
|
PosColumn(
|
||||||
|
text: formatPointNumber(amountExVat),
|
||||||
|
width: 3,
|
||||||
styles: const PosStyles(align: PosAlign.right),
|
styles: const PosStyles(align: PosAlign.right),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
@@ -602,7 +614,9 @@ class SalesThermalPrinterInvoice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<List<int>> getSalesTicket80mm(
|
Future<List<int>> getSalesTicket80mm(
|
||||||
{required PrintSalesTransactionModel printTransactionModel, required List<SalesDetails>? productList}) async {
|
{required PrintSalesTransactionModel printTransactionModel,
|
||||||
|
required List<SalesDetails>? productList,
|
||||||
|
List<Product>? products}) async {
|
||||||
List<DateTime> returnedDates = [];
|
List<DateTime> returnedDates = [];
|
||||||
String productName({required num detailsId}) {
|
String productName({required num detailsId}) {
|
||||||
final details = productList?[productList.indexWhere((element) => element.id == detailsId)];
|
final details = productList?[productList.indexWhere((element) => element.id == detailsId)];
|
||||||
@@ -816,13 +830,12 @@ class SalesThermalPrinterInvoice {
|
|||||||
bytes += generator.emptyLines(1);
|
bytes += generator.emptyLines(1);
|
||||||
|
|
||||||
///____________Products_Section_________________________________
|
///____________Products_Section_________________________________
|
||||||
bytes += generator.hr();
|
|
||||||
bytes += generator.row([
|
bytes += generator.row([
|
||||||
PosColumn(text: 'SL', width: 1, styles: const PosStyles(align: PosAlign.left, bold: true)),
|
PosColumn(text: 'Item', width: 1, styles: const PosStyles(align: PosAlign.left, bold: true)),
|
||||||
PosColumn(text: 'Product', width: 5, styles: const PosStyles(align: PosAlign.left, bold: true)),
|
PosColumn(text: 'Qt', width: 1, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
||||||
PosColumn(text: 'QTY', width: 1, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
PosColumn(text: 'Price', width: 2, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
||||||
PosColumn(text: 'VAT/Tax', width: 2, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
PosColumn(text: '%', width: 2, styles: const PosStyles(align: PosAlign.center, bold: true)),
|
||||||
PosColumn(text: 'Amount', width: 3, styles: const PosStyles(align: PosAlign.right, bold: true)),
|
PosColumn(text: 'Amount(Ex Vat)', width: 3, styles: const PosStyles(align: PosAlign.right, bold: true)),
|
||||||
]);
|
]);
|
||||||
bytes += generator.hr();
|
bytes += generator.hr();
|
||||||
List.generate(productList?.length ?? 1, (index) {
|
List.generate(productList?.length ?? 1, (index) {
|
||||||
@@ -838,34 +851,42 @@ class SalesThermalPrinterInvoice {
|
|||||||
|
|
||||||
final name = "${productList?[index].product?.productName ?? ''}"
|
final name = "${productList?[index].product?.productName ?? ''}"
|
||||||
"${productList?[index].product?.productType == ProductType.variant.name ? ' [${productList?[index].stock?.batchNo ?? ''}]' : ''}";
|
"${productList?[index].product?.productType == ProductType.variant.name ? ' [${productList?[index].stock?.batchNo ?? ''}]' : ''}";
|
||||||
|
|
||||||
|
final double qty = getProductQuantity(detailsId: productList?[index].id ?? 0).toDouble();
|
||||||
|
final double price = num.tryParse(productList?[index].price.toString() ?? '0')?.toDouble() ?? 0;
|
||||||
|
final double discount = num.tryParse(productList?[index].discount.toString() ?? '0')?.toDouble() ?? 0;
|
||||||
|
final product = products?.firstWhere((element) => element.id == productList?[index].productId,
|
||||||
|
orElse: () => Product());
|
||||||
|
final double vatPercent = num.tryParse(product?.vat?.rate.toString() ?? '0')?.toDouble() ?? 0;
|
||||||
|
final double amountExVat = (price * qty) - (discount * qty);
|
||||||
|
final double vatAmount = (amountExVat * vatPercent) / 100;
|
||||||
|
|
||||||
bytes += generator.row([
|
bytes += generator.row([
|
||||||
PosColumn(
|
|
||||||
text: '${index + 1}',
|
|
||||||
width: 1,
|
|
||||||
styles: const PosStyles(
|
|
||||||
align: PosAlign.left,
|
|
||||||
)),
|
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text:
|
text:
|
||||||
"${productList?[index].product?.productName ?? ''}${productList?[index].product?.productType == ProductType.variant.name ? ' [${productList?[index].stock?.batchNo ?? ''}]' : ''}",
|
"${productList?[index].product?.productName ?? ''}${productList?[index].product?.productType == ProductType.variant.name ? ' [${productList?[index].stock?.batchNo ?? ''}]' : ''}",
|
||||||
width: 5,
|
width: 1,
|
||||||
styles: const PosStyles(
|
styles: const PosStyles(
|
||||||
align: PosAlign.left,
|
align: PosAlign.left,
|
||||||
)),
|
)),
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: formatPointNumber(getProductQuantity(detailsId: productList?[index].id ?? 0), addComma: true),
|
text: formatPointNumber(qty, addComma: true),
|
||||||
width: 1,
|
width: 1,
|
||||||
styles: const PosStyles(align: PosAlign.center)),
|
styles: const PosStyles(align: PosAlign.center)),
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: formatPointNumber(0, addComma: true),
|
text: formatPointNumber(price, addComma: true),
|
||||||
width: 2,
|
width: 2,
|
||||||
styles: const PosStyles(
|
styles: const PosStyles(
|
||||||
align: PosAlign.center,
|
align: PosAlign.center,
|
||||||
)),
|
)),
|
||||||
PosColumn(
|
PosColumn(
|
||||||
text: formatPointNumber(
|
text: "${vatPercent % 1 == 0 ? vatPercent.toInt() : vatPercent}",
|
||||||
(productList?[index].price ?? 0) * getProductQuantity(detailsId: productList?[index].id ?? 0),
|
width: 2,
|
||||||
addComma: true),
|
styles: const PosStyles(
|
||||||
|
align: PosAlign.center,
|
||||||
|
)),
|
||||||
|
PosColumn(
|
||||||
|
text: formatPointNumber(amountExVat, addComma: true),
|
||||||
width: 3,
|
width: 3,
|
||||||
styles: const PosStyles(align: PosAlign.right)),
|
styles: const PosStyles(align: PosAlign.right)),
|
||||||
]);
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user