asdasdasd

This commit is contained in:
Phuoc Nguyen
2025-10-29 16:31:04 +07:00
parent c12869b01f
commit efcc6306b0
6 changed files with 4351 additions and 17 deletions

View File

@@ -21,16 +21,25 @@ class PrintService {
String? responsibleName,
String? barcodeData,
}) async {
// Load Vietnamese-compatible fonts using PdfGoogleFonts
// Noto Sans has excellent Vietnamese character support
final fontRegular = await PdfGoogleFonts.notoSansRegular();
final fontBold = await PdfGoogleFonts.notoSansBold();
final pdf = pw.Document();
// Format current date
final dt = DateFormat('dd/MM/yyyy HH:mm').format(DateTime.now());
// Add page to PDF
// Add page to PDF with theme for Vietnamese font support
pdf.addPage(
pw.Page(
pageFormat: PdfPageFormat.a4,
margin: const pw.EdgeInsets.all(12),
theme: pw.ThemeData.withFont(
base: fontRegular,
bold: fontBold,
),
build: (pw.Context pdfContext) {
return pw.Container(
padding: const pw.EdgeInsets.all(12),

View File

@@ -362,12 +362,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
title: 'Thêm số lượng mới',
icon: Icons.add_circle_outline,
children: [
_buildTextField(
label: 'Số lượng đạt',
controller: _passedQuantityController,
keyboardType: TextInputType.number,
theme: theme,
),
_buildTextField(
label: 'Khối lượng đạt (kg)',
controller: _passedWeightController,
@@ -375,8 +370,8 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
theme: theme,
),
_buildTextField(
label: 'Số lượng lỗi',
controller: _issuedQuantityController,
label: 'Số lượng đạt',
controller: _passedQuantityController,
keyboardType: TextInputType.number,
theme: theme,
),
@@ -386,13 +381,20 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
keyboardType: const TextInputType.numberWithOptions(decimal: true),
theme: theme,
),
_buildTextField(
label: 'Số lượng lỗi',
controller: _issuedQuantityController,
keyboardType: TextInputType.number,
theme: theme,
),
],
),
_buildSectionCard(theme: theme, title: "Nhân viên", icon: Icons.people, children: [
// Warehouse User Dropdown
// Warehouse User Dropdown (Required)
_buildUserDropdown(
label: 'Người dùng kho',
label: 'Người dùng kho *',
value: _selectedWarehouseUser,
users: ref.watch(usersListProvider)
.where((user) => user.isWareHouseUser)
@@ -405,9 +407,9 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
theme: theme,
),
const SizedBox(height: 8),
// All Employees Dropdown
// All Employees Dropdown (Required)
_buildUserDropdown(
label: 'Nhân viên',
label: 'Nhân viên *',
value: _selectedEmployee,
users: ref.watch(usersListProvider),
onChanged: (user) {
@@ -448,6 +450,18 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
}
Future<void> _printQuantities(ProductStageEntity stage) async {
// Validate that both users are selected
if (_selectedEmployee == null || _selectedWarehouseUser == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Vui lòng chọn cả Nhân viên và Người dùng kho trước khi in'),
backgroundColor: Colors.orange,
duration: Duration(seconds: 3),
),
);
return;
}
// Get the current quantity values (entered by user or use current values)
final passedQuantity = int.tryParse(_passedQuantityController.text) ?? 0;
final passedWeight = double.tryParse(_passedWeightController.text) ?? 0.0;
@@ -461,9 +475,7 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
final finalIssuedKg = issuedWeight > 0.0 ? issuedWeight : stage.issuedQuantityWeight;
// Get responsible user name
final responsibleName = _selectedWarehouseUser != null
? '${_selectedWarehouseUser!.name} ${_selectedWarehouseUser!.firstName}'
: null;
final responsibleName = '${_selectedWarehouseUser!.name} ${_selectedWarehouseUser!.firstName}';
// Generate barcode data (using product code or product ID)
final barcodeData = stage.productCode.isNotEmpty
@@ -521,8 +533,9 @@ class _ProductDetailPageState extends ConsumerState<ProductDetailPage> {
if (_selectedEmployee == null || _selectedWarehouseUser == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Vui lòng chọn cả Nhân viên và Người dùng kho'),
content: Text('Vui lòng chọn cả Nhân viên và Người dùng kho trước khi lưu'),
backgroundColor: Colors.orange,
duration: Duration(seconds: 3),
),
);
return;