|
|
|
@ -31,7 +31,23 @@ public class WalletPrerequisiteProjectionService {
|
|
|
|
|
|
|
|
|
|
|
|
@Transactional
|
|
|
|
@Transactional
|
|
|
|
public WalletPrerequisiteReference ensureForSubject(InstitutionKeySubject subject) {
|
|
|
|
public WalletPrerequisiteReference ensureForSubject(InstitutionKeySubject subject) {
|
|
|
|
SourceWallet source = loadCompletedSource(subject);
|
|
|
|
return ensureForSubject(subject, false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Module four follows the module-three prototype: step four is complete when
|
|
|
|
|
|
|
|
* the commercial bank sends the confirmation whose JSON status is ACTIVATED.
|
|
|
|
|
|
|
|
* Older module-five data may still require the central final-confirmation row,
|
|
|
|
|
|
|
|
* so this compatibility path is intentionally limited to the exchange module.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
@Transactional
|
|
|
|
|
|
|
|
public WalletPrerequisiteReference ensureForModule4(InstitutionKeySubject subject) {
|
|
|
|
|
|
|
|
return ensureForSubject(subject, true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private WalletPrerequisiteReference ensureForSubject(InstitutionKeySubject subject,
|
|
|
|
|
|
|
|
boolean allowModule3Step4) {
|
|
|
|
|
|
|
|
SourceWallet source = loadCompletedSource(subject, allowModule3Step4);
|
|
|
|
Institution institution = loadInstitution(subject);
|
|
|
|
Institution institution = loadInstitution(subject);
|
|
|
|
String accountId = ensureBankAccount(source, institution);
|
|
|
|
String accountId = ensureBankAccount(source, institution);
|
|
|
|
ensureWallet(source);
|
|
|
|
ensureWallet(source);
|
|
|
|
@ -53,12 +69,7 @@ public class WalletPrerequisiteProjectionService {
|
|
|
|
@Transactional
|
|
|
|
@Transactional
|
|
|
|
public WalletPrerequisiteReference ensureForWallet(String walletId) {
|
|
|
|
public WalletPrerequisiteReference ensureForWallet(String walletId) {
|
|
|
|
if (blank(walletId)) throw prerequisite();
|
|
|
|
if (blank(walletId)) throw prerequisite();
|
|
|
|
List<InstitutionKeySubject> subjects = jdbc.query(
|
|
|
|
List<InstitutionKeySubject> subjects = findSubjectsForWallet(walletId.trim());
|
|
|
|
"SELECT DISTINCT user_id,school_id,class_id FROM central_wallet_activation " +
|
|
|
|
|
|
|
|
"WHERE wallet_id=? AND wallet_activated=TRUE AND final_sent=TRUE " +
|
|
|
|
|
|
|
|
"AND cb_final_signature IS NOT NULL AND deleted=FALSE",
|
|
|
|
|
|
|
|
(rs, row) -> new InstitutionKeySubject(rs.getString("user_id"),
|
|
|
|
|
|
|
|
rs.getLong("school_id"), rs.getLong("class_id")), walletId.trim());
|
|
|
|
|
|
|
|
if (subjects.isEmpty()) throw prerequisite();
|
|
|
|
if (subjects.isEmpty()) throw prerequisite();
|
|
|
|
if (subjects.size() != 1) throw conflict("钱包标识对应多个实验主体");
|
|
|
|
if (subjects.size() != 1) throw conflict("钱包标识对应多个实验主体");
|
|
|
|
return ensureForSubject(subjects.get(0));
|
|
|
|
return ensureForSubject(subjects.get(0));
|
|
|
|
@ -67,18 +78,17 @@ public class WalletPrerequisiteProjectionService {
|
|
|
|
@Transactional(readOnly = true)
|
|
|
|
@Transactional(readOnly = true)
|
|
|
|
public WalletPrerequisiteReference referenceForWallet(String walletId) {
|
|
|
|
public WalletPrerequisiteReference referenceForWallet(String walletId) {
|
|
|
|
if (blank(walletId)) throw prerequisite();
|
|
|
|
if (blank(walletId)) throw prerequisite();
|
|
|
|
List<InstitutionKeySubject> subjects = jdbc.query(
|
|
|
|
List<InstitutionKeySubject> subjects = findSubjectsForWallet(walletId.trim());
|
|
|
|
"SELECT DISTINCT user_id,school_id,class_id FROM central_wallet_activation " +
|
|
|
|
|
|
|
|
"WHERE wallet_id=? AND wallet_activated=TRUE AND final_sent=TRUE " +
|
|
|
|
|
|
|
|
"AND cb_final_signature IS NOT NULL AND deleted=FALSE",
|
|
|
|
|
|
|
|
(rs, row) -> new InstitutionKeySubject(rs.getString("user_id"),
|
|
|
|
|
|
|
|
rs.getLong("school_id"), rs.getLong("class_id")), walletId.trim());
|
|
|
|
|
|
|
|
if (subjects.isEmpty()) throw prerequisite();
|
|
|
|
if (subjects.isEmpty()) throw prerequisite();
|
|
|
|
if (subjects.size() != 1) throw conflict("钱包标识对应多个实验主体");
|
|
|
|
if (subjects.size() != 1) throw conflict("钱包标识对应多个实验主体");
|
|
|
|
return referenceForSubject(subjects.get(0));
|
|
|
|
return referenceForSubject(subjects.get(0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private SourceWallet loadCompletedSource(InstitutionKeySubject subject) {
|
|
|
|
private SourceWallet loadCompletedSource(InstitutionKeySubject subject) {
|
|
|
|
|
|
|
|
return loadCompletedSource(subject, false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private SourceWallet loadCompletedSource(InstitutionKeySubject subject, boolean allowModule3Step4) {
|
|
|
|
List<Activation> activations = jdbc.query(
|
|
|
|
List<Activation> activations = jdbc.query(
|
|
|
|
"SELECT wallet_id,cb_final_signature,final_time FROM central_wallet_activation " +
|
|
|
|
"SELECT wallet_id,cb_final_signature,final_time FROM central_wallet_activation " +
|
|
|
|
"WHERE user_id=? AND school_id=? AND class_id=? AND wallet_activated=TRUE " +
|
|
|
|
"WHERE user_id=? AND school_id=? AND class_id=? AND wallet_activated=TRUE " +
|
|
|
|
@ -87,8 +97,33 @@ public class WalletPrerequisiteProjectionService {
|
|
|
|
(rs, row) -> new Activation(rs.getString("wallet_id"),
|
|
|
|
(rs, row) -> new Activation(rs.getString("wallet_id"),
|
|
|
|
rs.getString("cb_final_signature"), rs.getString("final_time")),
|
|
|
|
rs.getString("cb_final_signature"), rs.getString("final_time")),
|
|
|
|
subject.getUserId(), subject.getSchoolId(), subject.getClassId());
|
|
|
|
subject.getUserId(), subject.getSchoolId(), subject.getClassId());
|
|
|
|
if (activations.isEmpty()) throw prerequisite();
|
|
|
|
Activation activation;
|
|
|
|
Activation activation = activations.get(0);
|
|
|
|
if (!activations.isEmpty()) {
|
|
|
|
|
|
|
|
// Prefer the complete step-five record when it exists. It contains the
|
|
|
|
|
|
|
|
// central bank's final confirmation signature used by the shared wallet.
|
|
|
|
|
|
|
|
activation = activations.get(0);
|
|
|
|
|
|
|
|
} else if (allowModule3Step4) {
|
|
|
|
|
|
|
|
// The prototype finishes module three step four when the commercial
|
|
|
|
|
|
|
|
// bank sends the activation confirmation. The confirmation JSON itself
|
|
|
|
|
|
|
|
// carries status=ACTIVATED, while older deployments do not materialize
|
|
|
|
|
|
|
|
// a matching central_wallet_activation row. Use that sent confirmation
|
|
|
|
|
|
|
|
// as the module-four source instead of requiring an invisible central-bank
|
|
|
|
|
|
|
|
// action that is not present in the prototype.
|
|
|
|
|
|
|
|
List<Activation> sentConfirmations = jdbc.query(
|
|
|
|
|
|
|
|
"SELECT wallet_id,activate_signature,activate_timestamp " +
|
|
|
|
|
|
|
|
"FROM smart_contract_generation " +
|
|
|
|
|
|
|
|
"WHERE user_id=? AND school_id=? AND class_id=? AND sent=TRUE " +
|
|
|
|
|
|
|
|
"AND status='SENT' AND confirm_json LIKE '%ACTIVATED%' " +
|
|
|
|
|
|
|
|
"AND activate_signature IS NOT NULL AND activate_timestamp IS NOT NULL " +
|
|
|
|
|
|
|
|
"AND deleted=FALSE ORDER BY created_at DESC LIMIT 1",
|
|
|
|
|
|
|
|
(rs, row) -> new Activation(rs.getString("wallet_id"),
|
|
|
|
|
|
|
|
rs.getString("activate_signature"), rs.getString("activate_timestamp")),
|
|
|
|
|
|
|
|
subject.getUserId(), subject.getSchoolId(), subject.getClassId());
|
|
|
|
|
|
|
|
if (sentConfirmations.isEmpty()) throw prerequisite();
|
|
|
|
|
|
|
|
activation = sentConfirmations.get(0);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
throw prerequisite();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<Application> applications = jdbc.query(
|
|
|
|
List<Application> applications = jdbc.query(
|
|
|
|
"SELECT COALESCE(account_bank,selected_bank) bank_name," +
|
|
|
|
"SELECT COALESCE(account_bank,selected_bank) bank_name," +
|
|
|
|
@ -147,6 +182,15 @@ public class WalletPrerequisiteProjectionService {
|
|
|
|
certificates.get(0), rootSignatures.get(0), contract);
|
|
|
|
certificates.get(0), rootSignatures.get(0), contract);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private List<InstitutionKeySubject> findSubjectsForWallet(String walletId) {
|
|
|
|
|
|
|
|
return jdbc.query(
|
|
|
|
|
|
|
|
"SELECT DISTINCT user_id,school_id,class_id FROM central_wallet_activation " +
|
|
|
|
|
|
|
|
"WHERE wallet_id=? AND wallet_activated=TRUE AND final_sent=TRUE " +
|
|
|
|
|
|
|
|
"AND cb_final_signature IS NOT NULL AND deleted=FALSE",
|
|
|
|
|
|
|
|
(rs, row) -> new InstitutionKeySubject(rs.getString("user_id"),
|
|
|
|
|
|
|
|
rs.getLong("school_id"), rs.getLong("class_id")), walletId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Institution loadInstitution(InstitutionKeySubject subject) {
|
|
|
|
private Institution loadInstitution(InstitutionKeySubject subject) {
|
|
|
|
List<Institution> institutions = jdbc.query(
|
|
|
|
List<Institution> institutions = jdbc.query(
|
|
|
|
"SELECT bank_code,institution_identifier FROM institution_identifier_application " +
|
|
|
|
"SELECT bank_code,institution_identifier FROM institution_identifier_application " +
|
|
|
|
|