반응형

0. 복식부기


부기(簿 문서 부, 記 기록할 기)’란 장부를 작성하는 방법을 말한다. 자산, 자본, 부채가 늘어나거나 줄어든 것을 정확하게 계산, 기록, 정리하는 기술이다.

 

복식(複 겹옷 복, 式 법 식)’은 부기의 한 방법이다. 단식부기는 한쪽 측면에서만, 복식부기는 두 개의 계정에 모든 거래를 수입 또는 지출로 기록하는 장부 작성 방법이다.

 

복식부기(Double Entry Book keeping)는 회계상의 거래를 기록하는 수단으로, 모든 거래를 두 개의 방향, 차변대변으로 대응시켜 기록하는 회계 기법이다. 동일한 개념으로 이중부기 회계원칙(double-entry accounting principle)이라고도 한다.

 

이 방식의 기본 원리는 “모든 거래는 차변과 대변에 동시에 기록되며 차변의 합계와 대변의 합계는 항상 일치해야 한다”이다.

 

 

 

보통 복식부기 원칙에 따라 자산이 증가하면 차변에, 부채가 증가하면 대변에 적는다.

 

거래를 통해 발생하는 기업의 재무적인 변화는 자산, 부채, 자본, 수익 및 비용 등 5가지 계정과목들의 증감의 표시를 통해 보고되는데 거래를 통한 이들 계정과목들의 증감을 표시하는 복식부기의 방법으로 오랫동안 차변(Debit)과 대변(Credit)의 분개(Journalizing) 방법이 사용되어 왔다.

 

(분개란 회계상의 거래를 차변요소와 대변요소로 분류하고 어떤 계정과목을 기입하고 얼마의 금액을 기입할 것인가를 결정하는 절차를 말한다.)

 

 

 

 

1. 차변과 대변


차변과 대변은 거래를 기록할 때 사용되는 용어로, 거래에서 많이 사용되는 사람의 호칭으로, 돈을 꾼 사람을 "차인(借人 : Debtor)"과 돈을 빌려준 사람을 부르는 "대인(貸人 : Creditior)으로 부르던 것이 오늘날에 와서 "차변""대변"이 되었다.

 

차변 (借邊, Debit)

  • “자산의 증가, 부채의 감소, 자본의 감소, 비용의 발생”을 왼쪽에 기입
  • 회사가 가진 자원(자산)이나 소비한 비용을 나타냄
  • 자산↑ / 부채↓ / "돈을 사용한 곳"

대변 (貸邊, Credit)

  • “자산의 감소, 부채의 증가, 자본의 증가, 수익의 발생”을 오른쪽에 기입
  • 조달한 원천(부채, 자본, 수익)
  • 부채↑ / 자본↑ / "돈이 들어온 출처"

 

여기서, 돈을 사용한 곳과 돈이 들어온 출처라는 표현은 현금 거래를 중심으로 설명할 때 이해하기 쉽지만, 실제로 분개장을 보면 헷갈릴 수 있다.

 

복식부기에서 차변과 대변은 단순히 들어오고 나가는 것이 아니라, 각 계정의 성질에 따라 증가와 감소를 나타내기에  정확하게 이해하기 위해서는 각 계정의 성질에 따른 증가와 감소를 이해해야 한다.

 

1. 자산 계정: 차변은 증가, 대변은 감소

2. 부채와 자본 계정: 차변은 감소, 대변은 증가

3. 비용 계정: 차변은 발생, 대변은 취소

4. 수익 계정: 차변은 취소 대변은 발생

 

이러한 관계를 "거래의 8요소"라 한다.

 

 

 

 

2. 거래의 8요소


거래의 8요소는 자산, 부채, 자본, 수익, 비용의 증가와 감소를 말한다. 회계상 거래는 이러한 8가지 요소로 구성되어 있다.

 

차변 대변
자산의 증가 ➕ 자산의 감소 ➖
부채의 감소 ➖ 부채의 증가 ➕
자본의 감소 ➖ 자본의 증가 ➕
비용의 발생 💸 수익의 발생 💸

 

 

위의 항등식의 오른쪽(대변)은 경제적 자원이 어디에서 조달되었는가 하는 출처를 나타내고, 왼쪽(차변)은 그렇게 조달된 자원이 현재 어떤 상태에 있는가의 현황 내지 운용을 나타낸다.

 

즉, 기업이 어느 시점에 보유하고 있는 자산의 총금액은 부채의 총금액과 자본의 총금액을 더한 것과 같다는 뜻이다. 기업이 보유한 자산을 처분한 후 빚을 갚고 난 금액이 주주들이 나눠 가져야 할 금액인 자본이 되는 것이다.

 

