feat: 회사 관리 API 연동 구현

- CompanyService 및 RemoteDataSource 구현
- Company, Branch DTO 모델 생성 (Freezed)
- 의존성 주입 컨테이너 업데이트
- 회사 등록/수정 폼에 API 연동 로직 적용
- API 통합 계획 문서 업데이트
This commit is contained in:
JiWoong Sul
2025-07-24 17:56:06 +09:00
parent 47bfa3a26a
commit 6b31631cfb
16 changed files with 4171 additions and 85 deletions

View File

@@ -0,0 +1,253 @@
import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/core/constants/api_endpoints.dart';
import 'package:superport/core/errors/exceptions.dart';
import 'package:superport/data/datasources/remote/api_client.dart';
import 'package:superport/data/models/company/company_dto.dart';
import 'package:superport/data/models/company/company_list_dto.dart';
import 'package:superport/data/models/company/branch_dto.dart';
abstract class CompanyRemoteDataSource {
Future<List<CompanyListDto>> getCompanies({
int page = 1,
int perPage = 20,
String? search,
bool? isActive,
});
Future<CompanyResponse> createCompany(CreateCompanyRequest request);
Future<CompanyResponse> getCompanyDetail(int id);
Future<CompanyWithBranches> getCompanyWithBranches(int id);
Future<CompanyResponse> updateCompany(int id, UpdateCompanyRequest request);
Future<void> deleteCompany(int id);
Future<List<CompanyNameDto>> getCompanyNames();
// Branch related methods
Future<BranchResponse> createBranch(int companyId, CreateBranchRequest request);
Future<BranchResponse> getBranchDetail(int companyId, int branchId);
Future<BranchResponse> updateBranch(int companyId, int branchId, UpdateBranchRequest request);
Future<void> deleteBranch(int companyId, int branchId);
Future<List<BranchListDto>> getCompanyBranches(int companyId);
}
class CompanyRemoteDataSourceImpl implements CompanyRemoteDataSource {
final ApiClient _apiClient = GetIt.instance<ApiClient>();
@override
Future<List<CompanyListDto>> getCompanies({
int page = 1,
int perPage = 20,
String? search,
bool? isActive,
}) async {
try {
final queryParams = {
'page': page,
'per_page': perPage,
if (search != null) 'search': search,
if (isActive != null) 'is_active': isActive,
};
final response = await _apiClient.dio.get(
ApiEndpoints.companies,
queryParameters: queryParams,
);
final List<dynamic> data = response.data['data'];
return data.map((json) => CompanyListDto.fromJson(json)).toList();
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to fetch companies',
code: e.response?.statusCode,
);
}
}
@override
Future<CompanyResponse> createCompany(CreateCompanyRequest request) async {
try {
final response = await _apiClient.dio.post(
ApiEndpoints.companies,
data: request.toJson(),
);
return CompanyResponse.fromJson(response.data['data']);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to create company',
code: e.response?.statusCode,
);
}
}
@override
Future<CompanyResponse> getCompanyDetail(int id) async {
try {
final response = await _apiClient.dio.get(
'${ApiEndpoints.companies}/$id',
);
return CompanyResponse.fromJson(response.data['data']);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to fetch company detail',
code: e.response?.statusCode,
);
}
}
@override
Future<CompanyWithBranches> getCompanyWithBranches(int id) async {
try {
final response = await _apiClient.dio.get(
'${ApiEndpoints.companies}/$id/with-branches',
);
return CompanyWithBranches.fromJson(response.data['data']);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to fetch company with branches',
code: e.response?.statusCode,
);
}
}
@override
Future<CompanyResponse> updateCompany(int id, UpdateCompanyRequest request) async {
try {
final response = await _apiClient.dio.put(
'${ApiEndpoints.companies}/$id',
data: request.toJson(),
);
return CompanyResponse.fromJson(response.data['data']);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to update company',
code: e.response?.statusCode,
);
}
}
@override
Future<void> deleteCompany(int id) async {
try {
await _apiClient.dio.delete(
'${ApiEndpoints.companies}/$id',
);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to delete company',
code: e.response?.statusCode,
);
}
}
@override
Future<List<CompanyNameDto>> getCompanyNames() async {
try {
final response = await _apiClient.dio.get(
'${ApiEndpoints.companies}/names',
);
final List<dynamic> data = response.data['data'];
return data.map((json) => CompanyNameDto.fromJson(json)).toList();
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to fetch company names',
code: e.response?.statusCode,
);
}
}
// Branch methods
@override
Future<BranchResponse> createBranch(int companyId, CreateBranchRequest request) async {
try {
final response = await _apiClient.dio.post(
'${ApiEndpoints.companies}/$companyId/branches',
data: request.toJson(),
);
return BranchResponse.fromJson(response.data['data']);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to create branch',
code: e.response?.statusCode,
);
}
}
@override
Future<BranchResponse> getBranchDetail(int companyId, int branchId) async {
try {
final response = await _apiClient.dio.get(
'${ApiEndpoints.companies}/$companyId/branches/$branchId',
);
return BranchResponse.fromJson(response.data['data']);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to fetch branch detail',
code: e.response?.statusCode,
);
}
}
@override
Future<BranchResponse> updateBranch(int companyId, int branchId, UpdateBranchRequest request) async {
try {
final response = await _apiClient.dio.put(
'${ApiEndpoints.companies}/$companyId/branches/$branchId',
data: request.toJson(),
);
return BranchResponse.fromJson(response.data['data']);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to update branch',
code: e.response?.statusCode,
);
}
}
@override
Future<void> deleteBranch(int companyId, int branchId) async {
try {
await _apiClient.dio.delete(
'${ApiEndpoints.companies}/$companyId/branches/$branchId',
);
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to delete branch',
code: e.response?.statusCode,
);
}
}
@override
Future<List<BranchListDto>> getCompanyBranches(int companyId) async {
try {
final response = await _apiClient.dio.get(
'${ApiEndpoints.companies}/$companyId/branches',
);
final List<dynamic> data = response.data['data'];
return data.map((json) => BranchListDto.fromJson(json)).toList();
} on DioException catch (e) {
throw ServerException(
message: e.response?.data['message'] ?? 'Failed to fetch company branches',
code: e.response?.statusCode,
);
}
}
}

