ru.apertum.qsystem.common.model.QCustomer.java Source code

Java tutorial

Introduction

Here is the source code for ru.apertum.qsystem.common.model.QCustomer.java

Source

/*
 *  Copyright (C) 2010 {Apertum}Projects. web: www.apertum.ru email: info@apertum.ru
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package ru.apertum.qsystem.common.model;

import java.io.Serializable;
import java.util.LinkedList;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import ru.apertum.qsystem.server.model.QService;
import ru.apertum.qsystem.server.model.QUser;
import ru.apertum.qsystem.server.model.results.QResult;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.Arrays;
import java.util.Date;
import java.util.ServiceLoader;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Transient;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import ru.apertum.qsystem.common.QLog;
import ru.apertum.qsystem.common.CustomerState;
import ru.apertum.qsystem.common.exceptions.ServerException;
import ru.apertum.qsystem.extra.IChangeCustomerStateEvent;
import ru.apertum.qsystem.server.Spring;
import ru.apertum.qsystem.server.model.IidGetter;

/**
 * @author Evgeniy Egorov ?  ?? "". ??? ?  ? . ? ??? ,  ?
 * ?  ? ?????. ??! ? ? ?? ?   , ?   .
 *
 */
@Entity
@Table(name = "clients")
public final class QCustomer implements Comparable<QCustomer>, Serializable, IidGetter {

    public QCustomer() {
        id = new Date().getTime();
    }

    /**
     * ?  ?     . ?  , ..     ?   ?. ? ? ? -
     * ???   .
     *
     * @param number    
     */
    public QCustomer(int number) {
        this.number = number;
        id = new Date().getTime();
        setStandTime(new Date()); // ??    ?
        // ? ? ?? ?  ?   ????  ? ?   ?  
        QLog.l().logger().debug(" ? ?  " + number);
    }

    @Expose
    @SerializedName("id")
    private Long id = new Date().getTime();

    @Id
    @Column(name = "id")
    @Override
    //@GeneratedValue(strategy = GenerationType.AUTO) ???    ??.
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    /**
     * ? "??" ? ,    ??     
     *   -  ?
     */
    @Expose
    @SerializedName("number")
    private Integer number;

    public void setNumber(Integer number) {
        this.number = number;
    }

    @Column(name = "number")
    public int getNumber() {
        return number;
    }

    private Integer stateIn;

    @Column(name = "state_in")
    public Integer getStateIn() {
        return stateIn;
    }

    public void setStateIn(Integer stateIn) {
        this.stateIn = stateIn;
    }

    /**
     * ? "??" ??? ?,    ??   ?? ? ? ?  ??? ?  ? ? 
     *   ?  ?     . ?  ??  ,    ??? ?   .   ?
     * ?- ?    ?  ??  ,     ??  ? ?? ??,    ? ,
     * ? ,    ? ???,   ??.
     *
     * ??? 
     * @see ru.apertum.qsystem.common.Uses
     */
    @Expose
    @SerializedName("state")
    private CustomerState state;

    public void setState(CustomerState state) {
        setState(state, new Long(-1));
    }

    /**
     *  ?    ? 
     *
     * @param state
     * @param newServiceId -     ?    ID  ?    ,  ?  ? ?  ??, ..     ?  
     */
    public void setState(CustomerState state, Long newServiceId) {
        this.state = state;
        stateIn = state.ordinal();

        //   ?   ?      ?
        if (getUser() != null) {
            getUser().getShadow().setCustomerState(state);
        }

        switch (state) {
        case STATE_DEAD:
            QLog.l().logger().debug("?: ? ?  \"" + getPrefix()
                    + getNumber() + "\"    ?");
            getUser().getPlanService(getService()).inkKilled();
            //  ? , ?    . ? ?  
            //  _  ?,  ?,  ?_ , ?
            setStartTime(new Date());
            setFinishTime(new Date());
            saveToSelfDB();
            break;
        case STATE_WAIT:
            QLog.l().logger().debug("?: ?    ?  \""
                    + getPrefix() + getNumber() + "\"");
            break;
        case STATE_WAIT_AFTER_POSTPONED:
            QLog.l().logger().debug(
                    "?: ?      ?    ?  \""
                            + getPrefix() + getNumber() + "\"");
            break;
        case STATE_WAIT_COMPLEX_SERVICE:
            QLog.l().logger().debug(
                    "?: ?  ? ?   .. ? ??   ?  \""
                            + getPrefix() + getNumber() + "\"");
            break;
        case STATE_INVITED:
            QLog.l().logger().debug("?: ? ? ?  \""
                    + getPrefix() + getNumber() + "\"");
            break;
        case STATE_INVITED_SECONDARY:
            QLog.l().logger().debug(
                    "?: ?     ? ?  \""
                            + getPrefix() + getNumber() + "\"");
            break;
        case STATE_REDIRECT:
            QLog.l().logger().debug("?: ?  ?  \""
                    + getPrefix() + getNumber() + "\"");
            getUser().getPlanService(getService()).inkWorked(new Date().getTime() - getStartTime().getTime());
            // ? ?  
            saveToSelfDB();
            break;
        case STATE_WORK:
            QLog.l().logger().debug("?  ? ? ?  \""
                    + getPrefix() + getNumber() + "\"");
            getUser().getPlanService(getService()).upWait(new Date().getTime() - getStandTime().getTime());
            break;
        case STATE_WORK_SECONDARY:
            QLog.l().logger().debug(
                    "?:      ? ? ?  \""
                            + getPrefix() + getNumber() + "\"");
            break;
        case STATE_BACK:
            QLog.l().logger().debug("?: ? ?  \"" + getPrefix()
                    + getNumber() + "\"    ?");
            break;
        case STATE_FINISH:
            QLog.l().logger().debug("?:  ? ?  \"" + getPrefix()
                    + getNumber() + "\"  ");
            getUser().getPlanService(getService()).inkWorked(new Date().getTime() - getStartTime().getTime());
            // ? ?  
            saveToSelfDB();
            break;
        case STATE_POSTPONED:
            QLog.l().logger().debug("? ?  \"" + getPrefix() + getNumber()
                    + "\"    ?? ");
            getUser().getPlanService(getService()).inkWorked(new Date().getTime() - getStartTime().getTime());
            // ? ?  
            saveToSelfDB();
            break;
        }

        //  ??? 
        for (final IChangeCustomerStateEvent event : ServiceLoader.load(IChangeCustomerStateEvent.class)) {
            QLog.l().logger()
                    .info(" SPI ??. ?: " + event.getDescription());
            try {
                event.change(this, state, newServiceId);
            } catch (Throwable tr) {
                QLog.l().logger().error(
                        " SPI ?? ?? . ?: "
                                + tr);
            }
        }
    }

