add logic
parent
1d31dce7be
commit
c76bc5f9d2
|
|
@ -4,6 +4,7 @@ const String TransactionColumnUuid = 'uuid';
|
|||
const String TransactionColumnType = 'type';
|
||||
const String TransactionColumnStatus = 'status';
|
||||
const String TransactionColumnData = 'data';
|
||||
const String TransactionColumnAppCompanyId = 'appCompanyId';
|
||||
const String TransactionColumnCreatedAt = 'createdAt';
|
||||
|
||||
const int TransactionTypeSell = 1;
|
||||
|
|
@ -18,6 +19,7 @@ class Transaction {
|
|||
int type;
|
||||
int status;
|
||||
String data;
|
||||
int appCompanyId;
|
||||
String createdAt;
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
|
|
@ -26,6 +28,7 @@ class Transaction {
|
|||
TransactionColumnType: type,
|
||||
TransactionColumnStatus: status,
|
||||
TransactionColumnData: data,
|
||||
TransactionColumnAppCompanyId: appCompanyId,
|
||||
TransactionColumnCreatedAt: createdAt,
|
||||
};
|
||||
if (id != null) {
|
||||
|
|
@ -41,6 +44,7 @@ class Transaction {
|
|||
uuid = map[TransactionColumnUuid];
|
||||
type = map[TransactionColumnType];
|
||||
status = map[TransactionColumnStatus];
|
||||
appCompanyId = map[TransactionColumnAppCompanyId];
|
||||
data = map[TransactionColumnData];
|
||||
createdAt = map[TransactionColumnCreatedAt];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,35 @@ class ProductDao {
|
|||
String eanCode;
|
||||
int article;
|
||||
String excise;
|
||||
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
var map = <String, dynamic>{
|
||||
'id': id,
|
||||
'categoryId': categoryId,
|
||||
'count': count,
|
||||
'price': price,
|
||||
'productName': productName,
|
||||
'categoryName': categoryName,
|
||||
'eanCode': eanCode,
|
||||
'article': article,
|
||||
'excise': excise,
|
||||
};
|
||||
return map;
|
||||
}
|
||||
|
||||
ProductDao();
|
||||
|
||||
ProductDao.fromMap(Map<String, dynamic> map) {
|
||||
id = map['id'];
|
||||
categoryId = map['categoryId'];
|
||||
count = map['count'];
|
||||
price = map['price'];
|
||||
productName = map['productName'];
|
||||
categoryName = map['categoryName'];
|
||||
eanCode = map['eanCode'];
|
||||
article = map['article'];
|
||||
excise = map['excise'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
class TransactionState {
|
||||
String uuid;
|
||||
}
|
||||
|
|
@ -1,13 +1,19 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:redux_thunk/redux_thunk.dart';
|
||||
import 'package:satu/core/entity/Category.dart';
|
||||
import 'package:satu/core/entity/Goods.dart';
|
||||
import 'package:satu/core/entity/Transaction.dart';
|
||||
import 'package:satu/core/models/flow/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/transaction_state.dart';
|
||||
import 'package:satu/core/redux/state/sell_state.dart';
|
||||
import 'package:satu/core/services/db_service.dart';
|
||||
import 'package:satu/core/services/dialog_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
import 'package:satu/core/utils/logger.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../store.dart';
|
||||
|
||||
|
|
@ -18,27 +24,97 @@ class SetSellStateAction {
|
|||
SetSellStateAction(this.sellState);
|
||||
}
|
||||
|
||||
final Logger log = getLogger('SetSellStateAction');
|
||||
|
||||
final DbService _dbService = locator<DbService>();
|
||||
|
||||
ThunkAction<AppState> addSellItem({Good good, String excise}) {
|
||||
return (Store<AppState> store) async {
|
||||
ProductDao item = new ProductDao()
|
||||
..id = good.id
|
||||
..price = good.price
|
||||
..article = good.articul
|
||||
..count = 1.0
|
||||
..eanCode = good.ean
|
||||
..productName = good.name
|
||||
..excise = excise;
|
||||
//category add logic
|
||||
if (good.categoryId != null) {
|
||||
List<Map<String, dynamic>> set =
|
||||
await _dbService.queryRowsWithWhere(CategoryTableName, 'id = ?', [good.categoryId]);
|
||||
log.i('addSellItem');
|
||||
int appCompanyId = store.state.userState.auth.companyId;
|
||||
String uuid = store.state.sellState.transactionState.uuid;
|
||||
|
||||
Transaction transaction;
|
||||
|
||||
if (uuid != null && good !=null) {
|
||||
List<Map<String, dynamic>> set = await _dbService.queryRowsWithWhere(
|
||||
TransactionTableName,
|
||||
'$TransactionColumnAppCompanyId = ? and $TransactionColumnStatus = ? and ${TransactionColumnType} = ?',
|
||||
[appCompanyId, TransactionStatusPrepare, TransactionTypeSell],
|
||||
orderBy: '$TransactionColumnCreatedAt desc');
|
||||
if (set.isNotEmpty) {
|
||||
Category category = Category.fromMap(set.first);
|
||||
item.categoryId = category.id;
|
||||
for(Map<String, dynamic> map in set) {
|
||||
Transaction _transaction = Transaction.fromMap(map);
|
||||
ProductDao _product = ProductDao.fromMap(jsonDecode(_transaction.data));
|
||||
if(_product.id == good.id) {
|
||||
transaction = _transaction;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
store.dispatch(SetSellStateAction(SellState()));
|
||||
|
||||
if(transaction !=null) {
|
||||
ProductDao item = ProductDao.fromMap(jsonDecode(transaction.data));
|
||||
item..count = item.count + 1;
|
||||
transaction.data = jsonEncode(item.toMap());
|
||||
transaction.createdAt = DateTime.now().toIso8601String();
|
||||
_dbService.update(TransactionTableName, transaction.toMap());
|
||||
} else {
|
||||
ProductDao item = new ProductDao()
|
||||
..id = good.id
|
||||
..price = good.price
|
||||
..article = good.articul
|
||||
..count = 1.0
|
||||
..eanCode = good.ean
|
||||
..productName = good.name
|
||||
..excise = excise;
|
||||
//category add logic
|
||||
if (good.categoryId != null) {
|
||||
List<Map<String, dynamic>> set =
|
||||
await _dbService.queryRowsWithWhere(CategoryTableName, 'id = ?', [good.categoryId]);
|
||||
if (set.isNotEmpty) {
|
||||
Category category = Category.fromMap(set.first);
|
||||
item.categoryId = category.id;
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid == null) {
|
||||
var uuidTool = Uuid();
|
||||
;
|
||||
uuid = uuidTool.v4();
|
||||
}
|
||||
|
||||
transaction = new Transaction()
|
||||
..uuid = uuid
|
||||
..status = TransactionStatusPrepare
|
||||
..appCompanyId = appCompanyId
|
||||
..type = TransactionTypeSell
|
||||
..createdAt = DateTime.now().toIso8601String()
|
||||
..data = jsonEncode(item.toMap());
|
||||
await _dbService.insert(TransactionTableName, transaction.toMap());
|
||||
}
|
||||
await loadSellData(store);
|
||||
};
|
||||
}
|
||||
|
||||
Future<void> loadSellData(Store<AppState> store) async {
|
||||
try {
|
||||
int appCompanyId = store.state.userState.auth.companyId;
|
||||
List<Map<String, dynamic>> set = await _dbService.queryRowsWithWhere(
|
||||
TransactionTableName,
|
||||
'$TransactionColumnAppCompanyId = ? and $TransactionColumnStatus = ? and ${TransactionColumnType} = ?',
|
||||
[appCompanyId, TransactionStatusPrepare, TransactionTypeSell],
|
||||
orderBy: '$TransactionColumnCreatedAt desc');
|
||||
List<ProductDao> list = [];
|
||||
String uuid;
|
||||
for (Map<String, dynamic> map in set) {
|
||||
Transaction transaction = Transaction.fromMap(map);
|
||||
uuid = transaction.uuid;
|
||||
list.add(ProductDao.fromMap(jsonDecode(transaction.data)));
|
||||
}
|
||||
store.dispatch(SetSellStateAction(SellState(items: list, transactionState: TransactionState()..uuid = uuid)));
|
||||
} catch (e, stack) {
|
||||
log.e('loadSellData', e, stack);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import 'package:satu/core/redux/state/user_state.dart';
|
|||
sellReducer(SellState prevState, SetSellStateAction action) {
|
||||
final payload = action.sellState;
|
||||
return prevState.copyWith(
|
||||
items: payload.items
|
||||
items: payload.items,
|
||||
transactionState: payload.transactionState
|
||||
);
|
||||
}
|
||||
|
|
@ -1,20 +1,23 @@
|
|||
import 'package:meta/meta.dart';
|
||||
import 'package:satu/core/models/auth/auth_response.dart';
|
||||
import 'package:satu/core/models/flow/product_dao.dart';
|
||||
import 'package:satu/core/models/flow/transaction_state.dart';
|
||||
|
||||
@immutable
|
||||
class SellState {
|
||||
final List<ProductDao> items;
|
||||
final TransactionState transactionState;
|
||||
|
||||
SellState({
|
||||
this.items,
|
||||
});
|
||||
SellState({this.items, this.transactionState});
|
||||
|
||||
factory SellState.initial() => SellState(
|
||||
items: [],
|
||||
transactionState: TransactionState(),
|
||||
);
|
||||
|
||||
SellState copyWith({@required List<ProductDao> items}) {
|
||||
return SellState(items: items ?? this.items);
|
||||
SellState copyWith({@required List<ProductDao> items, @required TransactionState transactionState}) {
|
||||
return SellState(items: items ?? this.items, transactionState: transactionState ?? this.transactionState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ import 'package:redux_persist_flutter/redux_persist_flutter.dart';
|
|||
import 'package:redux_thunk/redux_thunk.dart';
|
||||
import 'package:redux_persist/redux_persist.dart';
|
||||
import 'package:satu/core/redux/actions/nav_actions.dart';
|
||||
import 'package:satu/core/redux/actions/sell_actions.dart';
|
||||
import 'package:satu/core/redux/reducers/nav_reducer.dart';
|
||||
import 'package:satu/core/redux/reducers/sell_reducer.dart';
|
||||
import 'package:satu/core/redux/reducers/user_reducer.dart';
|
||||
import 'package:satu/core/redux/state/nav_state.dart';
|
||||
import 'package:satu/core/redux/state/sell_state.dart';
|
||||
|
|
@ -24,6 +26,10 @@ AppState appReducer(AppState state, dynamic action) {
|
|||
/** NavAction **/
|
||||
final nextState = navReducer(state.navState, action);
|
||||
return state.copyWith(navState: nextState);
|
||||
} else if (action is SetSellStateAction) {
|
||||
/** NavAction **/
|
||||
final nextState = sellReducer(state.sellState, action);
|
||||
return state.copyWith(sellState: nextState);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ class DbService extends BaseService {
|
|||
$TransactionColumnId integer primary key autoincrement,
|
||||
$TransactionColumnUuid text,
|
||||
$TransactionColumnType integer not null,
|
||||
$TransactionColumnAppCompanyId integer not null,
|
||||
$TransactionColumnStatus integer not null,
|
||||
$TransactionColumnData text,
|
||||
$TransactionColumnCreatedAt text not null
|
||||
);
|
||||
|
|
@ -98,15 +100,20 @@ class DbService extends BaseService {
|
|||
return await db.query(table);
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> queryRaw(String sql, List<dynamic> args) async {
|
||||
Database db = await instance.database;
|
||||
return await db.rawQuery(sql, args );
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> queryAllRowsOrderBy(String table, String orderBy) async {
|
||||
Database db = await instance.database;
|
||||
return await db.query(table, orderBy: orderBy);
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> queryRowsWithWhere(
|
||||
String table, String where, List<dynamic> args) async {
|
||||
String table, String where, List<dynamic> args, { String orderBy }) async {
|
||||
Database db = await instance.database;
|
||||
return await db.query(table, where: where, whereArgs: args);
|
||||
return await db.query(table, where: where, whereArgs: args, orderBy: orderBy);
|
||||
}
|
||||
|
||||
// All of the methods (insert, query, update, delete) can also be done using
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:satu/core/base/base_service.dart';
|
||||
import 'package:satu/core/entity/Category.dart';
|
||||
import 'package:satu/core/entity/Goods.dart';
|
||||
|
|
@ -49,7 +47,7 @@ class DictionaryService extends BaseService {
|
|||
List<Category> list = [];
|
||||
try {
|
||||
int appCompanyId = Redux.store.state.userState.auth.companyId;
|
||||
List<Map<String, dynamic>> elements = await _db.queryRowsWithWhere(CategoryTableName, '$CategoryColumnParentIn = ?', [parentId]);
|
||||
List<Map<String, dynamic>> elements = await _db.queryRowsWithWhere(CategoryTableName, '$CategoryColumnAppCompanyId = ? and $CategoryColumnParentIn = ?', [appCompanyId, parentId]);
|
||||
elements.forEach((element) {
|
||||
list.add(Category.fromMap(element));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
|||
case SettingPrinterBluetoothViewRoute:
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: PrinterSelectView(title: 'Принтер печати чеков',),
|
||||
//viewToShow: PrinterSelectView(title: 'Принтер печати чеков',),
|
||||
);
|
||||
// case ImageShowRoute:
|
||||
// ImageShowModel data = settings.arguments as ImageShowModel;
|
||||
|
|
|
|||
|
|
@ -9,10 +9,8 @@ import 'package:flutter_redux/flutter_redux.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
import 'package:satu/core/redux/actions/user_actions.dart';
|
||||
import 'package:satu/core/redux/constants/auth_type_const.dart';
|
||||
import 'package:satu/core/redux/state/user_state.dart';
|
||||
import 'package:satu/core/redux/store.dart';
|
||||
import 'package:satu/core/services/api_service.dart';
|
||||
import 'package:satu/core/services/dialog_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
import 'package:satu/shared/app_colors.dart';
|
||||
|
|
|
|||
|
|
@ -1,366 +1,366 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:charset_converter/charset_converter.dart';
|
||||
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
|
||||
import 'package:esc_pos_utils/esc_pos_utils.dart';
|
||||
import 'package:flutter/material.dart' hide Image;
|
||||
import 'package:image/image.dart' as Im;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class PrinterSelectView extends StatefulWidget {
|
||||
PrinterSelectView({Key key, this.title}) : super(key: key);
|
||||
final String title;
|
||||
|
||||
@override
|
||||
_PrinterSelectViewState createState() => _PrinterSelectViewState();
|
||||
}
|
||||
|
||||
class _PrinterSelectViewState extends State<PrinterSelectView> {
|
||||
PrinterBluetoothManager printerManager = PrinterBluetoothManager();
|
||||
List<PrinterBluetooth> _devices = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
printerManager.scanResults.listen((devices) async {
|
||||
// print('UI: Devices found ${devices.length}');
|
||||
setState(() {
|
||||
_devices = devices;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void _startScanDevices() {
|
||||
setState(() {
|
||||
_devices = [];
|
||||
});
|
||||
printerManager.startScan(Duration(seconds: 4));
|
||||
}
|
||||
|
||||
void _stopScanDevices() {
|
||||
printerManager.stopScan();
|
||||
}
|
||||
|
||||
Future<Ticket> demoReceipt(PaperSize paper) async {
|
||||
final Ticket ticket = Ticket(paper, );
|
||||
|
||||
// Print image
|
||||
final ByteData data = await rootBundle.load('assets/images/aman_kassa_check.png');
|
||||
final Uint8List bytes = data.buffer.asUint8List();
|
||||
final Im.Image image = Im.decodeImage(bytes);
|
||||
Im.Image thumbnail = Im.copyResize(image, width: 270);
|
||||
// ticket.image(thumbnail, align: PosAlign.center);
|
||||
|
||||
//ticket.imageRaster(image, align: PosAlign.center);
|
||||
|
||||
ticket.text('AMAN-SATU',
|
||||
styles: PosStyles(
|
||||
align: PosAlign.center,
|
||||
height: PosTextSize.size2,
|
||||
width: PosTextSize.size2,
|
||||
),
|
||||
linesAfter: 1);
|
||||
|
||||
ticket.text('889 Watson Lane', styles: PosStyles(align: PosAlign.center));
|
||||
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, codeTable: PosCodeTable.westEur), containsChinese: true);
|
||||
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, fontType: PosFontType.fontA), containsChinese: true);
|
||||
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, fontType: PosFontType.fontB), containsChinese: true);
|
||||
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, height: PosTextSize.size1), containsChinese: true);
|
||||
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, width: PosTextSize.size2), containsChinese: true);
|
||||
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, width: PosTextSize.size3), containsChinese: true);
|
||||
ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, width: PosTextSize.size4), containsChinese: true);
|
||||
ticket.text('Tel: 830-221-1234', styles: PosStyles(align: PosAlign.center));
|
||||
ticket.text('Web: www.example.com',
|
||||
styles: PosStyles(align: PosAlign.center), linesAfter: 1);
|
||||
|
||||
ticket.hr();
|
||||
ticket.row([
|
||||
PosColumn(text: 'Qty', width: 1),
|
||||
PosColumn(text: 'Item', width: 7),
|
||||
PosColumn(
|
||||
text: 'Price', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
PosColumn(
|
||||
text: 'Total', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
]);
|
||||
|
||||
ticket.row([
|
||||
PosColumn(text: '2', width: 1),
|
||||
PosColumn(text: 'ONION RINGS', width: 7),
|
||||
PosColumn(
|
||||
text: '0.99', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
PosColumn(
|
||||
text: '1.98', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
]);
|
||||
ticket.row([
|
||||
PosColumn(text: '1', width: 1),
|
||||
PosColumn(text: 'PIZZA', width: 7),
|
||||
PosColumn(
|
||||
text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
PosColumn(
|
||||
text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
]);
|
||||
ticket.row([
|
||||
PosColumn(text: '1', width: 1),
|
||||
PosColumn(text: 'SPRING ROLLS', width: 7),
|
||||
PosColumn(
|
||||
text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
PosColumn(
|
||||
text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
]);
|
||||
ticket.row([
|
||||
PosColumn(text: '3', width: 1),
|
||||
PosColumn(text: 'CRUNCHY STICKS', width: 7),
|
||||
PosColumn(
|
||||
text: '0.85', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
PosColumn(
|
||||
text: '2.55', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
]);
|
||||
ticket.hr();
|
||||
|
||||
ticket.row([
|
||||
PosColumn(
|
||||
text: 'TOTAL',
|
||||
width: 6,
|
||||
styles: PosStyles(
|
||||
height: PosTextSize.size2,
|
||||
width: PosTextSize.size2,
|
||||
)),
|
||||
PosColumn(
|
||||
text: '\$10.97',
|
||||
width: 6,
|
||||
styles: PosStyles(
|
||||
align: PosAlign.right,
|
||||
height: PosTextSize.size2,
|
||||
width: PosTextSize.size2,
|
||||
)),
|
||||
]);
|
||||
|
||||
ticket.hr(ch: '=', linesAfter: 1);
|
||||
|
||||
ticket.row([
|
||||
PosColumn(
|
||||
text: 'Cash',
|
||||
width: 7,
|
||||
styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||
PosColumn(
|
||||
text: '\$15.00',
|
||||
width: 5,
|
||||
styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||
]);
|
||||
ticket.row([
|
||||
PosColumn(
|
||||
text: 'Change',
|
||||
width: 7,
|
||||
styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||
PosColumn(
|
||||
text: '\$4.03',
|
||||
width: 5,
|
||||
styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||
]);
|
||||
|
||||
ticket.feed(2);
|
||||
ticket.text('Thank you!',
|
||||
styles: PosStyles(align: PosAlign.center, bold: true));
|
||||
|
||||
final now = DateTime.now();
|
||||
final formatter = DateFormat('MM/dd/yyyy H:m');
|
||||
final String timestamp = formatter.format(now);
|
||||
ticket.text(timestamp,
|
||||
styles: PosStyles(align: PosAlign.center), linesAfter: 2);
|
||||
|
||||
// Print QR Code from image
|
||||
// try {
|
||||
// const String qrData = 'example.com';
|
||||
// const double qrSize = 200;
|
||||
// final uiImg = await QrPainter(
|
||||
// data: qrData,
|
||||
// version: QrVersions.auto,
|
||||
// gapless: false,
|
||||
// ).toImageData(qrSize);
|
||||
// final dir = await getTemporaryDirectory();
|
||||
// final pathName = '${dir.path}/qr_tmp.png';
|
||||
// final qrFile = File(pathName);
|
||||
// final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List());
|
||||
// final img = decodeImage(imgFile.readAsBytesSync());
|
||||
|
||||
// ticket.image(img);
|
||||
// } catch (e) {
|
||||
// print(e);
|
||||
// }
|
||||
|
||||
// Print QR Code using native function
|
||||
// ticket.qrcode('example.com');
|
||||
|
||||
ticket.feed(2);
|
||||
ticket.cut();
|
||||
return ticket;
|
||||
}
|
||||
|
||||
Future<Ticket> testTicket(PaperSize paper) async {
|
||||
final Ticket ticket = Ticket(paper);
|
||||
Uint8List encTxt4 =
|
||||
await CharsetConverter.encode("cp866", "Russian: Привет Мир!");
|
||||
ticket.textEncoded(encTxt4,
|
||||
styles: PosStyles(codeTable: PosCodeTable.pc866_2));
|
||||
|
||||
ticket.text('Kazakh: Сәлем Әлем!',
|
||||
styles: PosStyles(codeTable: PosCodeTable.westEur), containsChinese: true);
|
||||
|
||||
// Uint8List encTxt1 =
|
||||
// await CharsetConverter.encode("utf-8", "Kazakh: Сәлем Әлем!");
|
||||
// ticket.textEncoded(encTxt1,
|
||||
// styles: PosStyles(codeTable: PosCodeTable.pc866_2));
|
||||
ticket.text(
|
||||
'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ');
|
||||
ticket.text('Special 1: àÀ èÈ éÉ ûÛ üÜ çÇ ôÔ',
|
||||
styles: PosStyles(codeTable: PosCodeTable.westEur));
|
||||
ticket.text('Special 2: blåbærgrød',
|
||||
styles: PosStyles(codeTable: PosCodeTable.westEur));
|
||||
|
||||
ticket.text('Bold text', styles: PosStyles(bold: true));
|
||||
ticket.text('Reverse text', styles: PosStyles(reverse: true));
|
||||
ticket.text('Underlined text',
|
||||
styles: PosStyles(underline: true), linesAfter: 1);
|
||||
ticket.text('Align left', styles: PosStyles(align: PosAlign.left));
|
||||
ticket.text('Align center', styles: PosStyles(align: PosAlign.center));
|
||||
ticket.text('Align right',
|
||||
styles: PosStyles(align: PosAlign.right), linesAfter: 1);
|
||||
|
||||
ticket.row([
|
||||
PosColumn(
|
||||
text: 'col3',
|
||||
width: 3,
|
||||
styles: PosStyles(align: PosAlign.center, underline: true),
|
||||
),
|
||||
PosColumn(
|
||||
text: 'col6',
|
||||
width: 6,
|
||||
styles: PosStyles(align: PosAlign.center, underline: true),
|
||||
),
|
||||
PosColumn(
|
||||
text: 'col3',
|
||||
width: 3,
|
||||
styles: PosStyles(align: PosAlign.center, underline: true),
|
||||
),
|
||||
]);
|
||||
|
||||
ticket.text('Text size 200%',
|
||||
styles: PosStyles(
|
||||
height: PosTextSize.size2,
|
||||
width: PosTextSize.size2,
|
||||
));
|
||||
|
||||
// Print image
|
||||
//final ByteData data = await rootBundle.load('assets/images/logo.png');
|
||||
//final Uint8List bytes = data.buffer.asUint8List();
|
||||
// Print image using alternative commands
|
||||
// ticket.imageRaster(image);
|
||||
// ticket.imageRaster(image, imageFn: PosImageFn.graphics);
|
||||
|
||||
// Print barcode
|
||||
final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
|
||||
ticket.barcode(Barcode.upcA(barData));
|
||||
|
||||
// Print mixed (chinese + latin) text. Only for printers supporting Kanji mode
|
||||
ticket.text(
|
||||
'hello ! 中文字 # world @ éphémère &',
|
||||
styles: PosStyles(codeTable: PosCodeTable.westEur),
|
||||
containsChinese: true,
|
||||
);
|
||||
|
||||
ticket.text(
|
||||
'hello ! Мир # world @ éphémère &',
|
||||
styles: PosStyles(codeTable: PosCodeTable.westEur),
|
||||
containsChinese: true,
|
||||
);
|
||||
|
||||
ticket.feed(2);
|
||||
|
||||
ticket.cut();
|
||||
return ticket;
|
||||
}
|
||||
|
||||
void _testPrint(PrinterBluetooth printer) async {
|
||||
printerManager.selectPrinter(printer);
|
||||
|
||||
// TODO Don't forget to choose printer's paper
|
||||
const PaperSize paper = PaperSize.mm58;
|
||||
|
||||
// TEST PRINT
|
||||
// final PosPrintResult res =
|
||||
// await printerManager.printTicket(await testTicket(paper));
|
||||
|
||||
// DEMO RECEIPT
|
||||
final PosPrintResult res =
|
||||
await printerManager.printTicket(await testTicket(paper) , queueSleepTimeMs: 50);
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: ListView.builder(
|
||||
itemCount: _devices.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return InkWell(
|
||||
onTap: () => _testPrint(_devices[index]),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: 60,
|
||||
padding: EdgeInsets.only(left: 10),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(Icons.print),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(_devices[index].name ?? ''),
|
||||
Text(_devices[index].address),
|
||||
Text(
|
||||
'Click to print a test receipt',
|
||||
style: TextStyle(color: Colors.grey[700]),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
floatingActionButton: StreamBuilder<bool>(
|
||||
stream: printerManager.isScanningStream,
|
||||
initialData: false,
|
||||
builder: (c, snapshot) {
|
||||
if (snapshot.data) {
|
||||
return FloatingActionButton(
|
||||
child: Icon(Icons.stop),
|
||||
onPressed: _stopScanDevices,
|
||||
backgroundColor: Colors.red,
|
||||
);
|
||||
} else {
|
||||
return FloatingActionButton(
|
||||
child: Icon(Icons.search),
|
||||
onPressed: _startScanDevices,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
// import 'dart:convert';
|
||||
// import 'dart:typed_data';
|
||||
//
|
||||
// import 'package:charset_converter/charset_converter.dart';
|
||||
// import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
|
||||
// import 'package:esc_pos_utils/esc_pos_utils.dart';
|
||||
// import 'package:flutter/material.dart' hide Image;
|
||||
// import 'package:image/image.dart' as Im;
|
||||
// import 'package:flutter/services.dart';
|
||||
// import 'package:intl/intl.dart';
|
||||
//
|
||||
// class PrinterSelectView extends StatefulWidget {
|
||||
// PrinterSelectView({Key key, this.title}) : super(key: key);
|
||||
// final String title;
|
||||
//
|
||||
// @override
|
||||
// _PrinterSelectViewState createState() => _PrinterSelectViewState();
|
||||
// }
|
||||
//
|
||||
// class _PrinterSelectViewState extends State<PrinterSelectView> {
|
||||
// // PrinterBluetoothManager printerManager = PrinterBluetoothManager();
|
||||
// // List<PrinterBluetooth> _devices = [];
|
||||
//
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
//
|
||||
// printerManager.scanResults.listen((devices) async {
|
||||
// // print('UI: Devices found ${devices.length}');
|
||||
// setState(() {
|
||||
// _devices = devices;
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// void _startScanDevices() {
|
||||
// setState(() {
|
||||
// _devices = [];
|
||||
// });
|
||||
// printerManager.startScan(Duration(seconds: 4));
|
||||
// }
|
||||
//
|
||||
// void _stopScanDevices() {
|
||||
// printerManager.stopScan();
|
||||
// }
|
||||
//
|
||||
// Future<Ticket> demoReceipt(PaperSize paper) async {
|
||||
// final Ticket ticket = Ticket(paper, );
|
||||
//
|
||||
// // Print image
|
||||
// final ByteData data = await rootBundle.load('assets/images/aman_kassa_check.png');
|
||||
// final Uint8List bytes = data.buffer.asUint8List();
|
||||
// final Im.Image image = Im.decodeImage(bytes);
|
||||
// Im.Image thumbnail = Im.copyResize(image, width: 270);
|
||||
// // ticket.image(thumbnail, align: PosAlign.center);
|
||||
//
|
||||
// //ticket.imageRaster(image, align: PosAlign.center);
|
||||
//
|
||||
// ticket.text('AMAN-SATU',
|
||||
// styles: PosStyles(
|
||||
// align: PosAlign.center,
|
||||
// height: PosTextSize.size2,
|
||||
// width: PosTextSize.size2,
|
||||
// ),
|
||||
// linesAfter: 1);
|
||||
//
|
||||
// ticket.text('889 Watson Lane', styles: PosStyles(align: PosAlign.center));
|
||||
// ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, codeTable: PosCodeTable.westEur), containsChinese: true);
|
||||
// ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, fontType: PosFontType.fontA), containsChinese: true);
|
||||
// ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, fontType: PosFontType.fontB), containsChinese: true);
|
||||
// ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, height: PosTextSize.size1), containsChinese: true);
|
||||
// ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, width: PosTextSize.size2), containsChinese: true);
|
||||
// ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, width: PosTextSize.size3), containsChinese: true);
|
||||
// ticket.text('Русский язык', styles: PosStyles(align: PosAlign.center, width: PosTextSize.size4), containsChinese: true);
|
||||
// ticket.text('Tel: 830-221-1234', styles: PosStyles(align: PosAlign.center));
|
||||
// ticket.text('Web: www.example.com',
|
||||
// styles: PosStyles(align: PosAlign.center), linesAfter: 1);
|
||||
//
|
||||
// ticket.hr();
|
||||
// ticket.row([
|
||||
// PosColumn(text: 'Qty', width: 1),
|
||||
// PosColumn(text: 'Item', width: 7),
|
||||
// PosColumn(
|
||||
// text: 'Price', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// PosColumn(
|
||||
// text: 'Total', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// ]);
|
||||
//
|
||||
// ticket.row([
|
||||
// PosColumn(text: '2', width: 1),
|
||||
// PosColumn(text: 'ONION RINGS', width: 7),
|
||||
// PosColumn(
|
||||
// text: '0.99', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// PosColumn(
|
||||
// text: '1.98', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// ]);
|
||||
// ticket.row([
|
||||
// PosColumn(text: '1', width: 1),
|
||||
// PosColumn(text: 'PIZZA', width: 7),
|
||||
// PosColumn(
|
||||
// text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// PosColumn(
|
||||
// text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// ]);
|
||||
// ticket.row([
|
||||
// PosColumn(text: '1', width: 1),
|
||||
// PosColumn(text: 'SPRING ROLLS', width: 7),
|
||||
// PosColumn(
|
||||
// text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// PosColumn(
|
||||
// text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// ]);
|
||||
// ticket.row([
|
||||
// PosColumn(text: '3', width: 1),
|
||||
// PosColumn(text: 'CRUNCHY STICKS', width: 7),
|
||||
// PosColumn(
|
||||
// text: '0.85', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// PosColumn(
|
||||
// text: '2.55', width: 2, styles: PosStyles(align: PosAlign.right)),
|
||||
// ]);
|
||||
// ticket.hr();
|
||||
//
|
||||
// ticket.row([
|
||||
// PosColumn(
|
||||
// text: 'TOTAL',
|
||||
// width: 6,
|
||||
// styles: PosStyles(
|
||||
// height: PosTextSize.size2,
|
||||
// width: PosTextSize.size2,
|
||||
// )),
|
||||
// PosColumn(
|
||||
// text: '\$10.97',
|
||||
// width: 6,
|
||||
// styles: PosStyles(
|
||||
// align: PosAlign.right,
|
||||
// height: PosTextSize.size2,
|
||||
// width: PosTextSize.size2,
|
||||
// )),
|
||||
// ]);
|
||||
//
|
||||
// ticket.hr(ch: '=', linesAfter: 1);
|
||||
//
|
||||
// ticket.row([
|
||||
// PosColumn(
|
||||
// text: 'Cash',
|
||||
// width: 7,
|
||||
// styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||
// PosColumn(
|
||||
// text: '\$15.00',
|
||||
// width: 5,
|
||||
// styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||
// ]);
|
||||
// ticket.row([
|
||||
// PosColumn(
|
||||
// text: 'Change',
|
||||
// width: 7,
|
||||
// styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||
// PosColumn(
|
||||
// text: '\$4.03',
|
||||
// width: 5,
|
||||
// styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
|
||||
// ]);
|
||||
//
|
||||
// ticket.feed(2);
|
||||
// ticket.text('Thank you!',
|
||||
// styles: PosStyles(align: PosAlign.center, bold: true));
|
||||
//
|
||||
// final now = DateTime.now();
|
||||
// final formatter = DateFormat('MM/dd/yyyy H:m');
|
||||
// final String timestamp = formatter.format(now);
|
||||
// ticket.text(timestamp,
|
||||
// styles: PosStyles(align: PosAlign.center), linesAfter: 2);
|
||||
//
|
||||
// // Print QR Code from image
|
||||
// // try {
|
||||
// // const String qrData = 'example.com';
|
||||
// // const double qrSize = 200;
|
||||
// // final uiImg = await QrPainter(
|
||||
// // data: qrData,
|
||||
// // version: QrVersions.auto,
|
||||
// // gapless: false,
|
||||
// // ).toImageData(qrSize);
|
||||
// // final dir = await getTemporaryDirectory();
|
||||
// // final pathName = '${dir.path}/qr_tmp.png';
|
||||
// // final qrFile = File(pathName);
|
||||
// // final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List());
|
||||
// // final img = decodeImage(imgFile.readAsBytesSync());
|
||||
//
|
||||
// // ticket.image(img);
|
||||
// // } catch (e) {
|
||||
// // print(e);
|
||||
// // }
|
||||
//
|
||||
// // Print QR Code using native function
|
||||
// // ticket.qrcode('example.com');
|
||||
//
|
||||
// ticket.feed(2);
|
||||
// ticket.cut();
|
||||
// return ticket;
|
||||
// }
|
||||
//
|
||||
// Future<Ticket> testTicket(PaperSize paper) async {
|
||||
// final Ticket ticket = Ticket(paper);
|
||||
// Uint8List encTxt4 =
|
||||
// await CharsetConverter.encode("cp866", "Russian: Привет Мир!");
|
||||
// ticket.textEncoded(encTxt4,
|
||||
// styles: PosStyles(codeTable: PosCodeTable.pc866_2));
|
||||
//
|
||||
// ticket.text('Kazakh: Сәлем Әлем!',
|
||||
// styles: PosStyles(codeTable: PosCodeTable.westEur), containsChinese: true);
|
||||
//
|
||||
// // Uint8List encTxt1 =
|
||||
// // await CharsetConverter.encode("utf-8", "Kazakh: Сәлем Әлем!");
|
||||
// // ticket.textEncoded(encTxt1,
|
||||
// // styles: PosStyles(codeTable: PosCodeTable.pc866_2));
|
||||
// ticket.text(
|
||||
// 'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ');
|
||||
// ticket.text('Special 1: àÀ èÈ éÉ ûÛ üÜ çÇ ôÔ',
|
||||
// styles: PosStyles(codeTable: PosCodeTable.westEur));
|
||||
// ticket.text('Special 2: blåbærgrød',
|
||||
// styles: PosStyles(codeTable: PosCodeTable.westEur));
|
||||
//
|
||||
// ticket.text('Bold text', styles: PosStyles(bold: true));
|
||||
// ticket.text('Reverse text', styles: PosStyles(reverse: true));
|
||||
// ticket.text('Underlined text',
|
||||
// styles: PosStyles(underline: true), linesAfter: 1);
|
||||
// ticket.text('Align left', styles: PosStyles(align: PosAlign.left));
|
||||
// ticket.text('Align center', styles: PosStyles(align: PosAlign.center));
|
||||
// ticket.text('Align right',
|
||||
// styles: PosStyles(align: PosAlign.right), linesAfter: 1);
|
||||
//
|
||||
// ticket.row([
|
||||
// PosColumn(
|
||||
// text: 'col3',
|
||||
// width: 3,
|
||||
// styles: PosStyles(align: PosAlign.center, underline: true),
|
||||
// ),
|
||||
// PosColumn(
|
||||
// text: 'col6',
|
||||
// width: 6,
|
||||
// styles: PosStyles(align: PosAlign.center, underline: true),
|
||||
// ),
|
||||
// PosColumn(
|
||||
// text: 'col3',
|
||||
// width: 3,
|
||||
// styles: PosStyles(align: PosAlign.center, underline: true),
|
||||
// ),
|
||||
// ]);
|
||||
//
|
||||
// ticket.text('Text size 200%',
|
||||
// styles: PosStyles(
|
||||
// height: PosTextSize.size2,
|
||||
// width: PosTextSize.size2,
|
||||
// ));
|
||||
//
|
||||
// // Print image
|
||||
// //final ByteData data = await rootBundle.load('assets/images/logo.png');
|
||||
// //final Uint8List bytes = data.buffer.asUint8List();
|
||||
// // Print image using alternative commands
|
||||
// // ticket.imageRaster(image);
|
||||
// // ticket.imageRaster(image, imageFn: PosImageFn.graphics);
|
||||
//
|
||||
// // Print barcode
|
||||
// final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
|
||||
// ticket.barcode(Barcode.upcA(barData));
|
||||
//
|
||||
// // Print mixed (chinese + latin) text. Only for printers supporting Kanji mode
|
||||
// ticket.text(
|
||||
// 'hello ! 中文字 # world @ éphémère &',
|
||||
// styles: PosStyles(codeTable: PosCodeTable.westEur),
|
||||
// containsChinese: true,
|
||||
// );
|
||||
//
|
||||
// ticket.text(
|
||||
// 'hello ! Мир # world @ éphémère &',
|
||||
// styles: PosStyles(codeTable: PosCodeTable.westEur),
|
||||
// containsChinese: true,
|
||||
// );
|
||||
//
|
||||
// ticket.feed(2);
|
||||
//
|
||||
// ticket.cut();
|
||||
// return ticket;
|
||||
// }
|
||||
//
|
||||
// void _testPrint(PrinterBluetooth printer) async {
|
||||
// printerManager.selectPrinter(printer);
|
||||
//
|
||||
// // TODO Don't forget to choose printer's paper
|
||||
// const PaperSize paper = PaperSize.mm58;
|
||||
//
|
||||
// // TEST PRINT
|
||||
// // final PosPrintResult res =
|
||||
// // await printerManager.printTicket(await testTicket(paper));
|
||||
//
|
||||
// // DEMO RECEIPT
|
||||
// final PosPrintResult res =
|
||||
// await printerManager.printTicket(await testTicket(paper) , queueSleepTimeMs: 50);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Scaffold(
|
||||
// appBar: AppBar(
|
||||
// title: Text(widget.title),
|
||||
// ),
|
||||
// body: ListView.builder(
|
||||
// itemCount: _devices.length,
|
||||
// itemBuilder: (BuildContext context, int index) {
|
||||
// return InkWell(
|
||||
// onTap: () => _testPrint(_devices[index]),
|
||||
// child: Column(
|
||||
// children: <Widget>[
|
||||
// Container(
|
||||
// height: 60,
|
||||
// padding: EdgeInsets.only(left: 10),
|
||||
// alignment: Alignment.centerLeft,
|
||||
// child: Row(
|
||||
// children: <Widget>[
|
||||
// Icon(Icons.print),
|
||||
// SizedBox(width: 10),
|
||||
// Expanded(
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: <Widget>[
|
||||
// Text(_devices[index].name ?? ''),
|
||||
// Text(_devices[index].address),
|
||||
// Text(
|
||||
// 'Click to print a test receipt',
|
||||
// style: TextStyle(color: Colors.grey[700]),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// Divider(),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }),
|
||||
// floatingActionButton: StreamBuilder<bool>(
|
||||
// stream: printerManager.isScanningStream,
|
||||
// initialData: false,
|
||||
// builder: (c, snapshot) {
|
||||
// if (snapshot.data) {
|
||||
// return FloatingActionButton(
|
||||
// child: Icon(Icons.stop),
|
||||
// onPressed: _stopScanDevices,
|
||||
// backgroundColor: Colors.red,
|
||||
// );
|
||||
// } else {
|
||||
// return FloatingActionButton(
|
||||
// child: Icon(Icons.search),
|
||||
// onPressed: _startScanDevices,
|
||||
// );
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:satu/core/models/flow/product_dao.dart';
|
||||
import 'package:satu/core/redux/state/sell_state.dart';
|
||||
import 'package:satu/core/redux/store.dart';
|
||||
import 'package:satu/core/services/navigator_service.dart';
|
||||
import 'package:satu/core/utils/locator.dart';
|
||||
import 'package:satu/routes/route_names.dart';
|
||||
|
|
@ -6,44 +10,50 @@ import 'package:satu/shared/app_colors.dart';
|
|||
import 'package:satu/views/work/tabs/component/product_list_item.dart';
|
||||
import 'package:satu/views/work/tabs/component/products_app_bar.dart';
|
||||
import 'package:satu/views/work/tabs/component/products_header_bar.dart';
|
||||
import 'package:satu/views/work/tabs/utils/ProductUtils.dart';
|
||||
|
||||
class SellView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: ProductsAppBar(
|
||||
title: 'Продажа',
|
||||
actions: actions(),
|
||||
elevation: 2.0,
|
||||
child: ProductHeaderBar(
|
||||
count: 14,
|
||||
sum: 25000,
|
||||
),
|
||||
backgroundColor: backgroundColor,
|
||||
childHeight: 80,
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
//ProductHeaderBar(count: 14, sum: 25000,),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemCount: 5,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ProductListItem(
|
||||
ean: '1234567890123',
|
||||
isOdd: index % 2 == 0,
|
||||
name:
|
||||
'Хлеб ржаной который необходимо покупать каждый раз когда придет мысль об этом - ${index + 1}. ',
|
||||
price: 75,
|
||||
count: 15,
|
||||
categoryName: 'Хлебобулочные изделия',
|
||||
);
|
||||
},
|
||||
return StoreConnector<AppState, SellState>(
|
||||
converter: (store) => store.state.sellState,
|
||||
builder: (_, state) {
|
||||
return Scaffold(
|
||||
appBar: ProductsAppBar(
|
||||
title: 'Продажа',
|
||||
actions: actions(),
|
||||
elevation: 2.0,
|
||||
child: ProductHeaderBar(
|
||||
count: state.items.length,
|
||||
sum: sumProducts(state.items),
|
||||
),
|
||||
backgroundColor: backgroundColor,
|
||||
childHeight: 80,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
//ProductHeaderBar(count: 14, sum: 25000,),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemCount: state.items.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
ProductDao product = state.items.elementAt(index);
|
||||
return ProductListItem(
|
||||
ean: product.eanCode,
|
||||
isOdd: index % 2 == 0,
|
||||
name: product.productName,
|
||||
price: product.price,
|
||||
count: product.count,
|
||||
categoryName: product.productName,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
import 'package:satu/core/models/flow/product_dao.dart';
|
||||
|
||||
num sumProducts(List<ProductDao> list) {
|
||||
num result = 0.0;
|
||||
if (list.isNotEmpty) {
|
||||
list.forEach((product) {
|
||||
result += (product.price * product.count);
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
41
pubspec.lock
41
pubspec.lock
|
|
@ -127,20 +127,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
esc_pos_bluetooth:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: esc_pos_bluetooth
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.8"
|
||||
esc_pos_utils:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: esc_pos_utils
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.6"
|
||||
version: "1.0.0"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -174,13 +167,6 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_bluetooth_basic:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_bluetooth_basic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
flutter_redux:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -218,7 +204,7 @@ packages:
|
|||
name: get_it
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.1"
|
||||
version: "7.1.2"
|
||||
hex:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -239,7 +225,7 @@ packages:
|
|||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.13.2"
|
||||
version: "0.13.3"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -275,13 +261,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.3"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
logger:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -471,13 +450,6 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.1"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: rxdart
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.23.1"
|
||||
searchable_dropdown:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -644,6 +616,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+3"
|
||||
uuid:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: uuid
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -36,16 +36,15 @@ dependencies:
|
|||
responsive_builder: ^0.4.1
|
||||
provider: ^5.0.0
|
||||
logger: ^1.0.0
|
||||
get_it: ^6.1.1
|
||||
get_it: ^7.1.2
|
||||
equatable: ^2.0.0
|
||||
http: ^0.13.2
|
||||
http: ^0.13.3
|
||||
sqflite: ^2.0.0+3
|
||||
path_provider: ^2.0.1
|
||||
material_design_icons_flutter: ^4.0.5955
|
||||
intl: ^0.17.0
|
||||
barcode_scan: ^3.0.1
|
||||
device_info: ^2.0.0
|
||||
#esys_flutter_share: ^1.0.2
|
||||
auto_size_text: ^2.1.0
|
||||
url_launcher: ^5.7.10
|
||||
qr_flutter: ^4.0.0
|
||||
|
|
@ -55,8 +54,8 @@ dependencies:
|
|||
searchable_dropdown: ^1.1.3
|
||||
material_floating_search_bar: ^0.3.4
|
||||
implicitly_animated_reorderable_list: ^0.4.0
|
||||
esc_pos_bluetooth: ^0.2.8
|
||||
esc_pos_utils: ^0.3.6 # for esc_pos_bluetooth: ^0.2.8
|
||||
esc_pos_utils: ^1.0.0
|
||||
uuid: ^2.2.2 #for esc_pos_utils: ^1.0.0
|
||||
charset_converter: ^2.0.0
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
|||
Loading…
Reference in New Issue