View File

@@ -0,0 +1,69 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'branch_dto.freezed.dart';
part 'branch_dto.g.dart';
@freezed
class CreateBranchRequest with _$CreateBranchRequest {
const factory CreateBranchRequest({
@JsonKey(name: 'branch_name') required String branchName,
required String address,
required String phone,
@JsonKey(name: 'manager_name') String? managerName,
@JsonKey(name: 'manager_phone') String? managerPhone,
String? remark,
}) = _CreateBranchRequest;
factory CreateBranchRequest.fromJson(Map<String, dynamic> json) =>
_$CreateBranchRequestFromJson(json);
}
@freezed
class UpdateBranchRequest with _$UpdateBranchRequest {
const factory UpdateBranchRequest({
@JsonKey(name: 'branch_name') String? branchName,
String? address,
String? phone,
@JsonKey(name: 'manager_name') String? managerName,
@JsonKey(name: 'manager_phone') String? managerPhone,
String? remark,
}) = _UpdateBranchRequest;
factory UpdateBranchRequest.fromJson(Map<String, dynamic> json) =>
_$UpdateBranchRequestFromJson(json);
}
@freezed
class BranchResponse with _$BranchResponse {
const factory BranchResponse({
required int id,
@JsonKey(name: 'company_id') required int companyId,
@JsonKey(name: 'branch_name') required String branchName,
required String address,
required String phone,
@JsonKey(name: 'manager_name') String? managerName,
@JsonKey(name: 'manager_phone') String? managerPhone,
String? remark,
@JsonKey(name: 'created_at') required DateTime createdAt,
@JsonKey(name: 'updated_at') required DateTime updatedAt,
@JsonKey(name: 'address_id') int? addressId,
}) = _BranchResponse;
factory BranchResponse.fromJson(Map<String, dynamic> json) =>
_$BranchResponseFromJson(json);
}
@freezed
class BranchListDto with _$BranchListDto {
const factory BranchListDto({
required int id,
@JsonKey(name: 'company_id') required int companyId,
@JsonKey(name: 'branch_name') required String branchName,
required String address,
required String phone,
@JsonKey(name: 'manager_name') String? managerName,
}) = _BranchListDto;
factory BranchListDto.fromJson(Map<String, dynamic> json) =>
_$BranchListDtoFromJson(json);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'branch_dto.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$CreateBranchRequestImpl _$$CreateBranchRequestImplFromJson(
Map<String, dynamic> json) =>
_$CreateBranchRequestImpl(
branchName: json['branch_name'] as String,
address: json['address'] as String,
phone: json['phone'] as String,
managerName: json['manager_name'] as String?,
managerPhone: json['manager_phone'] as String?,
remark: json['remark'] as String?,
);
Map<String, dynamic> _$$CreateBranchRequestImplToJson(
_$CreateBranchRequestImpl instance) =>
<String, dynamic>{
'branch_name': instance.branchName,
'address': instance.address,
'phone': instance.phone,
'manager_name': instance.managerName,
'manager_phone': instance.managerPhone,
'remark': instance.remark,
};
_$UpdateBranchRequestImpl _$$UpdateBranchRequestImplFromJson(
Map<String, dynamic> json) =>
_$UpdateBranchRequestImpl(
branchName: json['branch_name'] as String?,
address: json['address'] as String?,
phone: json['phone'] as String?,
managerName: json['manager_name'] as String?,
managerPhone: json['manager_phone'] as String?,
remark: json['remark'] as String?,
);
Map<String, dynamic> _$$UpdateBranchRequestImplToJson(
_$UpdateBranchRequestImpl instance) =>
<String, dynamic>{
'branch_name': instance.branchName,
'address': instance.address,
'phone': instance.phone,
'manager_name': instance.managerName,
'manager_phone': instance.managerPhone,
'remark': instance.remark,
};
_$BranchResponseImpl _$$BranchResponseImplFromJson(Map<String, dynamic> json) =>
_$BranchResponseImpl(
id: (json['id'] as num).toInt(),
companyId: (json['company_id'] as num).toInt(),
branchName: json['branch_name'] as String,
address: json['address'] as String,
phone: json['phone'] as String,
managerName: json['manager_name'] as String?,
managerPhone: json['manager_phone'] as String?,
remark: json['remark'] as String?,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
addressId: (json['address_id'] as num?)?.toInt(),
);
Map<String, dynamic> _$$BranchResponseImplToJson(
_$BranchResponseImpl instance) =>
<String, dynamic>{
'id': instance.id,
'company_id': instance.companyId,
'branch_name': instance.branchName,
'address': instance.address,
'phone': instance.phone,
'manager_name': instance.managerName,
'manager_phone': instance.managerPhone,
'remark': instance.remark,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'address_id': instance.addressId,
};
_$BranchListDtoImpl _$$BranchListDtoImplFromJson(Map<String, dynamic> json) =>
_$BranchListDtoImpl(
id: (json['id'] as num).toInt(),
companyId: (json['company_id'] as num).toInt(),
branchName: json['branch_name'] as String,
address: json['address'] as String,
phone: json['phone'] as String,
managerName: json['manager_name'] as String?,
);
Map<String, dynamic> _$$BranchListDtoImplToJson(_$BranchListDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'company_id': instance.companyId,
'branch_name': instance.branchName,
'address': instance.address,
'phone': instance.phone,
'manager_name': instance.managerName,
};