이를 확장하면 ‘자산 + 비용 = 부채 + 자본 + 수익’ 이 된다.

 

 

자산은 그 자체로 아무것도 할 수 없다. 돈이든 건물이든 가지고 있어야 의미가 없고 이것을 비용으로 소비해야 수익이 창출된다. 쓰지 않고 놔두면 현금성 자산은 이자율만큼, 유형 자산은 감가상각비만큼 계속적으로 손실이 발생한다.

 

결국 기업은 자산 자체가 아닌 자산을 사용함으로써(비용화함으로써) 돈을 버는 것이다. 회사의 자산인 원재료, 부품, 빌딩 혹은 영업용 차량은 다 비용으로 바뀌어야 수익을 창출할 수 있다.

 

회계는 정태적 관점(재무상태표)뿐 아니라 동태적 관점(손익계산서)을 통해 기업 활동을 설명한다. 회사는 자본부채로 자금을 조달하여(대변), 이를 통해 자산을 형성하고(차변) 사업 활동을 시작한다. 사업 활동 중 비용이 발생하고(차변), 이를 통해 수익을 창출하며(대변), 최종적으로 이익은 다시 자본으로 귀속된다.

 

다시 말해 모든 자산은 채권자와 주주에게 속해있다는 중요한 의미이다. 회사라는 독립체는 어떤 것도 직접 소유한 것이 없으며 모든 자산은 부채를 소유했거나, 지분을 소유한 이들에게 돌아갈 수밖에 없다.

 

 

 

 

반응형

지난 글(WebSocket)에 이어서 STOMP에 대해 알아보자.

 

 

1. STOMP


STOMP(Simple/Streaming Text Oriented Messaging Protocol)란 클라이언트와 서버 간의 메시지 전송을 위한 텍스트 기반 프로토콜이다.

 

이 프로토콜은 Publish-Subscribe 구조를 기반으로 하며, Spring의 내장 브로커인 SimpleBroker나 외부 메시지 브로커(RabbitMQ, Redis, Kafka 등)를 활용하여 발신자(Publisher)와 수신자(Subscriber) 간의 메시지를 쉽게 주고받을 수 있다.

 

STOMP는 메시징 프로토콜이며, 발행자(Publisher)가 메시지를 생성하면 브로커가 이를 관리하고 구독자(Subscriber)에게 전달한다.

 

 

 

2. STOMP 구조


이전 글에서 WebSocket을 알아보며, 메세지 형식에 대한 규격이 없어 개발자가 직접 정의해야 하는 문제점들을 언급했다. STOMP를 사용하면 형식을 따로 고민할 필요도, 파싱하기 위한 코드를 구현할 필요도 없다.

 

STOMP는 프레임(frame)이라고 해서 Command, header, body로 이미 형식을 정의해 두었다.

frame

COMMAND
header1:value1
header2:value2

Body
  • Command는 메세지 유형을 나타내며 CONNECT, SEND, SUBSCRIBE 등이 있다.
  • Header은 메시지에 대한 부가 정보를 key-value 형태로 제공한다. 대표적으로 'destination' 헤더는 메시지의 목적지를 지정한다.
  • Body에 실제 전송할 데이터 내용을 포함하게 된다.

 

좌: WebSocket, 우: STOMP

 

 

 

3. STOMP 통신 흐름


STOMP 통신 흐름은 발신자, 서버, 브로커, 구독자 간의 상호작용을 통해 이루어진다.

 

STOMP 프로토콜에서 /topic/app 접두사는 다음과 같은 의미를 가진다.

  1. /topic : 이 접두사를 사용하면 메시지가 직접 메시지 브로커로 전달되어 해당 토픽을 구독하고 있는 모든 클라이언트에게 즉시 발행된다.
  2. /app : 이 접두사는 애플리케이션의 @MessageMapping 메서드로 메시지를 라우팅한다. 이 메서드에서 메시지를 처리한 후, 개발자가 명시적으로 SimpMessagingTemplate을 사용하여 /topic으로 메시지를 전송해야 구독자들에게 발행이 된다.

 

따라서, /app으로 들어온 메시지는 서버에서 추가 처리(데이터베이스 저장, 메시지 변환, 인증 등)를 할 수 있는 기회를 제공하며, 이 처리 후에 개발자가 명시적으로 /topic으로 메시지를 전송해야 구독자들에게 발행된다.

 

이러한 구조는 단순히 메시지를 전달하는 경우와 서버에서 추가 로직이 필요한 경우를 유연하게 처리할 수 있게 해준다.

 

 

 

4. Spring STOMP


