백엔드 계약 문서 동기화하고 DTO 파서 정합성 확장
This commit is contained in:
@@ -44,38 +44,83 @@ class ApprovalDto {
|
||||
|
||||
/// API 응답 JSON을 [ApprovalDto]로 변환한다.
|
||||
factory ApprovalDto.fromJson(Map<String, dynamic> json) {
|
||||
final approvalEnvelope = _mapOrEmpty(json['approval']);
|
||||
final statusMap = _firstNonEmptyMap([
|
||||
json['status'],
|
||||
json['approval_status'],
|
||||
approvalEnvelope['status'],
|
||||
approvalEnvelope['approval_status'],
|
||||
]);
|
||||
final requesterMap = _firstNonEmptyMap([
|
||||
json['requester'],
|
||||
json['requested_by'],
|
||||
approvalEnvelope['requester'],
|
||||
approvalEnvelope['requested_by'],
|
||||
]);
|
||||
final currentStepMap = _firstNonEmptyMap([
|
||||
json['current_step'],
|
||||
json['currentStep'],
|
||||
approvalEnvelope['current_step'],
|
||||
]);
|
||||
final transactionMap = _mapOrEmpty(json['transaction']);
|
||||
final envelopeTransactionMap = _mapOrEmpty(approvalEnvelope['transaction']);
|
||||
var stepsSource = _asListOfMap(json['steps']);
|
||||
if (stepsSource.isEmpty) {
|
||||
stepsSource = _asListOfMap(approvalEnvelope['steps']);
|
||||
}
|
||||
var historiesSource = _asListOfMap(json['histories']);
|
||||
if (historiesSource.isEmpty) {
|
||||
historiesSource = _asListOfMap(approvalEnvelope['histories']);
|
||||
}
|
||||
final currentStepDto = currentStepMap.isEmpty
|
||||
? null
|
||||
: ApprovalStepDto.fromJson(currentStepMap);
|
||||
|
||||
final approvalNo =
|
||||
_pickString(
|
||||
[json, approvalEnvelope],
|
||||
const ['approval_no', 'approvalNo'],
|
||||
) ??
|
||||
'-';
|
||||
final transactionNo = _pickString(
|
||||
[json, transactionMap, approvalEnvelope, envelopeTransactionMap],
|
||||
const ['transaction_no', 'transactionNo'],
|
||||
);
|
||||
|
||||
return ApprovalDto(
|
||||
id: json['id'] as int?,
|
||||
approvalNo: json['approval_no'] as String,
|
||||
transactionNo: json['transaction'] is Map<String, dynamic>
|
||||
? (json['transaction']['transaction_no'] as String?)
|
||||
: json['transaction_no'] as String?,
|
||||
status: ApprovalStatusDto.fromJson(
|
||||
(json['status'] as Map<String, dynamic>? ?? const {}),
|
||||
id: json['id'] as int? ?? approvalEnvelope['id'] as int?,
|
||||
approvalNo: approvalNo,
|
||||
transactionNo: transactionNo,
|
||||
status: ApprovalStatusDto.fromJson(statusMap),
|
||||
currentStep: currentStepDto,
|
||||
requester: ApprovalRequesterDto.fromJson(requesterMap),
|
||||
requestedAt:
|
||||
_parseDate(
|
||||
json['requested_at'] ?? approvalEnvelope['requested_at'],
|
||||
) ??
|
||||
DateTime.now(),
|
||||
decidedAt: _parseDate(
|
||||
json['decided_at'] ?? approvalEnvelope['decided_at'],
|
||||
),
|
||||
currentStep: json['current_step'] is Map<String, dynamic>
|
||||
? ApprovalStepDto.fromJson(
|
||||
json['current_step'] as Map<String, dynamic>,
|
||||
)
|
||||
: null,
|
||||
requester: ApprovalRequesterDto.fromJson(
|
||||
(json['requester'] as Map<String, dynamic>? ?? const {}),
|
||||
),
|
||||
requestedAt: _parseDate(json['requested_at']) ?? DateTime.now(),
|
||||
decidedAt: _parseDate(json['decided_at']),
|
||||
note: json['note'] as String?,
|
||||
isActive: (json['is_active'] as bool?) ?? true,
|
||||
isDeleted: (json['is_deleted'] as bool?) ?? false,
|
||||
steps: (json['steps'] as List<dynamic>? ?? [])
|
||||
.whereType<Map<String, dynamic>>()
|
||||
.map(ApprovalStepDto.fromJson)
|
||||
.toList(),
|
||||
histories: (json['histories'] as List<dynamic>? ?? [])
|
||||
.whereType<Map<String, dynamic>>()
|
||||
note: json['note'] as String? ?? approvalEnvelope['note'] as String?,
|
||||
isActive:
|
||||
(json['is_active'] as bool?) ??
|
||||
(approvalEnvelope['is_active'] as bool?) ??
|
||||
true,
|
||||
isDeleted:
|
||||
(json['is_deleted'] as bool?) ??
|
||||
(approvalEnvelope['is_deleted'] as bool?) ??
|
||||
false,
|
||||
steps: stepsSource.map(ApprovalStepDto.fromJson).toList(growable: false),
|
||||
histories: historiesSource
|
||||
.map(ApprovalHistoryDto.fromJson)
|
||||
.toList(),
|
||||
createdAt: _parseDate(json['created_at']),
|
||||
updatedAt: _parseDate(json['updated_at']),
|
||||
.toList(growable: false),
|
||||
createdAt: _parseDate(
|
||||
json['created_at'] ?? approvalEnvelope['created_at'],
|
||||
),
|
||||
updatedAt: _parseDate(
|
||||
json['updated_at'] ?? approvalEnvelope['updated_at'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -123,9 +168,21 @@ class ApprovalStatusDto {
|
||||
final String? color;
|
||||
|
||||
factory ApprovalStatusDto.fromJson(Map<String, dynamic> json) {
|
||||
if (json['status'] is Map<String, dynamic>) {
|
||||
return ApprovalStatusDto.fromJson(json['status'] as Map<String, dynamic>);
|
||||
}
|
||||
return ApprovalStatusDto(
|
||||
id: json['id'] as int? ?? json['status_id'] as int? ?? 0,
|
||||
name: json['name'] as String? ?? json['status_name'] as String? ?? '-',
|
||||
id:
|
||||
json['id'] as int? ??
|
||||
json['status_id'] as int? ??
|
||||
json['approval_status_id'] as int? ??
|
||||
0,
|
||||
name:
|
||||
json['name'] as String? ??
|
||||
json['status_name'] as String? ??
|
||||
json['approval_status_name'] as String? ??
|
||||
(json['status'] as String?) ??
|
||||
'-',
|
||||
color: json['color'] as String?,
|
||||
);
|
||||
}
|
||||
@@ -216,6 +273,7 @@ class ApprovalStepDto {
|
||||
status: ApprovalStatusDto.fromJson(
|
||||
(json['status'] as Map<String, dynamic>? ??
|
||||
json['step_status'] as Map<String, dynamic>? ??
|
||||
json['approval_status'] as Map<String, dynamic>? ??
|
||||
const {}),
|
||||
),
|
||||
assignedAt: _parseDate(json['assigned_at']) ?? DateTime.now(),
|
||||
@@ -262,28 +320,41 @@ class ApprovalHistoryDto {
|
||||
final String? note;
|
||||
|
||||
factory ApprovalHistoryDto.fromJson(Map<String, dynamic> json) {
|
||||
final actionMap = _firstNonEmptyMap([
|
||||
json['action'],
|
||||
json['approval_action'],
|
||||
json['step_action'],
|
||||
]);
|
||||
final fromStatusMap = _firstNonEmptyMap([
|
||||
json['from_status'],
|
||||
json['fromStatus'],
|
||||
]);
|
||||
final toStatusMap = _firstNonEmptyMap([
|
||||
json['to_status'],
|
||||
json['toStatus'],
|
||||
]);
|
||||
final approverMap = _firstNonEmptyMap([json['approver'], json['employee']]);
|
||||
final fallbackAction = {
|
||||
'id': json['approval_action_id'] ?? json['action_id'],
|
||||
'name':
|
||||
json['approval_action_name'] ??
|
||||
json['action_name'] ??
|
||||
(json['action'] as String?) ??
|
||||
'-',
|
||||
};
|
||||
|
||||
return ApprovalHistoryDto(
|
||||
id: json['id'] as int?,
|
||||
action: ApprovalActionDto.fromJson(
|
||||
json['action'] is Map<String, dynamic>
|
||||
? json['action'] as Map<String, dynamic>
|
||||
: {
|
||||
'id': json['approval_action_id'],
|
||||
'name': json['approval_action_name'],
|
||||
},
|
||||
actionMap.isEmpty ? fallbackAction : actionMap,
|
||||
),
|
||||
fromStatus: json['from_status'] is Map<String, dynamic>
|
||||
? ApprovalStatusDto.fromJson(
|
||||
json['from_status'] as Map<String, dynamic>,
|
||||
)
|
||||
: null,
|
||||
toStatus: ApprovalStatusDto.fromJson(
|
||||
(json['to_status'] as Map<String, dynamic>? ?? const {}),
|
||||
),
|
||||
approver: ApprovalApproverDto.fromJson(
|
||||
(json['approver'] as Map<String, dynamic>? ?? const {}),
|
||||
),
|
||||
actionAt: _parseDate(json['action_at']) ?? DateTime.now(),
|
||||
fromStatus: fromStatusMap.isEmpty
|
||||
? null
|
||||
: ApprovalStatusDto.fromJson(fromStatusMap),
|
||||
toStatus: ApprovalStatusDto.fromJson(toStatusMap),
|
||||
approver: ApprovalApproverDto.fromJson(approverMap),
|
||||
actionAt:
|
||||
_parseDate(json['action_at'] ?? json['actionAt']) ?? DateTime.now(),
|
||||
note: json['note'] as String?,
|
||||
);
|
||||
}
|
||||
@@ -308,9 +379,21 @@ class ApprovalActionDto {
|
||||
final String name;
|
||||
|
||||
factory ApprovalActionDto.fromJson(Map<String, dynamic> json) {
|
||||
if (json['action'] is Map<String, dynamic>) {
|
||||
return ApprovalActionDto.fromJson(json['action'] as Map<String, dynamic>);
|
||||
}
|
||||
return ApprovalActionDto(
|
||||
id: json['id'] as int? ?? json['action_id'] as int? ?? 0,
|
||||
name: json['name'] as String? ?? json['action_name'] as String? ?? '-',
|
||||
id:
|
||||
json['id'] as int? ??
|
||||
json['action_id'] as int? ??
|
||||
json['approval_action_id'] as int? ??
|
||||
0,
|
||||
name:
|
||||
json['name'] as String? ??
|
||||
json['action_name'] as String? ??
|
||||
json['approval_action_name'] as String? ??
|
||||
(json['action'] as String?) ??
|
||||
'-',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -318,6 +401,39 @@ class ApprovalActionDto {
|
||||
ApprovalAction toEntity() => ApprovalAction(id: id, name: name);
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>> _asListOfMap(dynamic value) {
|
||||
if (value is List) {
|
||||
return value.whereType<Map<String, dynamic>>().toList(growable: false);
|
||||
}
|
||||
return const [];
|
||||
}
|
||||
|
||||
Map<String, dynamic> _mapOrEmpty(dynamic value) =>
|
||||
value is Map<String, dynamic> ? value : const {};
|
||||
|
||||
Map<String, dynamic> _firstNonEmptyMap(List<dynamic> candidates) {
|
||||
for (final candidate in candidates) {
|
||||
if (candidate is Map<String, dynamic> && candidate.isNotEmpty) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return const {};
|
||||
}
|
||||
|
||||
String? _pickString(List<dynamic> sources, List<String> keys) {
|
||||
for (final source in sources) {
|
||||
if (source is Map<String, dynamic>) {
|
||||
for (final key in keys) {
|
||||
final value = source[key];
|
||||
if (value is String && value.isNotEmpty) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// 문자열/DateTime 입력을 DateTime으로 변환한다.
|
||||
DateTime? _parseDate(Object? value) {
|
||||
if (value == null) return null;
|
||||
|
||||
@@ -33,9 +33,13 @@ class ApprovalStepRepositoryRemote implements ApprovalStepRepository {
|
||||
'page': page,
|
||||
'page_size': pageSize,
|
||||
if (query != null && query.isNotEmpty) 'q': query,
|
||||
if (statusId != null) 'status_id': statusId,
|
||||
if (statusId != null) ...{
|
||||
'status_id': statusId,
|
||||
'step_status_id': statusId,
|
||||
},
|
||||
if (approverId != null) 'approver_id': approverId,
|
||||
if (approvalId != null) 'approval_id': approvalId,
|
||||
'include': 'approval,approver,step_status',
|
||||
},
|
||||
options: Options(responseType: ResponseType.json),
|
||||
);
|
||||
|
||||
@@ -52,10 +52,10 @@ class StockTransactionDto {
|
||||
id: json['id'] as int?,
|
||||
transactionNo: json['transaction_no'] as String? ?? '',
|
||||
transactionDate: _parseDate(json['transaction_date']) ?? DateTime.now(),
|
||||
type: _parseType(typeJson),
|
||||
status: _parseStatus(statusJson),
|
||||
warehouse: _parseWarehouse(warehouseJson),
|
||||
createdBy: _parseEmployee(createdByJson),
|
||||
type: _parseType(typeJson, json),
|
||||
status: _parseStatus(statusJson, json),
|
||||
warehouse: _parseWarehouse(warehouseJson, json),
|
||||
createdBy: _parseEmployee(createdByJson, json),
|
||||
note: json['note'] as String?,
|
||||
isActive: (json['is_active'] as bool?) ?? true,
|
||||
createdAt: _parseDateTime(json['created_at']),
|
||||
@@ -117,36 +117,86 @@ class StockTransactionDto {
|
||||
}
|
||||
}
|
||||
|
||||
StockTransactionType _parseType(Map<String, dynamic>? json) {
|
||||
return StockTransactionType(
|
||||
id: json?['id'] as int? ?? 0,
|
||||
name: json?['type_name'] as String? ?? '',
|
||||
);
|
||||
StockTransactionType _parseType(
|
||||
Map<String, dynamic>? json,
|
||||
Map<String, dynamic> fallback,
|
||||
) {
|
||||
final map = json ?? const <String, dynamic>{};
|
||||
final id = map['id'] as int? ?? fallback['transaction_type_id'] as int? ?? 0;
|
||||
final name =
|
||||
map['name'] as String? ??
|
||||
map['type_name'] as String? ??
|
||||
fallback['transaction_type_name'] as String? ??
|
||||
fallback['transaction_type'] as String? ??
|
||||
'';
|
||||
return StockTransactionType(id: id, name: name);
|
||||
}
|
||||
|
||||
StockTransactionStatus _parseStatus(Map<String, dynamic>? json) {
|
||||
return StockTransactionStatus(
|
||||
id: json?['id'] as int? ?? 0,
|
||||
name: json?['status_name'] as String? ?? '',
|
||||
);
|
||||
StockTransactionStatus _parseStatus(
|
||||
Map<String, dynamic>? json,
|
||||
Map<String, dynamic> fallback,
|
||||
) {
|
||||
final map = json ?? const <String, dynamic>{};
|
||||
final id =
|
||||
map['id'] as int? ?? fallback['transaction_status_id'] as int? ?? 0;
|
||||
final name =
|
||||
map['name'] as String? ??
|
||||
map['status_name'] as String? ??
|
||||
fallback['transaction_status_name'] as String? ??
|
||||
fallback['transaction_status'] as String? ??
|
||||
'';
|
||||
return StockTransactionStatus(id: id, name: name);
|
||||
}
|
||||
|
||||
StockTransactionWarehouse _parseWarehouse(Map<String, dynamic>? json) {
|
||||
final zipcode = json?['zipcode'] as Map<String, dynamic>?;
|
||||
StockTransactionWarehouse _parseWarehouse(
|
||||
Map<String, dynamic>? json,
|
||||
Map<String, dynamic> fallback,
|
||||
) {
|
||||
final map = json ?? const <String, dynamic>{};
|
||||
final zipcodeMap = _mapOrEmpty(map['zipcode']);
|
||||
final fallbackZipcode = _mapOrEmpty(fallback['zipcode']);
|
||||
final mergedZipcode = zipcodeMap.isNotEmpty ? zipcodeMap : fallbackZipcode;
|
||||
return StockTransactionWarehouse(
|
||||
id: json?['id'] as int? ?? 0,
|
||||
code: json?['warehouse_code'] as String? ?? '',
|
||||
name: json?['warehouse_name'] as String? ?? '',
|
||||
zipcode: zipcode?['zipcode'] as String?,
|
||||
addressLine: zipcode?['road_name'] as String?,
|
||||
id: map['id'] as int? ?? fallback['warehouse_id'] as int? ?? 0,
|
||||
code:
|
||||
map['warehouse_code'] as String? ??
|
||||
fallback['warehouse_code'] as String? ??
|
||||
fallback['warehouseCode'] as String? ??
|
||||
'',
|
||||
name:
|
||||
map['warehouse_name'] as String? ??
|
||||
fallback['warehouse_name'] as String? ??
|
||||
fallback['warehouseName'] as String? ??
|
||||
'',
|
||||
zipcode:
|
||||
mergedZipcode['zipcode'] as String? ?? fallback['zipcode'] as String?,
|
||||
addressLine:
|
||||
mergedZipcode['road_name'] as String? ??
|
||||
mergedZipcode['roadName'] as String? ??
|
||||
fallback['address_line'] as String? ??
|
||||
fallback['addressLine'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
StockTransactionEmployee _parseEmployee(Map<String, dynamic>? json) {
|
||||
StockTransactionEmployee _parseEmployee(
|
||||
Map<String, dynamic>? json,
|
||||
Map<String, dynamic> fallback,
|
||||
) {
|
||||
final map = json ?? const <String, dynamic>{};
|
||||
return StockTransactionEmployee(
|
||||
id: json?['id'] as int? ?? 0,
|
||||
employeeNo: json?['employee_no'] as String? ?? '',
|
||||
name: json?['employee_name'] as String? ?? '',
|
||||
id:
|
||||
map['id'] as int? ??
|
||||
fallback['created_by_id'] as int? ??
|
||||
fallback['created_by'] as int? ??
|
||||
0,
|
||||
employeeNo:
|
||||
map['employee_no'] as String? ??
|
||||
fallback['created_by_employee_no'] as String? ??
|
||||
'',
|
||||
name:
|
||||
map['employee_name'] as String? ??
|
||||
fallback['created_by_name'] as String? ??
|
||||
'',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -157,83 +207,184 @@ List<StockTransactionLine> _parseLines(Map<String, dynamic> json) {
|
||||
StockTransactionLine(
|
||||
id: item['id'] as int?,
|
||||
lineNo: JsonUtils.readInt(item, 'line_no', fallback: 1),
|
||||
product: _parseProduct(item['product'] as Map<String, dynamic>?),
|
||||
quantity: JsonUtils.readInt(item, 'quantity', fallback: 0),
|
||||
product: _parseProduct(item['product'] as Map<String, dynamic>?, item),
|
||||
quantity: _readQuantity(item['quantity']),
|
||||
unitPrice: _readDouble(item['unit_price']),
|
||||
note: item['note'] as String?,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
StockTransactionProduct _parseProduct(Map<String, dynamic>? json) {
|
||||
final vendorJson = json?['vendor'] as Map<String, dynamic>?;
|
||||
final uomJson = json?['uom'] as Map<String, dynamic>?;
|
||||
StockTransactionProduct _parseProduct(
|
||||
Map<String, dynamic>? json,
|
||||
Map<String, dynamic> fallback,
|
||||
) {
|
||||
final map = json ?? const <String, dynamic>{};
|
||||
return StockTransactionProduct(
|
||||
id: json?['id'] as int? ?? 0,
|
||||
code: json?['product_code'] as String? ?? json?['code'] as String? ?? '',
|
||||
name: json?['product_name'] as String? ?? json?['name'] as String? ?? '',
|
||||
vendor: vendorJson == null
|
||||
? null
|
||||
: StockTransactionVendorSummary(
|
||||
id: vendorJson['id'] as int? ?? 0,
|
||||
name:
|
||||
vendorJson['vendor_name'] as String? ??
|
||||
vendorJson['name'] as String? ??
|
||||
'',
|
||||
),
|
||||
uom: uomJson == null
|
||||
? null
|
||||
: StockTransactionUomSummary(
|
||||
id: uomJson['id'] as int? ?? 0,
|
||||
name:
|
||||
uomJson['uom_name'] as String? ??
|
||||
uomJson['name'] as String? ??
|
||||
'',
|
||||
),
|
||||
id:
|
||||
map['id'] as int? ??
|
||||
map['product_id'] as int? ??
|
||||
fallback['product_id'] as int? ??
|
||||
0,
|
||||
code:
|
||||
map['product_code'] as String? ??
|
||||
map['code'] as String? ??
|
||||
fallback['product_code'] as String? ??
|
||||
fallback['code'] as String? ??
|
||||
'',
|
||||
name:
|
||||
map['product_name'] as String? ??
|
||||
map['name'] as String? ??
|
||||
fallback['product_name'] as String? ??
|
||||
fallback['name'] as String? ??
|
||||
'',
|
||||
vendor: _parseVendor(map['vendor'], fallback),
|
||||
uom: _parseUom(map['uom'], fallback),
|
||||
);
|
||||
}
|
||||
|
||||
StockTransactionVendorSummary? _parseVendor(
|
||||
dynamic source,
|
||||
Map<String, dynamic> fallback,
|
||||
) {
|
||||
final map = _mapOrEmpty(source);
|
||||
final name =
|
||||
map['vendor_name'] as String? ??
|
||||
map['name'] as String? ??
|
||||
fallback['vendor_name'] as String? ??
|
||||
fallback['vendorName'] as String? ??
|
||||
fallback['manufacturer'] as String?;
|
||||
if (name == null || name.trim().isEmpty) {
|
||||
return null;
|
||||
}
|
||||
final id =
|
||||
map['id'] as int? ??
|
||||
map['vendor_id'] as int? ??
|
||||
fallback['vendor_id'] as int? ??
|
||||
0;
|
||||
return StockTransactionVendorSummary(id: id, name: name);
|
||||
}
|
||||
|
||||
StockTransactionUomSummary? _parseUom(
|
||||
dynamic source,
|
||||
Map<String, dynamic> fallback,
|
||||
) {
|
||||
final map = _mapOrEmpty(source);
|
||||
final name =
|
||||
map['uom_name'] as String? ??
|
||||
map['name'] as String? ??
|
||||
fallback['uom_name'] as String? ??
|
||||
fallback['uomName'] as String? ??
|
||||
fallback['unit'] as String?;
|
||||
if (name == null || name.trim().isEmpty) {
|
||||
return null;
|
||||
}
|
||||
final id =
|
||||
map['id'] as int? ??
|
||||
map['uom_id'] as int? ??
|
||||
fallback['uom_id'] as int? ??
|
||||
0;
|
||||
return StockTransactionUomSummary(id: id, name: name);
|
||||
}
|
||||
|
||||
List<StockTransactionCustomer> _parseCustomers(Map<String, dynamic> json) {
|
||||
final raw = JsonUtils.extractList(json, keys: const ['customers']);
|
||||
return [
|
||||
for (final item in raw)
|
||||
StockTransactionCustomer(
|
||||
id: item['id'] as int?,
|
||||
customer: _parseCustomer(item['customer'] as Map<String, dynamic>?),
|
||||
customer: _parseCustomer(
|
||||
item['customer'] as Map<String, dynamic>?,
|
||||
item,
|
||||
),
|
||||
note: item['note'] as String?,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
StockTransactionCustomerSummary _parseCustomer(Map<String, dynamic>? json) {
|
||||
StockTransactionCustomerSummary _parseCustomer(
|
||||
Map<String, dynamic>? json,
|
||||
Map<String, dynamic> fallback,
|
||||
) {
|
||||
final map = json ?? const <String, dynamic>{};
|
||||
return StockTransactionCustomerSummary(
|
||||
id: json?['id'] as int? ?? 0,
|
||||
code: json?['customer_code'] as String? ?? json?['code'] as String? ?? '',
|
||||
name: json?['customer_name'] as String? ?? json?['name'] as String? ?? '',
|
||||
id:
|
||||
map['id'] as int? ??
|
||||
map['customer_id'] as int? ??
|
||||
fallback['customer_id'] as int? ??
|
||||
0,
|
||||
code:
|
||||
map['customer_code'] as String? ??
|
||||
map['code'] as String? ??
|
||||
fallback['customer_code'] as String? ??
|
||||
fallback['code'] as String? ??
|
||||
'',
|
||||
name:
|
||||
map['customer_name'] as String? ??
|
||||
map['name'] as String? ??
|
||||
fallback['customer_name'] as String? ??
|
||||
fallback['name'] as String? ??
|
||||
'',
|
||||
);
|
||||
}
|
||||
|
||||
StockTransactionApprovalSummary? _parseApproval(dynamic raw) {
|
||||
if (raw is! Map<String, dynamic>) {
|
||||
final map = _mapOrEmpty(raw);
|
||||
if (map.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
final status = raw['approval_status'] as Map<String, dynamic>?;
|
||||
final statusMap = _firstNonEmptyMap([map['approval_status'], map['status']]);
|
||||
return StockTransactionApprovalSummary(
|
||||
id: raw['id'] as int? ?? 0,
|
||||
approvalNo: raw['approval_no'] as String? ?? '',
|
||||
status: status == null
|
||||
id: map['id'] as int? ?? 0,
|
||||
approvalNo:
|
||||
map['approval_no'] as String? ?? map['approvalNo'] as String? ?? '',
|
||||
status: statusMap.isEmpty
|
||||
? null
|
||||
: StockTransactionApprovalStatusSummary(
|
||||
id: status['id'] as int? ?? 0,
|
||||
id: statusMap['id'] as int? ?? statusMap['status_id'] as int? ?? 0,
|
||||
name:
|
||||
status['status_name'] as String? ??
|
||||
status['name'] as String? ??
|
||||
'',
|
||||
isBlocking: status['is_blocking_next'] as bool?,
|
||||
statusMap['name'] as String? ??
|
||||
statusMap['status_name'] as String? ??
|
||||
'-',
|
||||
isBlocking:
|
||||
statusMap['is_blocking_next'] as bool? ??
|
||||
statusMap['isBlocking'] as bool?,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _mapOrEmpty(dynamic value) =>
|
||||
value is Map<String, dynamic> ? value : const <String, dynamic>{};
|
||||
|
||||
Map<String, dynamic> _firstNonEmptyMap(List<dynamic> candidates) {
|
||||
for (final candidate in candidates) {
|
||||
if (candidate is Map<String, dynamic> && candidate.isNotEmpty) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return const <String, dynamic>{};
|
||||
}
|
||||
|
||||
int _readQuantity(Object? value) {
|
||||
if (value is int) {
|
||||
return value;
|
||||
}
|
||||
if (value is double) {
|
||||
return value.round();
|
||||
}
|
||||
if (value is String) {
|
||||
final parsedInt = int.tryParse(value);
|
||||
if (parsedInt != null) {
|
||||
return parsedInt;
|
||||
}
|
||||
final parsedDouble = double.tryParse(value);
|
||||
if (parsedDouble != null) {
|
||||
return parsedDouble.round();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DateTime? _parseDate(Object? value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
|
||||
@@ -34,7 +34,7 @@ class GroupPermissionRepositoryRemote implements GroupPermissionRepository {
|
||||
if (groupId != null) 'group_id': groupId,
|
||||
if (menuId != null) 'menu_id': menuId,
|
||||
if (isActive != null) 'active': isActive,
|
||||
if (includeDeleted) 'include_deleted': true,
|
||||
if (includeDeleted) 'deleted': true,
|
||||
'include': 'group,menu',
|
||||
},
|
||||
options: Options(responseType: ResponseType.json),
|
||||
|
||||
@@ -42,7 +42,7 @@ class MenuDto {
|
||||
: json['parent'] is Map<String, dynamic>
|
||||
? MenuSummaryDto.fromJson(json['parent'] as Map<String, dynamic>)
|
||||
: null,
|
||||
path: json['path'] as String?,
|
||||
path: json['path'] as String? ?? json['route_path'] as String?,
|
||||
displayOrder: json['display_order'] as int?,
|
||||
isActive: (json['is_active'] as bool?) ?? true,
|
||||
isDeleted: (json['is_deleted'] as bool?) ?? false,
|
||||
|
||||
Reference in New Issue
Block a user