    private void saveToSelfDB() {
        // ? ?  
        final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setName("SomeTxName");
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = Spring.getInstance().getTxManager().getTransaction(def);
        try {
            if (input_data == null) { //     ? ?       ,   ?   
                input_data = "";
            }
            Spring.getInstance().getHt().saveOrUpdate(this);
        } catch (Exception ex) {
            Spring.getInstance().getTxManager().rollback(status);
            throw new ServerException("  ? \n" + ex.toString() + "\n"
                    + Arrays.toString(ex.getStackTrace()));
        }
        Spring.getInstance().getTxManager().commit(status);
        QLog.l().logger().debug(".");
    }

    @Transient
    public CustomerState getState() {
        return state;
    }

    /**
     *  "??"
     */
    @Expose
    @SerializedName("priority")
    private Integer priority;

    public void setPriority(int priority) {
        this.priority = priority;
    }

    @Transient
    public IPriority getPriority() {
        return new Priority(priority);
    }

    /**
     *   ?  . ?  . ?  ,   
     *
     * @param customer
     * @return ???  "??? "(?    ? "? ??     ?") 1 - "??? "
     *  ?  , -1 - "??? "  ?  , 0 -  -1 - ? ???  ?  , ..
     * ?  1 - ??? ?  ?  , .. ? 
     */
    @Override
    public int compareTo(QCustomer customer) {
        int resultCmp = -1 * getPriority().compareTo(customer.getPriority()); // (-1) - ..    ? ???

        if (resultCmp == 0) {
            if (this.getStandTime().before(customer.getStandTime())) {
                resultCmp = -1;
            } else if (this.getStandTime().after(customer.getStandTime())) {
                resultCmp = 1;
            }
        }
        if (resultCmp == 0) {
            QLog.l().logger().warn("    .");
            resultCmp = -1;
        }
        return resultCmp;
    }