이전에 WebSocket을 구현해 볼 때 사용했던 WebSocket King Client의 경우 Command, header, body로 이루어진 STOMP의 프레임 타입을 지원하지 않는다. 따라서 STOMP 테스트를 만들어준 블로그를 이용하여 구현해 보자.

 

 

4.1 환경설정

WebSocket과 STOMP를 Gradle에 의존성 추가

gradle

implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.webjars:stomp-websocket:2.3.3'

 

 

4.2 Config

java

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // 클라이언트가 구독할 prefix (예: /topic)
        registry.enableSimpleBroker("/topic");
        // 클라이언트가 메시지를 보낼 때 사용할 prefix (예: /app)
        registry.setApplicationDestinationPrefixes("/app");

    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
                .setAllowedOriginPatterns("*");
    }
}

STOMP를 사용하면 더 이상 SocketTextHandler와 같은 저수준 WebSocket 핸들러를 직접 구현할 필요가 없다.

 

STOMP는 메시지 라우팅, 구독 관리, 메시지 형식 등을 추상화하여 제공하므로, 개발자는 비즈니스 로직에 더 집중할 수 있다.

 

대신, @MessageMapping 어노테이션을 사용하여 특정 목적지로 오는 메시지를 처리하는 메서드를 정의하게 된다.

WebSocket 때와 마찬가지로 Tester에서도 .withSockJs() 를 통해 SockJs를 활성화할 수 있지만 오류가 날 수 있으니 제거하고 실습하자.

 

 

4.3 Controller

java

@Controller
@RequiredArgsConstructor
public class ChatController {

    private final SimpMessagingTemplate messagingTemplate;

    @MessageMapping("/chat/enter")
    public void enterChatRoom(@RequestBody ChatDto chatDto, SimpMessageHeaderAccessor headerAccessor) {
        Map<String, Object> sessionAttributes = headerAccessor.getSessionAttributes();

        sessionAttributes.put("id", chatDto.getId());
        sessionAttributes.put("roomCode", chatDto.getRoomCode());

        String joinMessage = chatDto.getId() + "님이 입장하셨습니다.";
        messagingTemplate.convertAndSend("/topic/chat/room/" + chatDto.getRoomCode(), joinMessage);
    }

    @MessageMapping("/chat/send")
    public void sendMessage(@RequestBody ChatDto chatDto) {
        String msg = chatDto.getId() + ": " + chatDto.getMessage();
        messagingTemplate.convertAndSend("/topic/chat/room/" + chatDto.getRoomCode(), msg);
    }
}

@MessageMapping 어노테이션이 붙은 메서드는 WebSocketConfig에서 설정한 applicationDestinationPrefixes ("/app")와 결합된다. 따라서 클라이언트에서 "/app/chat/enter"로 보낸 메시지가 이 메서드로 라우팅 된다.

 

enterChatRoom 메서드는 사용자의 채팅방 입장을 처리한다. 세션 속성에 사용자 ID와 roomCode를 저장하고 입장 메시지를 생성한다. 그 후, messagingTemplate을 사용하여 "/topic/chat/room/{roomCode}" 목적지로 메시지를 전송하며 해당 채팅방을 구독 중인 모든 클라이언트에게 전달된다.

 

sendMessage 메서드에서 메세지를 가공하거나 DB에 저장하는 로직을 추가할 수 있다. DB 연결은 생략하고 메세지만 다음과 같이 가공하여 보내보자. String msg = chatDto.getId() + ": " + chatDto.getMessage();

 

 

4.4 Dto

java

@Data
public class ChatDto {
    private String id;
    private String roomCode;
    private String message;
}

DB가 없으니 Entity는 생략하고 Dto만 간단히 만들어보자.

 

 

4.5 SpringBoot + STOMP TESTER

먼저 STOMP TESTER 에 접속 후 창을 2개 켜서 같은 채팅방에 구독하고, 입장 해보자

 

DESTINATION PATH: /app/chat/enter

MESSAGE(JSON): {"id": "User1", "roomCode": "ROOM123"}

위와 같이 /topic/chat/room/ROOM123으로 구독한 후

 

유저의 정보와 채팅방 정보를 담은 메세지를 보내게 되면 채팅방 입장 메세지가 구독한 유저에게 모두 보이게 된다.

이후로는 아래와 같이 JSON 객체에 message 변수를 추가하여 메세지를 보낼 수 있다.

 

DESTINATION PATH: /app/chat/send

MESSAGE(JSON): {"id": "User1", "roomCode": "ROOM123", "message":"Hello"}

 

 

 

마치며,

 

WebSocket이 단순히 클라이언트-서버 간 1:1 통신을 제공하는 반면, STOMP를 사용하면서 메시지 브로커를 통한 중앙 집중식 구조를 가질 수 있게 되었다.

 

