first commit
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
import 'dart:io';
|
||||
import 'package:file_selector/file_selector.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mobile_pos/Provider/profile_provider.dart';
|
||||
import 'package:mobile_pos/generated/l10n.dart' as lang;
|
||||
import 'package:mobile_pos/Screens/Products/bulk%20product%20upload/repo/bulk_upload_repo.dart';
|
||||
import 'package:mobile_pos/constant.dart';
|
||||
|
||||
import '../../../GlobalComponents/glonal_popup.dart';
|
||||
|
||||
class BulkUploader extends StatefulWidget {
|
||||
const BulkUploader({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<BulkUploader> createState() => _BulkUploaderState();
|
||||
}
|
||||
|
||||
class _BulkUploaderState extends State<BulkUploader> {
|
||||
File? file;
|
||||
|
||||
String getFileExtension(String fileName) {
|
||||
return fileName.split('/').last;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final _lang = lang.S.of(context);
|
||||
return GlobalPopup(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(_lang.excelUploader),
|
||||
),
|
||||
body: Consumer(builder: (context, ref, __) {
|
||||
final businessInfo = ref.watch(businessInfoProvider);
|
||||
return businessInfo.when(data: (details) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Visibility(
|
||||
visible: file != null,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 20),
|
||||
child: Card(
|
||||
child: ListTile(
|
||||
leading: Container(
|
||||
height: 40,
|
||||
width: 40,
|
||||
padding: const EdgeInsets.all(2),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||
),
|
||||
child: const Image(image: AssetImage('images/excel.png'))),
|
||||
title: Text(
|
||||
getFileExtension(file?.path ?? ''),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
trailing: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
file = null;
|
||||
});
|
||||
},
|
||||
child: Text(_lang.remove)))),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: file == null,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.only(bottom: 20),
|
||||
child: Image(
|
||||
height: 100,
|
||||
width: 100,
|
||||
image: AssetImage('images/file-upload.png'),
|
||||
)),
|
||||
),
|
||||
ElevatedButton(
|
||||
style: const ButtonStyle(backgroundColor: WidgetStatePropertyAll(kMainColor)),
|
||||
onPressed: () async {
|
||||
if (file == null) {
|
||||
await pickAndUploadFile(ref: ref);
|
||||
} else {
|
||||
EasyLoading.show(status: _lang.uploading);
|
||||
await BulkUpLoadRepo().uploadBulkFile(file: file!, ref: ref, context: context);
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
},
|
||||
child: Text(file == null ? _lang.pickAndUploadFile : _lang.upload,
|
||||
style: const TextStyle(color: Colors.white)),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
await BulkUpLoadRepo().downloadFile(context);
|
||||
},
|
||||
child: Text(_lang.downloadExcelFormat),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}, error: (e, stack) {
|
||||
return Text(e.toString());
|
||||
}, loading: () {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
});
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
///
|
||||
|
||||
Future<void> pickAndUploadFile({required WidgetRef ref}) async {
|
||||
XTypeGroup typeGroup = XTypeGroup(
|
||||
label: lang.S.of(context).excelFiles,
|
||||
extensions: ['xlsx'],
|
||||
);
|
||||
final XFile? fileResult = await openFile(acceptedTypeGroups: [typeGroup]);
|
||||
|
||||
if (fileResult != null) {
|
||||
final File files = File(fileResult.path);
|
||||
setState(() {
|
||||
file = files;
|
||||
});
|
||||
} else {
|
||||
print(lang.S.of(context).noFileSelected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mobile_pos/Provider/product_provider.dart';
|
||||
import 'package:mobile_pos/Screens/product_brand/product_brand_provider/product_brand_provider.dart';
|
||||
import 'package:mobile_pos/Screens/product_category/provider/product_category_provider/product_unit_provider.dart';
|
||||
import 'package:mobile_pos/Screens/product_unit/provider/product_unit_provider.dart';
|
||||
|
||||
import '../../../../Const/api_config.dart';
|
||||
import '../../../../Repository/constant_functions.dart';
|
||||
import '../../../../http_client/custome_http_client.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class BulkUpLoadRepo {
|
||||
Future<void> uploadBulkFile({
|
||||
required WidgetRef ref,
|
||||
required BuildContext context,
|
||||
required File file,
|
||||
}) async {
|
||||
CustomHttpClient customHttpClient = CustomHttpClient(client: http.Client(), context: context, ref: ref);
|
||||
final uri = Uri.parse('${APIConfig.url}/bulk-uploads');
|
||||
|
||||
var request = http.MultipartRequest('POST', uri)
|
||||
..headers['Accept'] = 'application/json'
|
||||
..headers['Authorization'] = await getAuthToken();
|
||||
|
||||
request.files.add(http.MultipartFile.fromBytes('file', file.readAsBytesSync(), filename: file.path));
|
||||
|
||||
final response = await customHttpClient.uploadFile(url: uri, fileFieldName: 'file', file: file, fields: request.fields);
|
||||
final responseData = await response.stream.bytesToString();
|
||||
final parsedData = jsonDecode(responseData);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Added successful!')));
|
||||
ref.refresh(productProvider);
|
||||
ref.refresh(categoryProvider);
|
||||
ref.refresh(brandsProvider);
|
||||
ref.refresh(unitsProvider);
|
||||
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed: ${parsedData['message']}')));
|
||||
}
|
||||
}
|
||||
|
||||
final String fileUrl = '${APIConfig.domain}assets/POSpro_bulk_product_upload.xlsx';
|
||||
|
||||
Future<void> downloadFile(BuildContext context) async {
|
||||
try {
|
||||
final response = await http.get(Uri.parse(fileUrl));
|
||||
if (response.statusCode != 200) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Failed to download file!')),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final downloadPath = '/storage/emulated/0/Download';
|
||||
final file = File('$downloadPath/POSpro_bulk_product_upload.xlsx');
|
||||
|
||||
await file.writeAsBytes(response.bodyBytes);
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('File saved to: ${file.path}')),
|
||||
);
|
||||
} catch (e) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Download error: $e')),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user