View File

@@ -0,0 +1,72 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'company_dto.freezed.dart';
part 'company_dto.g.dart';
@freezed
class CreateCompanyRequest with _$CreateCompanyRequest {
const factory CreateCompanyRequest({
required String name,
required String address,
@JsonKey(name: 'contact_name') required String contactName,
@JsonKey(name: 'contact_position') required String contactPosition,
@JsonKey(name: 'contact_phone') required String contactPhone,
@JsonKey(name: 'contact_email') required String contactEmail,
@JsonKey(name: 'company_types') @Default([]) List<String> companyTypes,
String? remark,
}) = _CreateCompanyRequest;
factory CreateCompanyRequest.fromJson(Map<String, dynamic> json) =>
_$CreateCompanyRequestFromJson(json);
}
@freezed
class UpdateCompanyRequest with _$UpdateCompanyRequest {
const factory UpdateCompanyRequest({
String? name,
String? address,
@JsonKey(name: 'contact_name') String? contactName,
@JsonKey(name: 'contact_position') String? contactPosition,
@JsonKey(name: 'contact_phone') String? contactPhone,
@JsonKey(name: 'contact_email') String? contactEmail,
@JsonKey(name: 'company_types') List<String>? companyTypes,
String? remark,
@JsonKey(name: 'is_active') bool? isActive,
}) = _UpdateCompanyRequest;
factory UpdateCompanyRequest.fromJson(Map<String, dynamic> json) =>
_$UpdateCompanyRequestFromJson(json);
}
@freezed
class CompanyResponse with _$CompanyResponse {
const factory CompanyResponse({
required int id,
required String name,
required String address,
@JsonKey(name: 'contact_name') required String contactName,
@JsonKey(name: 'contact_position') required String contactPosition,
@JsonKey(name: 'contact_phone') required String contactPhone,
@JsonKey(name: 'contact_email') required String contactEmail,
@JsonKey(name: 'company_types') @Default([]) List<String> companyTypes,
String? remark,
@JsonKey(name: 'is_active') required bool isActive,
@JsonKey(name: 'created_at') required DateTime createdAt,
@JsonKey(name: 'updated_at') required DateTime updatedAt,
@JsonKey(name: 'address_id') int? addressId,
}) = _CompanyResponse;
factory CompanyResponse.fromJson(Map<String, dynamic> json) =>
_$CompanyResponseFromJson(json);
}
@freezed
class CompanyNameDto with _$CompanyNameDto {
const factory CompanyNameDto({
required int id,
required String name,
}) = _CompanyNameDto;
factory CompanyNameDto.fromJson(Map<String, dynamic> json) =>
_$CompanyNameDtoFromJson(json);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'company_dto.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$CreateCompanyRequestImpl _$$CreateCompanyRequestImplFromJson(
Map<String, dynamic> json) =>
_$CreateCompanyRequestImpl(
name: json['name'] as String,
address: json['address'] as String,
contactName: json['contact_name'] as String,
contactPosition: json['contact_position'] as String,
contactPhone: json['contact_phone'] as String,
contactEmail: json['contact_email'] as String,
companyTypes: (json['company_types'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
remark: json['remark'] as String?,
);
Map<String, dynamic> _$$CreateCompanyRequestImplToJson(
_$CreateCompanyRequestImpl instance) =>
<String, dynamic>{
'name': instance.name,
'address': instance.address,
'contact_name': instance.contactName,
'contact_position': instance.contactPosition,
'contact_phone': instance.contactPhone,
'contact_email': instance.contactEmail,
'company_types': instance.companyTypes,
'remark': instance.remark,
};
_$UpdateCompanyRequestImpl _$$UpdateCompanyRequestImplFromJson(
Map<String, dynamic> json) =>
_$UpdateCompanyRequestImpl(
name: json['name'] as String?,
address: json['address'] as String?,
contactName: json['contact_name'] as String?,
contactPosition: json['contact_position'] as String?,
contactPhone: json['contact_phone'] as String?,
contactEmail: json['contact_email'] as String?,
companyTypes: (json['company_types'] as List<dynamic>?)
?.map((e) => e as String)
.toList(),
remark: json['remark'] as String?,
isActive: json['is_active'] as bool?,
);
Map<String, dynamic> _$$UpdateCompanyRequestImplToJson(
_$UpdateCompanyRequestImpl instance) =>
<String, dynamic>{
'name': instance.name,
'address': instance.address,
'contact_name': instance.contactName,
'contact_position': instance.contactPosition,
'contact_phone': instance.contactPhone,
'contact_email': instance.contactEmail,
'company_types': instance.companyTypes,
'remark': instance.remark,
'is_active': instance.isActive,
};
_$CompanyResponseImpl _$$CompanyResponseImplFromJson(
Map<String, dynamic> json) =>
_$CompanyResponseImpl(
id: (json['id'] as num).toInt(),
name: json['name'] as String,
address: json['address'] as String,
contactName: json['contact_name'] as String,
contactPosition: json['contact_position'] as String,
contactPhone: json['contact_phone'] as String,
contactEmail: json['contact_email'] as String,
companyTypes: (json['company_types'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
remark: json['remark'] as String?,
isActive: json['is_active'] as bool,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
addressId: (json['address_id'] as num?)?.toInt(),
);
Map<String, dynamic> _$$CompanyResponseImplToJson(
_$CompanyResponseImpl instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'address': instance.address,
'contact_name': instance.contactName,
'contact_position': instance.contactPosition,
'contact_phone': instance.contactPhone,
'contact_email': instance.contactEmail,
'company_types': instance.companyTypes,
'remark': instance.remark,
'is_active': instance.isActive,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'address_id': instance.addressId,
};
_$CompanyNameDtoImpl _$$CompanyNameDtoImplFromJson(Map<String, dynamic> json) =>
_$CompanyNameDtoImpl(
id: (json['id'] as num).toInt(),
name: json['name'] as String,
);
Map<String, dynamic> _$$CompanyNameDtoImplToJson(
_$CompanyNameDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
};

View File

@@ -0,0 +1,33 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'company_dto.dart';
import 'branch_dto.dart';
part 'company_list_dto.freezed.dart';
part 'company_list_dto.g.dart';
@freezed
class CompanyListDto with _$CompanyListDto {
const factory CompanyListDto({
required int id,
required String name,
required String address,
@JsonKey(name: 'contact_name') required String contactName,
@JsonKey(name: 'contact_phone') required String contactPhone,
@JsonKey(name: 'is_active') required bool isActive,
@JsonKey(name: 'branch_count') @Default(0) int branchCount,
}) = _CompanyListDto;
factory CompanyListDto.fromJson(Map<String, dynamic> json) =>
_$CompanyListDtoFromJson(json);
}
@freezed
class CompanyWithBranches with _$CompanyWithBranches {
const factory CompanyWithBranches({
required CompanyResponse company,
@Default([]) List<BranchListDto> branches,
}) = _CompanyWithBranches;
factory CompanyWithBranches.fromJson(Map<String, dynamic> json) =>
_$CompanyWithBranchesFromJson(json);
}

View File

@@ -0,0 +1,499 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'company_list_dto.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
CompanyListDto _$CompanyListDtoFromJson(Map<String, dynamic> json) {
return _CompanyListDto.fromJson(json);
}
/// @nodoc
mixin _$CompanyListDto {
int get id => throw _privateConstructorUsedError;
String get name => throw _privateConstructorUsedError;
String get address => throw _privateConstructorUsedError;
@JsonKey(name: 'contact_name')
String get contactName => throw _privateConstructorUsedError;
@JsonKey(name: 'contact_phone')
String get contactPhone => throw _privateConstructorUsedError;
@JsonKey(name: 'is_active')
bool get isActive => throw _privateConstructorUsedError;
@JsonKey(name: 'branch_count')
int get branchCount => throw _privateConstructorUsedError;
/// Serializes this CompanyListDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of CompanyListDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$CompanyListDtoCopyWith<CompanyListDto> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $CompanyListDtoCopyWith<$Res> {
factory $CompanyListDtoCopyWith(
CompanyListDto value, $Res Function(CompanyListDto) then) =
_$CompanyListDtoCopyWithImpl<$Res, CompanyListDto>;
@useResult
$Res call(
{int id,
String name,
String address,
@JsonKey(name: 'contact_name') String contactName,
@JsonKey(name: 'contact_phone') String contactPhone,
@JsonKey(name: 'is_active') bool isActive,
@JsonKey(name: 'branch_count') int branchCount});
}
/// @nodoc
class _$CompanyListDtoCopyWithImpl<$Res, $Val extends CompanyListDto>
implements $CompanyListDtoCopyWith<$Res> {
_$CompanyListDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of CompanyListDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? name = null,
Object? address = null,
Object? contactName = null,
Object? contactPhone = null,
Object? isActive = null,
Object? branchCount = null,
}) {
return _then(_value.copyWith(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as int,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
address: null == address
? _value.address
: address // ignore: cast_nullable_to_non_nullable
as String,
contactName: null == contactName
? _value.contactName
: contactName // ignore: cast_nullable_to_non_nullable
as String,
contactPhone: null == contactPhone
? _value.contactPhone
: contactPhone // ignore: cast_nullable_to_non_nullable
as String,
isActive: null == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool,
branchCount: null == branchCount
? _value.branchCount
: branchCount // ignore: cast_nullable_to_non_nullable
as int,
) as $Val);
}
}
/// @nodoc
abstract class _$$CompanyListDtoImplCopyWith<$Res>
implements $CompanyListDtoCopyWith<$Res> {
factory _$$CompanyListDtoImplCopyWith(_$CompanyListDtoImpl value,
$Res Function(_$CompanyListDtoImpl) then) =
__$$CompanyListDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{int id,
String name,
String address,
@JsonKey(name: 'contact_name') String contactName,
@JsonKey(name: 'contact_phone') String contactPhone,
@JsonKey(name: 'is_active') bool isActive,
@JsonKey(name: 'branch_count') int branchCount});
}
/// @nodoc
class __$$CompanyListDtoImplCopyWithImpl<$Res>
extends _$CompanyListDtoCopyWithImpl<$Res, _$CompanyListDtoImpl>
implements _$$CompanyListDtoImplCopyWith<$Res> {
__$$CompanyListDtoImplCopyWithImpl(
_$CompanyListDtoImpl _value, $Res Function(_$CompanyListDtoImpl) _then)
: super(_value, _then);
/// Create a copy of CompanyListDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = null,
Object? name = null,
Object? address = null,
Object? contactName = null,
Object? contactPhone = null,
Object? isActive = null,
Object? branchCount = null,
}) {
return _then(_$CompanyListDtoImpl(
id: null == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as int,
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
address: null == address
? _value.address
: address // ignore: cast_nullable_to_non_nullable
as String,
contactName: null == contactName
? _value.contactName
: contactName // ignore: cast_nullable_to_non_nullable
as String,
contactPhone: null == contactPhone
? _value.contactPhone
: contactPhone // ignore: cast_nullable_to_non_nullable
as String,
isActive: null == isActive
? _value.isActive
: isActive // ignore: cast_nullable_to_non_nullable
as bool,
branchCount: null == branchCount
? _value.branchCount
: branchCount // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
/// @nodoc
@JsonSerializable()
class _$CompanyListDtoImpl implements _CompanyListDto {
const _$CompanyListDtoImpl(
{required this.id,
required this.name,
required this.address,
@JsonKey(name: 'contact_name') required this.contactName,
@JsonKey(name: 'contact_phone') required this.contactPhone,
@JsonKey(name: 'is_active') required this.isActive,
@JsonKey(name: 'branch_count') this.branchCount = 0});
factory _$CompanyListDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$CompanyListDtoImplFromJson(json);
@override
final int id;
@override
final String name;
@override
final String address;
@override
@JsonKey(name: 'contact_name')
final String contactName;
@override
@JsonKey(name: 'contact_phone')
final String contactPhone;
@override
@JsonKey(name: 'is_active')
final bool isActive;
@override
@JsonKey(name: 'branch_count')
final int branchCount;
@override
String toString() {
return 'CompanyListDto(id: $id, name: $name, address: $address, contactName: $contactName, contactPhone: $contactPhone, isActive: $isActive, branchCount: $branchCount)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$CompanyListDtoImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.name, name) || other.name == name) &&
(identical(other.address, address) || other.address == address) &&
(identical(other.contactName, contactName) ||
other.contactName == contactName) &&
(identical(other.contactPhone, contactPhone) ||
other.contactPhone == contactPhone) &&
(identical(other.isActive, isActive) ||
other.isActive == isActive) &&
(identical(other.branchCount, branchCount) ||
other.branchCount == branchCount));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType, id, name, address, contactName,
contactPhone, isActive, branchCount);
/// Create a copy of CompanyListDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$CompanyListDtoImplCopyWith<_$CompanyListDtoImpl> get copyWith =>
__$$CompanyListDtoImplCopyWithImpl<_$CompanyListDtoImpl>(
this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$CompanyListDtoImplToJson(
this,
);
}
}
abstract class _CompanyListDto implements CompanyListDto {
const factory _CompanyListDto(
{required final int id,
required final String name,
required final String address,
@JsonKey(name: 'contact_name') required final String contactName,
@JsonKey(name: 'contact_phone') required final String contactPhone,
@JsonKey(name: 'is_active') required final bool isActive,
@JsonKey(name: 'branch_count') final int branchCount}) =
_$CompanyListDtoImpl;
factory _CompanyListDto.fromJson(Map<String, dynamic> json) =
_$CompanyListDtoImpl.fromJson;
@override
int get id;
@override
String get name;
@override
String get address;
@override
@JsonKey(name: 'contact_name')
String get contactName;
@override
@JsonKey(name: 'contact_phone')
String get contactPhone;
@override
@JsonKey(name: 'is_active')
bool get isActive;
@override
@JsonKey(name: 'branch_count')
int get branchCount;
/// Create a copy of CompanyListDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$CompanyListDtoImplCopyWith<_$CompanyListDtoImpl> get copyWith =>
throw _privateConstructorUsedError;
}
CompanyWithBranches _$CompanyWithBranchesFromJson(Map<String, dynamic> json) {
return _CompanyWithBranches.fromJson(json);
}
/// @nodoc
mixin _$CompanyWithBranches {
CompanyResponse get company => throw _privateConstructorUsedError;
List<BranchListDto> get branches => throw _privateConstructorUsedError;
/// Serializes this CompanyWithBranches to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of CompanyWithBranches
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$CompanyWithBranchesCopyWith<CompanyWithBranches> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $CompanyWithBranchesCopyWith<$Res> {
factory $CompanyWithBranchesCopyWith(
CompanyWithBranches value, $Res Function(CompanyWithBranches) then) =
_$CompanyWithBranchesCopyWithImpl<$Res, CompanyWithBranches>;
@useResult
$Res call({CompanyResponse company, List<BranchListDto> branches});
$CompanyResponseCopyWith<$Res> get company;
}
/// @nodoc
class _$CompanyWithBranchesCopyWithImpl<$Res, $Val extends CompanyWithBranches>
implements $CompanyWithBranchesCopyWith<$Res> {
_$CompanyWithBranchesCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of CompanyWithBranches
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? company = null,
Object? branches = null,
}) {
return _then(_value.copyWith(
company: null == company
? _value.company
: company // ignore: cast_nullable_to_non_nullable
as CompanyResponse,
branches: null == branches
? _value.branches
: branches // ignore: cast_nullable_to_non_nullable
as List<BranchListDto>,
) as $Val);
}
/// Create a copy of CompanyWithBranches
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$CompanyResponseCopyWith<$Res> get company {
return $CompanyResponseCopyWith<$Res>(_value.company, (value) {
return _then(_value.copyWith(company: value) as $Val);
});
}
}
/// @nodoc
abstract class _$$CompanyWithBranchesImplCopyWith<$Res>
implements $CompanyWithBranchesCopyWith<$Res> {
factory _$$CompanyWithBranchesImplCopyWith(_$CompanyWithBranchesImpl value,
$Res Function(_$CompanyWithBranchesImpl) then) =
__$$CompanyWithBranchesImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({CompanyResponse company, List<BranchListDto> branches});
@override
$CompanyResponseCopyWith<$Res> get company;
}
/// @nodoc
class __$$CompanyWithBranchesImplCopyWithImpl<$Res>
extends _$CompanyWithBranchesCopyWithImpl<$Res, _$CompanyWithBranchesImpl>
implements _$$CompanyWithBranchesImplCopyWith<$Res> {
__$$CompanyWithBranchesImplCopyWithImpl(_$CompanyWithBranchesImpl _value,
$Res Function(_$CompanyWithBranchesImpl) _then)
: super(_value, _then);
/// Create a copy of CompanyWithBranches
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? company = null,
Object? branches = null,
}) {
return _then(_$CompanyWithBranchesImpl(
company: null == company
? _value.company
: company // ignore: cast_nullable_to_non_nullable
as CompanyResponse,
branches: null == branches
? _value._branches
: branches // ignore: cast_nullable_to_non_nullable
as List<BranchListDto>,
));
}
}
/// @nodoc
@JsonSerializable()
class _$CompanyWithBranchesImpl implements _CompanyWithBranches {
const _$CompanyWithBranchesImpl(
{required this.company, final List<BranchListDto> branches = const []})
: _branches = branches;
factory _$CompanyWithBranchesImpl.fromJson(Map<String, dynamic> json) =>
_$$CompanyWithBranchesImplFromJson(json);
@override
final CompanyResponse company;
final List<BranchListDto> _branches;
@override
@JsonKey()
List<BranchListDto> get branches {
if (_branches is EqualUnmodifiableListView) return _branches;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_branches);
}
@override
String toString() {
return 'CompanyWithBranches(company: $company, branches: $branches)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$CompanyWithBranchesImpl &&
(identical(other.company, company) || other.company == company) &&
const DeepCollectionEquality().equals(other._branches, _branches));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType, company, const DeepCollectionEquality().hash(_branches));
/// Create a copy of CompanyWithBranches
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$CompanyWithBranchesImplCopyWith<_$CompanyWithBranchesImpl> get copyWith =>
__$$CompanyWithBranchesImplCopyWithImpl<_$CompanyWithBranchesImpl>(
this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$CompanyWithBranchesImplToJson(
this,
);
}
}
abstract class _CompanyWithBranches implements CompanyWithBranches {
const factory _CompanyWithBranches(
{required final CompanyResponse company,
final List<BranchListDto> branches}) = _$CompanyWithBranchesImpl;
factory _CompanyWithBranches.fromJson(Map<String, dynamic> json) =
_$CompanyWithBranchesImpl.fromJson;
@override
CompanyResponse get company;
@override
List<BranchListDto> get branches;
/// Create a copy of CompanyWithBranches
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$CompanyWithBranchesImplCopyWith<_$CompanyWithBranchesImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -0,0 +1,48 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'company_list_dto.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$CompanyListDtoImpl _$$CompanyListDtoImplFromJson(Map<String, dynamic> json) =>
_$CompanyListDtoImpl(
id: (json['id'] as num).toInt(),
name: json['name'] as String,
address: json['address'] as String,
contactName: json['contact_name'] as String,
contactPhone: json['contact_phone'] as String,
isActive: json['is_active'] as bool,
branchCount: (json['branch_count'] as num?)?.toInt() ?? 0,
);
Map<String, dynamic> _$$CompanyListDtoImplToJson(
_$CompanyListDtoImpl instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'address': instance.address,
'contact_name': instance.contactName,
'contact_phone': instance.contactPhone,
'is_active': instance.isActive,
'branch_count': instance.branchCount,
};
_$CompanyWithBranchesImpl _$$CompanyWithBranchesImplFromJson(
Map<String, dynamic> json) =>
_$CompanyWithBranchesImpl(
company:
CompanyResponse.fromJson(json['company'] as Map<String, dynamic>),
branches: (json['branches'] as List<dynamic>?)
?.map((e) => BranchListDto.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);
Map<String, dynamic> _$$CompanyWithBranchesImplToJson(
_$CompanyWithBranchesImpl instance) =>
<String, dynamic>{
'company': instance.company,
'branches': instance.branches,
};

View File

@@ -6,9 +6,11 @@ import '../data/datasources/remote/api_client.dart';
import '../data/datasources/remote/auth_remote_datasource.dart';
import '../data/datasources/remote/dashboard_remote_datasource.dart';
import '../data/datasources/remote/equipment_remote_datasource.dart';
import '../data/datasources/remote/company_remote_datasource.dart';
import '../services/auth_service.dart';
import '../services/dashboard_service.dart';
import '../services/equipment_service.dart';
import '../services/company_service.dart';
/// GetIt 인스턴스
final getIt = GetIt.instance;
@@ -35,6 +37,9 @@ Future<void> setupDependencies() async {
getIt.registerLazySingleton<EquipmentRemoteDataSource>(
() => EquipmentRemoteDataSourceImpl(),
);
getIt.registerLazySingleton<CompanyRemoteDataSource>(
() => CompanyRemoteDataSourceImpl(),
);
// 서비스
getIt.registerLazySingleton<AuthService>(
@@ -46,6 +51,9 @@ Future<void> setupDependencies() async {
getIt.registerLazySingleton<EquipmentService>(
() => EquipmentService(),
);
getIt.registerLazySingleton<CompanyService>(
() => CompanyService(),
);
// 리포지토리
// TODO: Repositories will be registered here

View File

@@ -200,14 +200,41 @@ class _CompanyFormScreenState extends State<CompanyFormScreen> {
}
// 회사 저장
void _saveCompany() {
Future<void> _saveCompany() async {
final duplicateCompany = _controller.checkDuplicateCompany();
if (duplicateCompany != null) {
DuplicateCompanyDialog.show(context, duplicateCompany);
return;
}
if (_controller.saveCompany()) {
Navigator.pop(context, true);
// 로딩 표시
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const Center(
child: CircularProgressIndicator(),
),
);
try {
final success = await _controller.saveCompany();
if (mounted) {
Navigator.pop(context); // 로딩 다이얼로그 닫기
if (success) {
Navigator.pop(context, true);
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('회사 저장에 실패했습니다.')),
);
}
}
} catch (e) {
if (mounted) {
Navigator.pop(context); // 로딩 다이얼로그 닫기
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('오류가 발생했습니다: $e')),
);
}
}
}

View File

@@ -533,9 +533,8 @@ class EquipmentOutFormController extends ChangeNotifier {
} else {
onError('출고 정보를 찾을 수 없습니다');
}
}
} else {
if (selectedEquipments != null && selectedEquipments!.isNotEmpty) {
} else {
if (selectedEquipments != null && selectedEquipments!.isNotEmpty) {
// 여러 회사에 각각 출고 처리
List<String> successCompanies = [];
@@ -591,7 +590,7 @@ class EquipmentOutFormController extends ChangeNotifier {
} else {
onSuccess('${successCompanies.join(", ")} 회사로 다중 장비 출고 처리 완료');
}
} else if (selectedEquipmentInId != null) {
} else if (selectedEquipmentInId != null) {
final equipment = Equipment(
manufacturer: manufacturer,
name: name,
@@ -722,7 +721,6 @@ class EquipmentOutFormController extends ChangeNotifier {
onSuccess('${successCompanies.join(", ")} 회사로 새 출고 장비 추가 완료');
}
}
}
} on Failure catch (e) {
_error = e.message;
onError(e.message);

View File

@@ -0,0 +1,291 @@
import 'package:get_it/get_it.dart';
import 'package:superport/core/errors/exceptions.dart';
import 'package:superport/core/errors/failures.dart';
import 'package:superport/data/datasources/remote/company_remote_datasource.dart';
import 'package:superport/data/models/company/company_dto.dart';
import 'package:superport/data/models/company/company_list_dto.dart';
import 'package:superport/data/models/company/branch_dto.dart';
import 'package:superport/models/company_model.dart';
import 'package:superport/models/address_model.dart';
class CompanyService {
final CompanyRemoteDataSource _remoteDataSource = GetIt.instance<CompanyRemoteDataSource>();
// 회사 목록 조회
Future<List<Company>> getCompanies({
int page = 1,
int perPage = 20,
String? search,
bool? isActive,
}) async {
try {
final dtoList = await _remoteDataSource.getCompanies(
page: page,
perPage: perPage,
search: search,
isActive: isActive,
);
return dtoList.map((dto) => _convertListDtoToCompany(dto)).toList();
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to fetch company list: $e');
}
}
// 회사 생성
Future<Company> createCompany(Company company) async {
try {
final request = CreateCompanyRequest(
name: company.name,
address: company.address.toString(),
contactName: company.contactName ?? '',
contactPosition: company.contactPosition ?? '',
contactPhone: company.contactPhone ?? '',
contactEmail: company.contactEmail ?? '',
companyTypes: company.companyTypes.map((e) => e.toString().split('.').last).toList(),
remark: company.remark,
);
final response = await _remoteDataSource.createCompany(request);
return _convertResponseToCompany(response);
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to create company: $e');
}
}
// 회사 상세 조회
Future<Company> getCompanyDetail(int id) async {
try {
final response = await _remoteDataSource.getCompanyDetail(id);
return _convertResponseToCompany(response);
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to fetch company detail: $e');
}
}
// 회사와 지점 정보 함께 조회
Future<Company> getCompanyWithBranches(int id) async {
try {
final response = await _remoteDataSource.getCompanyWithBranches(id);
final company = _convertResponseToCompany(response.company);
final branches = response.branches.map((dto) => _convertBranchDtoToBranch(dto)).toList();
return company.copyWith(branches: branches);
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to fetch company with branches: $e');
}
}
// 회사 수정
Future<Company> updateCompany(int id, Company company) async {
try {
final request = UpdateCompanyRequest(
name: company.name,
address: company.address.toString(),
contactName: company.contactName,
contactPosition: company.contactPosition,
contactPhone: company.contactPhone,
contactEmail: company.contactEmail,
companyTypes: company.companyTypes.map((e) => e.toString().split('.').last).toList(),
remark: company.remark,
);
final response = await _remoteDataSource.updateCompany(id, request);
return _convertResponseToCompany(response);
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to update company: $e');
}
}
// 회사 삭제
Future<void> deleteCompany(int id) async {
try {
await _remoteDataSource.deleteCompany(id);
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to delete company: $e');
}
}
// 회사명 목록 조회 (드롭다운용)
Future<List<Map<String, dynamic>>> getCompanyNames() async {
try {
final dtoList = await _remoteDataSource.getCompanyNames();
return dtoList.map((dto) => {
'id': dto.id,
'name': dto.name,
}).toList();
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to fetch company names: $e');
}
}
// 지점 관련 메서드들
Future<Branch> createBranch(int companyId, Branch branch) async {
try {
final request = CreateBranchRequest(
branchName: branch.name,
address: branch.address.toString(),
phone: branch.contactPhone ?? '',
managerName: branch.contactName,
managerPhone: branch.contactPhone,
remark: branch.remark,
);
final response = await _remoteDataSource.createBranch(companyId, request);
return _convertBranchResponseToBranch(response);
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to create branch: $e');
}
}
Future<Branch> getBranchDetail(int companyId, int branchId) async {
try {
final response = await _remoteDataSource.getBranchDetail(companyId, branchId);
return _convertBranchResponseToBranch(response);
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to fetch branch detail: $e');
}
}
Future<Branch> updateBranch(int companyId, int branchId, Branch branch) async {
try {
final request = UpdateBranchRequest(
branchName: branch.name,
address: branch.address.toString(),
phone: branch.contactPhone,
managerName: branch.contactName,
managerPhone: branch.contactPhone,
remark: branch.remark,
);
final response = await _remoteDataSource.updateBranch(companyId, branchId, request);
return _convertBranchResponseToBranch(response);
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to update branch: $e');
}
}
Future<void> deleteBranch(int companyId, int branchId) async {
try {
await _remoteDataSource.deleteBranch(companyId, branchId);
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to delete branch: $e');
}
}
Future<List<Branch>> getCompanyBranches(int companyId) async {
try {
final dtoList = await _remoteDataSource.getCompanyBranches(companyId);
return dtoList.map((dto) => _convertBranchDtoToBranch(dto)).toList();
} on ServerException catch (e) {
throw Failure(message: e.message);
} catch (e) {
throw Failure(message: 'Failed to fetch company branches: $e');
}
}
// 변환 헬퍼 메서드들
Company _convertListDtoToCompany(CompanyListDto dto) {
return Company(
id: dto.id,
name: dto.name,
address: Address.fromFullAddress(dto.address),
contactName: dto.contactName,
contactPhone: dto.contactPhone,
companyTypes: [CompanyType.customer], // 기본값, 실제로는 API에서 받아와야 함
);
}
Company _convertResponseToCompany(CompanyResponse dto) {
final companyTypes = dto.companyTypes.map((typeStr) {
if (typeStr.contains('partner')) return CompanyType.partner;
return CompanyType.customer;
}).toList();
return Company(
id: dto.id,
name: dto.name,
address: Address.fromFullAddress(dto.address),
contactName: dto.contactName,
contactPosition: dto.contactPosition,
contactPhone: dto.contactPhone,
contactEmail: dto.contactEmail,
companyTypes: companyTypes.isEmpty ? [CompanyType.customer] : companyTypes,
remark: dto.remark,
);
}
Branch _convertBranchDtoToBranch(BranchListDto dto) {
return Branch(
id: dto.id,
companyId: dto.companyId,
name: dto.branchName,
address: Address.fromFullAddress(dto.address),
contactName: dto.managerName,
contactPhone: dto.phone,
);
}
Branch _convertBranchResponseToBranch(BranchResponse dto) {
return Branch(
id: dto.id,
companyId: dto.companyId,
name: dto.branchName,
address: Address.fromFullAddress(dto.address),
contactName: dto.managerName,
contactPhone: dto.phone,
remark: dto.remark,
);
}
}
// Company 모델에 copyWith 메서드가 없다면 extension으로 추가
extension CompanyExtension on Company {
Company copyWith({
int? id,
String? name,
Address? address,
String? contactName,
String? contactPosition,
String? contactPhone,
String? contactEmail,
List<Branch>? branches,
List<CompanyType>? companyTypes,
String? remark,
}) {
return Company(
id: id ?? this.id,
name: name ?? this.name,
address: address ?? this.address,
contactName: contactName ?? this.contactName,
contactPosition: contactPosition ?? this.contactPosition,
contactPhone: contactPhone ?? this.contactPhone,
contactEmail: contactEmail ?? this.contactEmail,
branches: branches ?? this.branches,
companyTypes: companyTypes ?? this.companyTypes,
remark: remark ?? this.remark,
);
}
}