이로 인해 메시지의 관리와 분배가 더 체계적으로 이루어질 수 있으며, 개발자는 복잡한 메시징 로직 구현에 집중하기보다는 비즈니스 로직에 더 집중할 수 있다.

반응형

1. Socket


소켓네트워크에서 데이터를 주고받을 수 있도록 네트워크 환경에 연결할 수 있게 만들어진 연결부이다.

 

마치 전화기와 비슷하다. 두 사람이 전화로 대화하려면 각자 전화기가 필요하듯이, 두 컴퓨터 프로그램이 대화하려면 각각 소켓이 필요하다. 따라서 클라이언트 소켓, 서버 소켓으로 구분된다.

 

현재 대부분의 네트워크 통신은 인터넷 프로토콜을 사용하며, 대표적으로 TCP/IP, UDP/IP가 존재한다. TCP와 UDP는 소켓을 통해 구현되는 가장 흔한 프로토콜이다.

 

 

 

2. WebSocket


웹 소켓하나의 TCP 접속에 전이중 통신 채널을 제공하는 컴퓨터 통신 프로토콜로, 소켓 통신에 기반하여 웹 애플리케이션에 맞게 발전한 형태이다. HTTP나 HTTPS 위에서 동작하도록 설계되었으며, 서버와 브라우저 간 연결을 유지한 상태로 추가적인 HTTP 요청 없이 데이터를 교환할 수 있다.

 

 

2.1 HTTP와 WebSocket의 차이

Http와 WebSocket Protocol의 가장 큰 차이는 수립된 커넥션을 어떻게 하느냐이다.

 

Http는 비 연결성 프로토콜로 클라이언트가 요청을 보낼 때마다 연결을 맺고 응답을 받은 후 연결을 끊어버린다.

웹 소켓 이전의 HTTP 기반으로 한 실시간 통신 방식으로 폴링(Polling)롱 폴링(Long Polling)이 있지만, 클라이언트가 요청을 지속적으로 보내야 하는 상황을 벗어나지 못했다.

 

반면에 웹 소켓의 경우 한번 연결을 맺고 나면 어느 한쪽에서 연결을 끊으라는 요청을 보내기 전까지 연결을 유지하기 때문에 매번 연결할 때마다 발생하는 비용을 줄일 수 있다.

 

다시한번 정리하면 HTTP는 요청과 응답이 한 쌍을 이루는 구조로 통신을 한다. 즉, 내가 원하는 어떤 것을 얻기 위해서는 항상 그것을 달라고 요청을 해야했다. 반면, 웹 소켓은 연결이 계속 유지되고 있는 상태이기 때문에, 연결된 채널, 소켓을 통해 상대가 보내오는 메세지를 듣기만 하면 된다.

 

그렇다면 WebSocket은 어떻게 연결되는 것일까?

 

 

2.2 핸드셰이크(handShake)

웹 소켓 커넥션을 만들려면 new WebSocket() 을 호출하면 되며 이때 handShake라는 과정을 HTTP 프로토콜을 사용해 시작한다.

 

핸드 셰이크가 성공적으로 완료되면, 연결은 HTTP에서 WebSocket Protocol로 전환되며 HTTP → ws://, HTTPS → wss:// 로 변경된다.

 

 

 

3. SpringBoot + WebSocket King Client


Chrome 확장 프로그램인 WebSocket King Client에서 WebSocket을 구현해보자.

 

 

3.1 환경설정

  • Chrome에서 WebSocket King Client 설치 후 접속
  • Spring Boot 2.7.18
  • Java 11

 

websocket과 JSON을 사용하기 위해 Gradle에 의존성 추가

gradle

    implementation 'org.springframework.boot:spring-boot-starter-websocket'
    implementation 'org.json:json:20211205'

 

 

3.2 Config

Spring에서 웹 소켓을 사용하려면 클라이언트가 보내오는 통신을 처리할 Handler가 필요하다.

java

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new SocketTextHandler(), "/ws")
                .setAllowedOriginPatterns("*");
    }
}

이후 구현할 Handler를 웹 소켓이 연결될 때 handShake할 주소와 함께 인자로 넣어주면 된다.

CORS 제어를 위해 setAllowedOriginPatterns를 설정하여 특정 도메인에서만 WebSocket 연결을 허용할 수 있다.

.withSockJs() 를 통해 SockJs를 활성화 할 수 있지만 WebSocket Client King에서 오류가 날 수 있으니 제거하고 실습하자.

 

 

3.3 Handler

java

public class SocketTextHandler extends TextWebSocketHandler{

