first commit
This commit is contained in:
704
lib/Screens/Sales/Repo/sales_repo.dart
Normal file
704
lib/Screens/Sales/Repo/sales_repo.dart
Normal file
@@ -0,0 +1,704 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:mobile_pos/Provider/product_provider.dart';
|
||||
import 'package:mobile_pos/constant.dart';
|
||||
import '../../../Const/api_config.dart';
|
||||
import '../../../Provider/profile_provider.dart';
|
||||
import '../../../Provider/transactions_provider.dart';
|
||||
import '../../../Repository/constant_functions.dart';
|
||||
import '../../../http_client/custome_http_client.dart';
|
||||
import '../../../http_client/customer_http_client_get.dart';
|
||||
import '../../../model/balance_sheet_model.dart' as bs;
|
||||
import '../../../model/bill_wise_loss_profit_report_model.dart' as bwlprm;
|
||||
import '../../../model/cashflow_model.dart' as cf;
|
||||
import '../../../model/loss_profit_model.dart' as lpmodel;
|
||||
import '../../../model/product_history_model.dart' as phlm;
|
||||
import '../../../model/sale_transaction_model.dart';
|
||||
import '../../../model/subscription_report_model.dart' as srm;
|
||||
import '../../../model/tax_report_model.dart' as trm;
|
||||
import '../../Customers/Provider/customer_provider.dart';
|
||||
|
||||
class SaleRepo {
|
||||
Future<List<SalesTransactionModel>> fetchSalesList({
|
||||
bool? salesReturn,
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
final client = CustomHttpClientGet(client: http.Client());
|
||||
|
||||
// Manually build query string to preserve order
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (salesReturn != null && salesReturn) {
|
||||
queryList.add('returned-sales=true');
|
||||
}
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri = Uri.parse('${APIConfig.url}/sales${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
|
||||
print(uri);
|
||||
|
||||
final response = await client.get(url: uri);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
final list = parsed['data'] as List<dynamic>;
|
||||
return list.map((json) => SalesTransactionModel.fromJson(json)).toList();
|
||||
} else {
|
||||
throw Exception('Failed to fetch Sales List. Status code: ${response.statusCode}');
|
||||
}
|
||||
}
|
||||
|
||||
Future<SalesTransactionModel?> getSingleSale(int id) async {
|
||||
final uri = Uri.parse('${APIConfig.url}/sales/$id');
|
||||
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
print("Fetch Single Single Status: ${response.statusCode}");
|
||||
print("Fetch Single Single Body: ${response.body}");
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
return SalesTransactionModel.fromJson(parsed['data']);
|
||||
} else {
|
||||
throw Exception("Failed to fetch sale details");
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception("Error fetching sale: $e");
|
||||
}
|
||||
}
|
||||
|
||||
/// Create Sale
|
||||
Future<SalesTransactionModel?> createSale({
|
||||
required WidgetRef ref,
|
||||
required BuildContext context,
|
||||
required num? partyId,
|
||||
required String? customerPhone,
|
||||
required String purchaseDate,
|
||||
required num discountAmount,
|
||||
required num discountPercent,
|
||||
required num unRoundedTotalAmount,
|
||||
required num totalAmount,
|
||||
required num roundingAmount,
|
||||
required num dueAmount,
|
||||
required num vatAmount,
|
||||
required num vatPercent,
|
||||
required num? vatId,
|
||||
required num changeAmount,
|
||||
required bool isPaid,
|
||||
required String paymentType,
|
||||
required String roundedOption,
|
||||
required List<CartSaleProducts> products,
|
||||
required String discountType,
|
||||
required num shippingCharge,
|
||||
String? note,
|
||||
File? image,
|
||||
}) async {
|
||||
// 1. Prepare Fields
|
||||
final fields = _buildCommonFields(
|
||||
purchaseDate: purchaseDate,
|
||||
discountAmount: discountAmount,
|
||||
discountPercent: discountPercent,
|
||||
totalAmount: totalAmount,
|
||||
dueAmount: dueAmount,
|
||||
vatAmount: vatAmount,
|
||||
vatPercent: vatPercent,
|
||||
changeAmount: changeAmount,
|
||||
isPaid: isPaid,
|
||||
paymentType: paymentType,
|
||||
discountType: discountType,
|
||||
shippingCharge: shippingCharge,
|
||||
roundedOption: roundedOption,
|
||||
roundingAmount: roundingAmount,
|
||||
unRoundedTotalAmount: unRoundedTotalAmount,
|
||||
products: products,
|
||||
note: note,
|
||||
partyId: partyId,
|
||||
vatId: vatId,
|
||||
);
|
||||
|
||||
if (customerPhone != null) fields['customer_phone'] = customerPhone;
|
||||
|
||||
// 2. Submit Request
|
||||
final response = await _submitRequest(
|
||||
ref: ref,
|
||||
context: context,
|
||||
url: '${APIConfig.url}/sales',
|
||||
method: 'POST',
|
||||
fields: fields,
|
||||
image: image,
|
||||
);
|
||||
print('Sales Response Data: ${response?.body}');
|
||||
|
||||
// 3. Handle Success
|
||||
if (response != null && response.statusCode == 200) {
|
||||
final parsedData = jsonDecode(response.body);
|
||||
_refreshProviders(ref);
|
||||
return SalesTransactionModel.fromJson(parsedData['data']);
|
||||
} else if (response != null) {
|
||||
_handleError(context, response);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Update Sale
|
||||
Future<void> updateSale({
|
||||
required WidgetRef ref,
|
||||
required BuildContext context,
|
||||
required num id,
|
||||
required num? partyId,
|
||||
required String purchaseDate,
|
||||
required num discountAmount,
|
||||
required num discountPercent,
|
||||
required num unRoundedTotalAmount,
|
||||
required num totalAmount,
|
||||
required num dueAmount,
|
||||
required num vatAmount,
|
||||
required num vatPercent,
|
||||
required num? vatId,
|
||||
required num changeAmount,
|
||||
required num roundingAmount,
|
||||
required bool isPaid,
|
||||
required String paymentType,
|
||||
required String roundedOption,
|
||||
required List<CartSaleProducts> products,
|
||||
required String discountType,
|
||||
required num shippingCharge,
|
||||
String? note,
|
||||
File? image,
|
||||
}) async {
|
||||
// 1. Prepare Fields
|
||||
final fields = _buildCommonFields(
|
||||
purchaseDate: purchaseDate,
|
||||
discountAmount: discountAmount,
|
||||
discountPercent: discountPercent,
|
||||
totalAmount: totalAmount,
|
||||
dueAmount: dueAmount,
|
||||
vatAmount: vatAmount,
|
||||
vatPercent: vatPercent,
|
||||
changeAmount: changeAmount,
|
||||
isPaid: isPaid,
|
||||
paymentType: paymentType,
|
||||
discountType: discountType,
|
||||
shippingCharge: shippingCharge,
|
||||
roundedOption: roundedOption,
|
||||
roundingAmount: roundingAmount,
|
||||
unRoundedTotalAmount: unRoundedTotalAmount,
|
||||
products: products,
|
||||
note: note,
|
||||
partyId: partyId,
|
||||
vatId: vatId,
|
||||
);
|
||||
|
||||
// Add Method Override for Update
|
||||
fields['_method'] = 'put';
|
||||
|
||||
// 2. Submit Request
|
||||
final response = await _submitRequest(
|
||||
ref: ref,
|
||||
context: context,
|
||||
url: '${APIConfig.url}/sales/$id',
|
||||
method: 'POST', // Multipart uses POST with _method field for PUT behavior usually
|
||||
fields: fields,
|
||||
image: image,
|
||||
);
|
||||
|
||||
// 3. Handle Success
|
||||
if (response != null && response.statusCode == 200) {
|
||||
EasyLoading.showSuccess('Updated successful!');
|
||||
_refreshProviders(ref);
|
||||
Navigator.pop(context);
|
||||
} else if (response != null) {
|
||||
_handleError(context, response);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------
|
||||
// Private Helper Methods (The Simplification)
|
||||
// ------------------------------------------
|
||||
|
||||
Map<String, String> _buildCommonFields({
|
||||
required String purchaseDate,
|
||||
required num discountAmount,
|
||||
required num discountPercent,
|
||||
required num totalAmount,
|
||||
required num dueAmount,
|
||||
required num vatAmount,
|
||||
required num vatPercent,
|
||||
required num changeAmount,
|
||||
required bool isPaid,
|
||||
required String paymentType,
|
||||
required String discountType,
|
||||
required num shippingCharge,
|
||||
required String roundedOption,
|
||||
required num roundingAmount,
|
||||
required num unRoundedTotalAmount,
|
||||
required List<CartSaleProducts> products,
|
||||
String? note,
|
||||
num? partyId,
|
||||
num? vatId,
|
||||
}) {
|
||||
final Map<String, String> fields = {
|
||||
'saleDate': purchaseDate,
|
||||
'discountAmount': discountAmount.toString(),
|
||||
'discount_percent': discountPercent.toString(),
|
||||
'totalAmount': totalAmount.toString(),
|
||||
'dueAmount': dueAmount.toString(),
|
||||
'paidAmount': (totalAmount - dueAmount).toString(),
|
||||
'change_amount': changeAmount.toString(),
|
||||
'vat_amount': vatAmount.toString(),
|
||||
'vat_percent': vatPercent.toString(),
|
||||
'isPaid': isPaid.toString(),
|
||||
'payments': paymentType,
|
||||
'discount_type': discountType,
|
||||
'shipping_charge': shippingCharge.toString(),
|
||||
'rounding_option': roundedOption,
|
||||
'rounding_amount': roundingAmount.toStringAsFixed(2),
|
||||
'actual_total_amount': unRoundedTotalAmount.toString(),
|
||||
'note': note ?? '',
|
||||
'products': jsonEncode(products.map((e) => e.toJson()).toList()),
|
||||
};
|
||||
|
||||
if (partyId != null) fields['party_id'] = partyId.toString();
|
||||
if (vatId != null) fields['vat_id'] = vatId.toString();
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
Future<http.Response?> _submitRequest({
|
||||
required WidgetRef ref,
|
||||
required BuildContext context,
|
||||
required String url,
|
||||
required String method,
|
||||
required Map<String, String> fields,
|
||||
File? image,
|
||||
}) async {
|
||||
final uri = Uri.parse(url);
|
||||
try {
|
||||
var request = http.MultipartRequest(method, uri);
|
||||
|
||||
// Add Headers
|
||||
request.headers.addAll({
|
||||
'Accept': 'application/json',
|
||||
'Authorization': await getAuthToken(),
|
||||
'Content-Type': 'multipart/form-data',
|
||||
});
|
||||
|
||||
// Add Fields
|
||||
request.fields.addAll(fields);
|
||||
|
||||
// Add Image
|
||||
if (image != null) {
|
||||
request.files.add(await http.MultipartFile.fromPath('image', image.path));
|
||||
}
|
||||
|
||||
CustomHttpClient customHttpClient = CustomHttpClient(
|
||||
client: http.Client(),
|
||||
ref: ref,
|
||||
context: context,
|
||||
);
|
||||
|
||||
var streamedResponse = await customHttpClient.uploadFile(
|
||||
url: uri,
|
||||
file: image,
|
||||
fileFieldName: 'image',
|
||||
fields: request.fields,
|
||||
contentType: 'multipart/form-data',
|
||||
);
|
||||
print('POST Sales Data ------------------->\n${request.fields}');
|
||||
|
||||
return await http.Response.fromStream(streamedResponse);
|
||||
} catch (error) {
|
||||
EasyLoading.dismiss();
|
||||
final errorMessage = error.toString().replaceFirst('Exception: ', '');
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(errorMessage), backgroundColor: kMainColor),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void _refreshProviders(WidgetRef ref) {
|
||||
ref.refresh(productProvider);
|
||||
ref.refresh(partiesProvider);
|
||||
ref.refresh(salesTransactionProvider);
|
||||
ref.refresh(businessInfoProvider);
|
||||
ref.refresh(getExpireDateProvider(ref));
|
||||
ref.refresh(summaryInfoProvider);
|
||||
}
|
||||
|
||||
void _handleError(BuildContext context, http.Response response) {
|
||||
EasyLoading.dismiss();
|
||||
try {
|
||||
final parsedData = jsonDecode(response.body);
|
||||
print('reponse :${parsedData}');
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Operation failed: ${parsedData['message'] ?? response.reasonPhrase}')),
|
||||
);
|
||||
} catch (_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Operation failed: ${response.statusCode}')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<lpmodel.LossProfitModel> getLossProfit({
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri = Uri.parse('${APIConfig.url}/reports/loss-profit${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
print('Response Status: ${response.statusCode}');
|
||||
print('Response Body: ${response.body}');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
if (parsed == null) {
|
||||
throw Exception("Response is null");
|
||||
}
|
||||
if (parsed['data'] == null) {
|
||||
return lpmodel.LossProfitModel.fromJson(parsed);
|
||||
}
|
||||
|
||||
return lpmodel.LossProfitModel.fromJson(parsed['data']);
|
||||
} else {
|
||||
throw Exception("Failed to fetch loss profit: ${response.statusCode} - ${response.body}");
|
||||
}
|
||||
} catch (e, stack) {
|
||||
throw Exception("Error fetching loss profit: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<cf.CashflowModel> getCashflow({
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri = Uri.parse('${APIConfig.url}/reports/cashflow${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
return cf.CashflowModel.fromJson(parsed);
|
||||
} else {
|
||||
throw Exception("Failed to fetch sale details: ${response.statusCode} - ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception("Error fetching sale: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<bs.BalanceSheetModel> getBalanceSheet({
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri =
|
||||
Uri.parse('${APIConfig.url}/reports/balance-sheet${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
return bs.BalanceSheetModel.fromJson(parsed);
|
||||
} else {
|
||||
throw Exception("Failed to fetch balance sheet details: ${response.statusCode} - ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception("Error fetching balance sheet: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<srm.SubscriptionReportModel>> getSubscriptionReport({
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri =
|
||||
Uri.parse('${APIConfig.url}/reports/subscription${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
return [...?parsed?["data"].map<srm.SubscriptionReportModel>((x) => srm.SubscriptionReportModel.fromJson(x))];
|
||||
} else {
|
||||
throw Exception("Failed to fetch subscription report details: ${response.statusCode} - ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception("Error fetching subscription report: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<trm.TaxReportModel> getTaxReport({
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri = Uri.parse('${APIConfig.url}/reports/tax${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
return trm.TaxReportModel.fromJson(parsed);
|
||||
} else {
|
||||
throw Exception("Failed to fetch tax report details: ${response.statusCode} - ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception("Error fetching tax report: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<bwlprm.BillWiseLossProfitReportModel> getBillWiseLossProfitReport({
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri =
|
||||
Uri.parse('${APIConfig.url}/reports/bill-wise-profit${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
return bwlprm.BillWiseLossProfitReportModel.fromJson(parsed);
|
||||
} else {
|
||||
throw Exception("Failed to fetch tax report details: ${response.statusCode} - ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception("Error fetching tax report: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<phlm.ProductHistoryListModel> getProductSaleHistoryReport({
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri =
|
||||
Uri.parse('${APIConfig.url}/reports/product-sale-history${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
return phlm.ProductHistoryListModel.fromJson(parsed);
|
||||
} else {
|
||||
throw Exception("Failed to fetch tax report details: ${response.statusCode} - ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception("Error fetching tax report: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<phlm.ProductHistoryDetailsModel> getProductSaleHistoryReportDetails({
|
||||
required int productId,
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri = Uri.parse(
|
||||
'${APIConfig.url}/reports/product-sale-history/$productId${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
return phlm.ProductHistoryDetailsModel.fromJson(parsed);
|
||||
} else {
|
||||
throw Exception("Failed to fetch tax report details: ${response.statusCode} - ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception("Error fetching tax report: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<phlm.ProductHistoryDetailsModel> getProductPurchaseHistoryReportDetails({
|
||||
required int productId,
|
||||
String? type,
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
}) async {
|
||||
try {
|
||||
CustomHttpClientGet clientGet = CustomHttpClientGet(client: http.Client());
|
||||
final List<String> queryList = [];
|
||||
|
||||
if (type != null && type.isNotEmpty) {
|
||||
queryList.add('duration=$type');
|
||||
}
|
||||
|
||||
if (type == 'custom_date' && fromDate != null && toDate != null && fromDate.isNotEmpty && toDate.isNotEmpty) {
|
||||
queryList.add('from_date=$fromDate');
|
||||
queryList.add('to_date=$toDate');
|
||||
}
|
||||
|
||||
final String queryString = queryList.join('&');
|
||||
final Uri uri = Uri.parse(
|
||||
'${APIConfig.url}/reports/product-purchase-history/$productId${queryString.isNotEmpty ? '?$queryString' : ''}');
|
||||
final response = await clientGet.get(url: uri);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final parsed = jsonDecode(response.body);
|
||||
return phlm.ProductHistoryDetailsModel.fromJson(parsed);
|
||||
} else {
|
||||
throw Exception("Failed to fetch tax report details: ${response.statusCode} - ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception("Error fetching tax report: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CartSaleProducts {
|
||||
final num stockId;
|
||||
final num productId;
|
||||
final num? price;
|
||||
final num? discount;
|
||||
final String productName;
|
||||
final num? quantities;
|
||||
|
||||
CartSaleProducts({
|
||||
required this.productName,
|
||||
required this.stockId,
|
||||
this.discount,
|
||||
required this.productId,
|
||||
required this.price,
|
||||
required this.quantities,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'stock_id': stockId,
|
||||
'product_id': productId,
|
||||
'product_name': productName,
|
||||
'price': price,
|
||||
'quantities': quantities,
|
||||
'discount': discount,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user