    /**
     *   ? ?. ? ? ??.
     */
    @Expose
    @SerializedName("to_service")
    private QService service;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "service_id")
    public QService getService() {
        return service;
    }

    /**
     * ? ?  ? ? ?, ?, ?.  ? ???   ?.   ?  ?
     * addCustomer() ?  ? + ???? ?, ?      XML- ?
     *
     * @param service    NULL
     */
    public void setService(QService service) {
        this.service = service;
        // ? ? ? ???   ?,     ?.
        if (getPrefix() == null) {
            setPrefix(service.getPrefix());
        }
        QLog.l().logger().debug(" \"" + getPrefix() + getNumber()
                + "\" ?  ? \"" + service.getName() + "\"");
    }

    /**
     *   ? 
     */
    private QResult result;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "result_id")
    public QResult getResult() {
        return result;
    }

    public void setResult(QResult result) {
        this.result = result;
        if (result == null) {
            QLog.l().logger().debug(
                    "   ? ?  ??");
        } else {
            QLog.l().logger()
                    .debug("   ? ?: \""
                            + result.getName() + "\"");
        }
    }

    /**
     *   . ? ? ??.
     */
    @Expose
    @SerializedName("from_user")
    private QUser user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    public QUser getUser() {
        return user;
    }

    public void setUser(QUser user) {
        this.user = user;
        QLog.l().logger()
                .debug(" \"" + getPrefix() + getNumber()
                        + (user == null ? "  ,     \""
                                : "   \"" + user.getName() + "\""));
    }

    /**
     * ? ?,   ? ?.
     *
     *  ?.
     */
    @Expose
    @SerializedName("prefix")
    private String prefix;

    @Column(name = "service_prefix")
    public String getPrefix() {
        return prefix;
    }

    @Transient()
    public String getFullNumber() {
        return getPrefix() + getNumber();
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix == null ? "" : prefix;
    }

    @Expose
    @SerializedName("stand_time")
    private Date standTime;

    @Column(name = "stand_time")
    @Temporal(TemporalType.TIMESTAMP)
    public Date getStandTime() {
        return standTime;
    }

    public void setStandTime(Date date) {
        this.standTime = date;
    }

    @Expose
    @SerializedName("start_time")
    private Date startTime;

    @Column(name = "start_time")
    @Temporal(TemporalType.TIMESTAMP)
    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date date) {
        this.startTime = date;
    }

    private Date callTime;

    public void setCallTime(Date date) {
        this.callTime = date;
    }

    @Transient
    public Date getCallTime() {
        return callTime;
    }

    @Expose
    @SerializedName("finish_time")
    private Date finishTime;

    @Column(name = "finish_time")
    @Temporal(TemporalType.TIMESTAMP)
    public Date getFinishTime() {
        return finishTime;
    }

    public void setFinishTime(Date date) {
        this.finishTime = date;
    }

    @Expose
    @SerializedName("input_data")
    private String input_data = "";

    /**
     *  ?    ?.
     *
     * @return
     */
    @Column(name = "input_data")
    public String getInput_data() {
        return input_data;
    }

    public void setInput_data(String input_data) {
        this.input_data = input_data;
    }

    /**
     * ? ?    ?? ?  ? ? ?  ???   ??.      ?? 
     * ? .
     */
    private final LinkedList<QService> serviceBack = new LinkedList<>();

    /**
     *   ? ? .   ? ? 
     *
     * @param service  ? ?  
     */
    public void addServiceForBack(QService service) {
        serviceBack.addFirst(service);
        needBack = !serviceBack.isEmpty();
    }

    /**
     *   ?    ? 
     *
     * @return   ? ?
     */
    @Transient
    public QService getServiceForBack() {
        needBack = serviceBack.size() > 1;
        return serviceBack.pollFirst();
    }

    @Expose
    @SerializedName("need_back")
    private boolean needBack = false;

    public boolean needBack() {
        return needBack;
    }

    /**
     *    ?      
     */
    @Expose
    @SerializedName("temp_comments")
    private String tempComments = "";

    @Transient
    public String getTempComments() {
        return tempComments;
    }

    public void setTempComments(String tempComments) {
        this.tempComments = tempComments;
    }

    /**
     *
     */
    @Expose
    @SerializedName("post_atatus")
    private String postponedStatus = "";

    @Transient
    public String getPostponedStatus() {
        return postponedStatus;
    }

    public void setPostponedStatus(String postponedStatus) {
        this.postponedStatus = postponedStatus;
    }

    /**
     *  ?  . 0 - ??;
     */
    @Expose
    @SerializedName("postpone_period")
    private int postponPeriod = 0;

    @Transient
    public int getPostponPeriod() {
        return postponPeriod;
    }

    /**
     * ?   ? 
     */
    @Expose
    @SerializedName("recall_cnt")
    private Integer recallCount = 0;

    @Transient
    public Integer getRecallCount() {
        return recallCount;
    }

    public void setRecallCount(Integer recallCount) {
        this.recallCount = recallCount;
    }

    public void upRecallCount() {
        this.recallCount++;
    }

    public void setPostponPeriod(int postponPeriod) {
        this.postponPeriod = postponPeriod;
        startPontpone = new Date().getTime();
        finishPontpone = startPontpone + postponPeriod * 1000 * 60;
    }

    private long startPontpone = 0;
    private long finishPontpone = 0;

    @Transient
    public long getFinishPontpone() {
        return finishPontpone;
    }

    /**
     *  ?, ? ?
     */
    @Override
    public String toString() {
        return prefix + getNumber() + (getInput_data().isEmpty() ? "" : " " + getInput_data())
                + (postponedStatus.isEmpty() ? ""
                        : " " + postponedStatus + (postponPeriod > 0 ? " (" + postponPeriod + "min.)" : ""));
    }

    @Transient
    @Override
    public String getName() {
        return prefix + getNumber() + " " + getInput_data();
    }

    @Expose
    @SerializedName("complex_id")
    public LinkedList<LinkedList<LinkedList<Long>>> complexId = new LinkedList<>();

    @Transient
    public LinkedList<LinkedList<LinkedList<Long>>> getComplexId() {
        return complexId;
    }

    public void setComplexId(LinkedList<LinkedList<LinkedList<Long>>> complexId) {
        this.complexId = complexId;
    }

}