    private final Set<WebSocketSession> sessions = ConcurrentHashMap.newKeySet();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
        for (WebSocketSession s : sessions) {
            s.sendMessage(new TextMessage("user: " + session.getId() + " connected"));
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        JSONObject jsonObject = new JSONObject(payload);
        for (WebSocketSession s : sessions) {
            s.sendMessage(new TextMessage(jsonObject.get("user") + ": " +  jsonObject.get("message")));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
        for (WebSocketSession s : sessions) {
            s.sendMessage(new TextMessage("user: " + session.getId() + " disconnected"));
        }
    }
}

 

웹 소켓은 기본적으로 Tex t또는 Binary 타입을 지원한다.

필요에 따라 TextWebSocketHandler 또는 BinaryWebSocketHandler라는 Spring이 기본적으로 제공하는 클래스를 상속하고 구현하면 된다.

 

이때, 메서드 인자로 받아오는 WebSocketSession이 있다. 흔히 말하는 HTTP 세션과는 다른 맥락으로 간단히 말하면 웹 소켓이 연결될 때 생기는 연결정보를 담고 있는 객체라고 보면 된다.

 

핸들러에서 웹 소켓 통신에 대한 처리를 하기 위해 이 세션들을 컬렉션으로 담아 관리하는 경우가 많으며, 위 코드를 보면 커넥션이 맺어질 때 컬렉션에서 웹 소켓 세션을 추가하고 끊어질 때 제거를 하고 있다.

 

추가로 세션이 연결됨과 끊어질 때, 입장과 퇴장 메세지를 보낼 수 있게 설정해놓았다.

 

handleTextMessage는 WebSocket을 통해 텍스트 메세지를 받았을 때 실행되는 핸들러로 받은 메세의 내용(payload, 클라이언트에서 JSON으로 보냈다고 가정)을 각 연결된 세션에 새 메세지를 보내게된다.

 

 

3.4 WebSocket King Client

상단에 CONNECTIONS을 하나 더 늘려 유저 A와 B가 각각 입장하여 채팅을 한다고 테스트해보자.

 

ws://localhost:8080/ws 주소로 연결과 함께 자동으로 부여된 session Id가 출력됨을 확인할 수 있다. /ws는 config에서 설정한 end-point이다.

 

이후 채팅을 JSON 형태로 보내게 되면, Handler에서 ‘user’‘message’ 의 key 값으로 메세지를 처리하는 걸 확인할 수 있다.

 

개발자 도구를 살펴보면 처음 handShake 과정에서 HTTP를 사용하기 때문에 유사한 양의 헤더 정보를 주고받게 되지만 한번 연결이 수립되고 나서는 간단한 Messages들만 오고 가는 것을 확인할 수 있다.

 

 

  • Origin : 클라이언트 origin을 나타낸다.
  • Connection : Upgrade, 클라이언트 측에서 프로토콜을 바꾸고 싶다는 신호를 보냈다는 것을 나타낸다. (http → ws)
  • Upgrade : websocket, 클라이언트 측에서 요청한 프로토콜은 'websocket’이라는 것을 의미한다.
  • Sec-WebSocket-Key : 보안을 위해 브라우저에서 생성한 키로, 서버가 웹 소켓 프로토콜을 지원하는지를 확인하는 데 사용된다.

 

마치며

WebSocket은 실시간 양방향 통신을 제공하는 강력한 기술이지만 몇 가지 한계가 있다.

 

1️⃣ 메세지 구조화

WebSocket은 단순한 텍스트 교환만을 제공하며 메세지 형식에 대한 규격이 없다. 우리는 handler에서 String 값인 payload를 JSON으로 파싱하여 사용하였다. 따라서 복잡한 메시지 패턴이나 로직들을 개발자가 직접 정의해야하고 구현해야 한다.

 

2️⃣ 클라이언트 관리

세션의 ID는 서버가 클라이언트와의 WebSocket 연결될 때 자동으로 생성되는 랜덤한 값이기 때문에 연결된 클라이언트들을 추적하고 관리하는 시스템을 직접 구축해야한다.

 

3️⃣ 메세지 라우팅

특정 주제(Topic)나 채널(Channel)에 따라 메시지를 구분하거나 라우팅하는 기능이 내장되어 있지 않기 때문에, 이를 구현하려면 추가적인 로직과 구조를 설계해야한다.

 

 

 

이러한 어려움을 해결하기 위해 STOMP와 같은 상위 프로토콜을 사용하면 메지 라우팅과 세션 관리를 더 쉽게 구현할 수 있다.

 

다음 글에서는 STOMP에 대해 알아보고 실습해 보는 시간을 가져보자.

 

 

[Spring] STOMP란? (Spring Boot + STOMP TESTER로 구현해보기)

지난 글(WebSocket)에 이어서 STOMP에 대해 알아보자.  1. STOMPSTOMP(Simple/Streaming Text Oriented Messaging Protocol)란 클라이언트와 서버 간의 메시지 전송을 위한 텍스트 기반 프로토콜이다. 이 프로토콜은 Pu

murphytklee.tistory.com

 

반응형

건설업의 매출액 회계 처리는 다른 업종과 특이하게 진행 기준으로 결정한다.

 

다시 말해 건설업은 장기 건설(1년 이상) 공사 특성상 진행 기준으로 수익을 인식하여야 하고, 단기 건설(1년 미만)일 경우에는 진행 기준 또는 완성 기준으로 수익을 인식할 수 있다.

 

 

1. 도급


都 도읍 도, 給 줄 급도

 

도급이란 원도급, 하도급, 위탁 기타 명칭 여하에 불구하고 공사를 완성할 것을 약정하고 상대방이 그 일의 결과에 대하여 대가를 지급할 것을 약정하는 계약이다.

  • 원도급 : 일의 완성을 전제로 위탁하는 행위 (ex 종합 건설사)
  • 하도급 : 도급인에게 위탁받은 일을 하는 행위 (ex 하청업체)
  • 공동도급 : 계약에 대하여 2인 이상의 계약 상대자가 이행에 필요한 자격, 면허, 허가, 등록 등을 상호 보완하기 위해 이행하는 계약

 

 

예를 들어 현대건설, 사우디 5125억 원 규모 송전선로 건설사업 잇따라 수주”라는 기사를 보았을 때,

사우디 전력청(SEC)은 발주처가, 종합건설(원도급사)는 현대건설이 되어 전문건설(하도급 업체)에게 다시 도급시키게 된다.

 

이러한 복잡한 계약 속에서 진행 기준을 척도 하는 것이 기성이다.

 

 

 

2. 기성


旣 이미 기 , 成 이룰 성

 

기성이란 공사의 진척도 또는 진행 정도를 말한다. 예를 들어, 도급액 100,000,000원에 대한 50% 기성률에 대한 기성금액은 50,000,000원이다.

 

건설공사는 공사 완료 전에는 정확한 원가를 알 수 없기 때문에 일정 시점에서의 공사 완성도를 파악하여 향후 잔여 공사에 대한 예측 관리를 하고 손익에 대한 분석을 통해 손익 추정을 가능하게 한다.

 

건설사가 분기마다 발주처에 청구하여 받는 금액도 도급기성이며, 하도급 업체가 월마다 한 달간 일한 금액을 건설사로부터 받는 금액도 하도급기성이다.

 

기성의 주기는 계약 시 결정하기 나름이며 일반적으로 건설사가 하도급업체에게 기성을 줄 때 한 달이 통상적이며 발주처가 건설사에게 주는 도급 기성은 도급 계약 체결에 따라 분기가 될 수도 있고, 2회가 될 수도 있다. 그 외 마일스톤 계약일 경우 공정 단계별로 대금을 청구할 수 있으며 건설사가 원가를 투입한 시점과 발주처가 공사 금액을 인정하는 시점 간의 차이로 미청구 공사가 발생할 수도 있다.

 

따라서 건설사는 진행 기준으로 도급 기성과 실행 기성(공사원가)으로 손익을 계산하고, 실적과 계획을 관리하게 된다.

 

 

 

3. 공사 원가와 손익


 

원가란 어떤 목적 활동을 수행하는 과정에서 발생했거나 발생할 수 있는 소비를 화폐단위로 측정한 것으로 건설 산업의 원가로는 자재, 노무, 외주 등의 비용과 관리비의 합(직접 공사비 + 간접 공사비)으로 구성된다.

 

손익이란 도급 기성에서 공사원가를 제외한 값으로 공사를 수행하는 과정에서 발생하는 수익과 비용의 차이를 말한다.

 

건설업에서 손익 계산은 주로 도급 기성과 공사원가를 기반으로 이루어지며 손익 인식은 공사진행기준과 공사완성기준으로 이루어진다.

  • 공사진행률 = 총공사예정원가 / 실제공사비발생액 × 100%

 

결론적으로 건설사에서는 매월 말 각 현장의 공사 진행 상황과 관련 비용을 정확히 기록하며, 도급과 실행을 기성에 따라 관리한다. 이를 통해 완료된 공사에 대한 대금을 적시에 청구하고 수금하여 원활한 현금 흐름을 유지하며 각 프로젝트의 공사 손익을 지속적으로 모니터링하고 필요한 경우 조치를 취할 수 있다.

 

 

 

 

 

공사 관련 포스트

  1. [Construction, 공사] 실행예산이란? (도급, 실행, 표준공종, 예산편성)
  2. [Construction, 공사] 도급, 기성, 공사원가와 손익
반응형

0. Setting


1. node.js 설치

 

2. vue 설치

bash

// (cmd 관리자 실행)
> npm install vue

// 설치확인
> npm vue -v

 

3. vue cli 설치

bash

// (cmd 관리자 실행)
> npm install -g @vue/cli c

// 설치확인
> vue -V

 

 

 

1. Spring Boot Project Initialize


Spring Initializr를 통해 Spring Boot 프로젝트를 생성

 

  •  개발환경
    • Visual Studio Code
    • Java 11
    • Spring Boot 2.7.17

 

 

 

2. Controller


java

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String index() {
        return "index.html";
    }
}
  • Vue.js 가 Build 될 때 생성된 index.html을 return 한다.

 

 

 

3. Vue 프로젝트 생성


  • src/main/java처럼 src/main/vue 로 폴더 구조를 가져가기 위해
  • 관리자 권한으로 실행한 cmd에서 프로젝트의 src\main 로 이동하여 vue.cmd create [프로젝트 명]

bash

src\main> vue.cmd create vue --no-git // src\main에서 폴더와 함께 설치

 

 

vue create 사용 시

  1. 프로젝트 폴더 구조 생성
  2. 필요한 종속성 설치
  3. git init 명령어를 사용하여 프로젝트 폴더에 Git Repository를 초기화 하게 되는데,

--no-git 은 git init을 건너뛰게 된다.

 

 

이후 Vue 버전 선택 하게되면 아래와 같이 Vue 프로젝트가 생성된다.

 

Vue.js를 빌드하면 Spring Boot 내 프로젝트로 빌드 파일이 생성되며, Spring Boot 배포 파일들과 함께 웹 서버로 배포하는 방식이다.

 

 

 

 

4. Config & Build


src\main\vue 에서 Build Directory와 devServer의 proxy를 설정하기 위해 vue.config.js 수정해준다.

 

javascript

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  outputDir: '../resources/static', // Build Directory
    devServer: {
        proxy: 'http://localhost:8080' // Spring Boot Server
    }
})

 

이후 Vue 프로젝트를 cmd에서 Build해준다.

 

bash

>npm run build

 

빌드 후 outputDir 경로에 .vue 파일들이 html, css, js 파일로 변환되고, Spring을 실행하여 localhost:8080 로 접속해보면 Vue로 생성된 화면이 출력되는 것을 확인할 수 있다.

 

App.vue 파일이 메인 페이지에 해당하기 때문에 앞으로는 해당 파일에 코드를 작성해주면 된다.

 

 

 

5. npm run serve


  • 스프링 부트 애플리케이션은 별다른 설정이 없으면 8080 포트를 사용하게 된다. 따라서, Vue 개발용 서버는 따로 설정해주지 않으면 자동적으로 8081, 8082, 8083... 포트를 사용하게 된다.
  • 매번 npm run build 하여 변경사항을 확인할 수 없기에, React와 같이 Hot Reload 기능을 지원하는

npm run serve로 (8081) 개발하면 된다.

 

 

6. Vue Extention Tip


코드 하이라이팅, 오류 검사, 코드 포맷, 디버깅, 자동완성 등을 지원하는 VS Code Extention은 다음과 같다.

  • Vetur
  • Vue - Official : 
  • vue3-snippets-for-vscode

Vetur 설치시 발생하는

vetur can't find ‘tsconfig.json’ or ‘jsconfig.json’ 이나

vetur can't find "package.json' 에러에 대한 해결방법은 해당 포스트 참고

 

[Error] vetur can't find package.json 에러

0. ProblemSpring + Vue 프로젝트 구축 후, VS Code로 Vue 프로젝트를 열었을 때, IDE에서 Vue 문법을 인식하지 못하며 빨간 줄과 함께 해당 오류가 발생했다.vetur can't find tsconfig.json or jsconfig.jsonvetur can't find

murphytklee.tistory.com

 

반응형

1. Value Chain의 정의 및 구성 요소


 

가치사슬은 ‘기업이 원재료 조달부터 생산, 마케팅, 판매, 서비스에 이르기까지 모든 활동을 연결하여 고객에게 가치를 전달하는 전체 과정’이다.

 

각 활동 단계에서 발생하는 부가가치는 최종적으로 기업의 이익으로 연결되며 ‘여러 기능이 종합된 조직의 능력을 파악하기 위한 분석방법’이다.

 

가치 사슬 분석 방법론

 
구성 요소
  • 본원적 활동:
    • 입고(원재료 조달): 원자재와 부품의 구매 및 보관
    • 운영(제조/생산): 원재료의 최종 제품 가공
    • 출고(유통): 고객 전달을 위한 물류 활동
    • 마케팅 및 판매: 제품 홍보와 판매 촉진
    • 서비스: 판매 후 고객 지원 및 애프터서비스
  • 보조 활동:
    • 조달: 필요 자원의 구매 활동
    • 기술 개발: 연구개발과 혁신을 통한 제품·프로세스 개선
    • 인적자원 관리: 직원 채용, 교육, 보상 체계 운영
    • 기업 인프라: 경영, 재무, 법률 등 전반적인 조직 지원 활동

 

 

 

2. Value Chain의 절차와 예시


1️⃣ 산업구조분석

우리 기업의 활동을 산업구조적인 관점에서 접근해 분석하여 전방 및 후방산업에 어떤 기업이 있는지 파악.

 

2️⃣ 내부활동 정의 및 역량분석

우리의 내부활동을 정의하고 필요역량을 파악, 사업에서 성공하려면 어떤 역량이 필요한지를 도출하는 작업으로 강점과 약점을 도출.

 

3️⃣ 차별화분석

요구역량을 중심으로 경쟁기업과의 상대적인 우위를 점하기 위해 경쟁 기업과의 비교, 분석을 통해 상대적인 강점과 약점 도출.

 

4️⃣ 종합결과

가치활동별 강점과 약점을 제시하며 우리 기업이 속한 산업의 포지션과 내·외부 측면에서의 강점과 약점을 종합적으로 파악

 

가치사슬분석(Value Chain Analysis) 분석 방법 및 사례

 

 

 

3. IT 및 디지털 전환에서의 가치 사슬


IT 분야에서의 역할

IT 업계는 가치사슬 분석을 디지털 전환과 프로세스 혁신에 활용할 수 있다. 소프트웨어 개발, 시스템 통합, 데이터 분석, 고객 경험 개선 등에 IT 기술을 접목하여 각 단계의 효율성을 높일 수 있다. 디지털과 AI 기술을 활용한 가치사슬 혁신으로 기업은 운영 데이터와 고객 인사이트를 통합하여 의사결정을 개선하고 운영 효율성을 높인다.

 

디지털 전환

클라우드, AI, IoT 등 디지털 기술은 기존의 아날로그 방식 가치사슬을 재구성하여 실시간 데이터 분석, 예측, 최적화를 가능하게 한다. 이로써 기업은 변화에 민첩하게 대응하고 맞춤형 서비스를 제공할 수 있다.

 

 

 

4. 미래의 가치 사슬


미래의 가치사슬은 디지털화와 AI 기술 발전으로 더욱 유연하고 실시간 데이터 기반의 운영체계로 전환될 것이다.

예측 분석 및 자동화 AI를 활용한 수요 예측, 재고 관리, 맞춤형 서비스로 의사결정의 정확도를 높이고 운영 효율을 극대화 할 수 있다.

 

통합 및 협업 ERP, CRM, SCM 등 다양한 시스템이 클라우드 기반으로 통합되어 기업 전체의 가치사슬을 '디지털 코어'로 관리하고 최적화 될 수 있다.

 

고객 중심의 맞춤화 데이터 분석을 통한 세분화와 맞춤형 서비스로 고객의 변화하는 요구에 신속하게 대응할 수 있다.

기업들은 전통적 가치사슬 분석을 넘어 디지털 기술과 ERP 시스템 기반의 실시간 모니터링, 예측, 프로세스 혁신으로 새로운 경쟁 우위를 확보할 수 있다.

 

 

 

5. 결론


요약하면,

  • 가치사슬은 기업이 원재료 조달부터 최종 고객 서비스까지 수행하는 모든 활동을 통해 부가가치를 창출하고 경쟁 우위를 확보하는 과정이다.
  • 실제 사례를 통해 각 기업이 자신만의 핵심 역량으로 효율적인 가치사슬 관리를 구현할 수 있다.
  • IT와 ERP 분야에서는 디지털 전환, 클라우드 기반 통합 시스템, AI 분석으로 전통적 가치사슬을 재구성하여 운영 효율성을 높이고 실시간 의사결정과 맞춤형 서비스를 제공한다.
  • 미래에는 기술 발전과 디지털 통합이 가속화되어 기업의 가치사슬이 더욱 유연하고 데이터 중심의 실시간 관리 체계로 발전할 것이다.

이처럼 가치사슬은 기업 경영의 근간이 되는 핵심 개념으로, 전략적 분석 도구이자 디지털 전환과 ERP 시스템 발전의 중요한 기반이다.

반응형
반응형

+ Recent posts